方法概览
| 方法 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|
| Apache POI + iText / PDFBox | 开源免费,灵活度高 | 代码复杂,样式兼容性差,需要自己处理所有布局 | 只需要提取文本或生成简单 PDF,不关心原始样式 |
| Aspose.Total | 功能强大,样式转换效果最好,API 友好 | 商业软件,价格昂贵 | 对 PDF 转换质量要求高,有预算的商业项目 |
| Spire.Office | 功能强大,样式转换效果好,比 Aspose 便宜 | 商业软件,需要付费 | 预算有限,但仍需要高质量转换的商业项目 |
| LibreOffice/OpenOffice Headless | 开源免费,转换质量高(依赖 Office 引擎) | 依赖外部进程,环境配置复杂,性能较差 | 允许安装外部服务器的后台任务,追求高质量开源方案 |
| Office Online Server / Microsoft Graph | 微软官方方案,格式保真度高 | 架构复杂,需要部署和维护 Office 环境,成本高 | 已有 Microsoft 365/Office 生态的大型企业应用 |
使用 Apache POI + iText / PDFBox (纯 Java 开源方案)
这种方法的核心思想是:先用 POI 读取 Office 文档的结构和内容,再用 PDFBox 或 iText 将这些内容重新绘制到一个 PDF 文件中。

关键点: 这种方法不进行“转换”,而是“重建”,它无法完美保留原始文档的复杂样式(如复杂的页眉页脚、图文混排、特定字体效果等)。
添加 Maven 依赖
你需要同时添加 POI 和 PDFBox 的依赖。
<!-- Apache POI for Office documents -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<!-- Apache PDFBox for PDF generation -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.27</version>
</dependency>
代码示例 (Word 转 PDF)
这个例子会读取 Word 文档中的所有段落,然后将它们添加到 PDF 中。
import org.apache.poi.xwpf.usermodel.*;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class PoiToPdfConverter {
public static void main(String[] args) {
try (FileInputStream docxInputStream = new FileInputStream("input.docx");
XWPFDocument document = new XWPFDocument(docxInputStream);
PDDocument pdfDocument = new PDDocument()) {
// 1. 创建一个 PDF 页面
PDPage page = new PDPage();
pdfDocument.addPage(page);
// 2. 准备 PDF 内容流
try (PDPageContentStream contentStream = new PDPageContentStream(pdfDocument, page)) {
// 设置字体和大小 (PDFBox 默认不支持所有字体,这里用默认的)
contentStream.setFont(PDType1Font.HELVETICA_BOLD, 12);
contentStream.beginText();
contentStream.newLineAtOffset(50, 750); // 设置起始坐标
// 3. 遍历 Word 文档的段落
for (XWPFParagraph paragraph : document.getParagraphs()) {
String text = paragraph.getText();
// 简单处理:换行
contentStream.showText(text + "\n");
}
contentStream.endText();
}
// 4. 保存 PDF 文件
pdfDocument.save("output.pdf");
System.out.println("PDF created successfully!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
评价:

- 优点: 免费,纯 Java,无外部依赖。
- 缺点: 对于任何稍微复杂一点的 Word 文档,这个代码都无能为力,字体、颜色、图片、表格位置等都会丢失,需要编写大量代码来处理样式,非常繁琐。
使用商业组件库 (Aspose.Total / Spire.Office)
这是最推荐、最简单、效果最好的方法,这些库专门用于处理文档格式转换,内部引擎会尽力模拟 Office 的渲染引擎,因此保真度非常高。
以 Aspose.Words 为例
Aspose.Total 是一个全家桶,包含了处理 Word, Excel, PowerPoint, PDF 等所有格式的组件,这里我们只使用 Aspose.Words 来做 Word 转 PDF。
添加 Maven 依赖
Aspose 提供了 Maven 仓库,但需要先获取授权。

<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-words</artifactId>
<version>23.8</version> <!-- 请使用最新版本 -->
</dependency>
代码示例 (Word 转 PDF)
代码极其简单,通常只需要一行。
import com.aspose.words.*;
public class AsposeWordsConverter {
public static void main(String[] args) throws Exception {
// 1. 加载 Word 文档
Document doc = new Document("input.docx");
// 2. 直接另存为 PDF (就这么简单!)
doc.save("output_from_aspose.pdf");
System.out.println("PDF created by Aspose successfully!");
}
}
评价:
- 优点:
- 代码极简: 一行代码搞定转换。
- 质量高: 几乎完美保留了原始文档的布局、字体、图片、表格等所有样式。
- 功能强大: 除了转换,还能进行文档合并、拆分、水印、加密等复杂操作。
- 跨平台: 纯 Java 实现,可在任何安装了 JRE 的环境运行。
- 缺点:
- 收费: 这是最大的门槛,需要购买许可证,价格不菲,但通常提供免费试用版。
使用 LibreOffice/OpenOffice Headless 模式
这种方法利用了 LibreOffice 或 OpenOffice 的命令行功能,让它们在后台静默(Headless)模式下进行转换。
环境准备
- 下载并安装 LibreOffice 或 OpenOffice。
- 将安装目录下的
program文件夹路径添加到系统的环境变量PATH中,以便在命令行中调用soffice(LibreOffice) 或soffice.exe(OpenOffice) 命令。
Java 代码示例
通过 Java 的 Runtime 或 ProcessBuilder 来执行命令。
import java.io.File;
public class LibreOfficeConverter {
public static void main(String[] args) {
String inputPath = "input.docx";
String outputPath = "output_libre.pdf";
String libreOfficePath = "C:\\Program Files\\LibreOffice\\program\\soffice.exe"; // Windows 示例路径
// 构建命令
// --headless: 无界面模式
// --convert-to pdf: 指定转换格式为 pdf
// --outdir: 指定输出目录
String command = String.format("\"%s\" --headless --convert-to pdf --outdir \"%s\" \"%s\"",
libreOfficePath,
new File(outputPath).getParent(),
inputPath);
try {
System.out.println("Executing command: " + command);
Process process = Runtime.getRuntime().exec(command);
// 等待进程结束
int exitCode = process.waitFor();
if (exitCode == 0) {
System.out.println("PDF created successfully by LibreOffice!");
} else {
System.err.println("Conversion failed with exit code: " + exitCode);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
评价:
- 优点:
- 开源免费: 无需任何软件许可费用。
- 质量高: 因为使用了真正的 Office 内核,转换效果通常很好,能处理复杂样式。
- 缺点:
- 依赖外部软件: 必须在目标服务器上安装并正确配置 LibreOffice。
- 性能问题: 启动 soffice 进程有一定开销,不适合高并发的实时转换请求。
- 环境耦合: 服务的稳定性和性能依赖于外部 Office 软件的版本和环境。
- 跨平台路径问题: 不同操作系统的命令和路径需要适配。
总结与如何选择
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 个人项目、学习、对样式要求不高 | Apache POI + PDFBox | 免费,能满足基本文本提取和简单生成需求。 |
| 商业项目,预算充足,对质量要求极高 | Aspose.Total / Spire.Office | 效果最好,开发效率最高,省时省力,避免踩坑。 |
| 商业项目,预算有限,但仍需要较好质量 | Spire.Office | 性价比高,是 Aspose 的强力竞争者。 |
| 已有内部部署的 Office 环境,或后台批处理任务 | LibreOffice Headless | 开源且质量可靠,适合作为后台服务运行,不要求低延迟。 |
| 大型企业,深度集成 Microsoft 365 | Microsoft Graph API | 官方方案,生态统一,但架构复杂,成本高。 |
最终建议:
对于绝大多数 Java 如果项目是商业性质的,强烈推荐使用 Aspose.Total 或 Spire.Office,虽然需要付费,但它们能为你节省大量的开发时间、调试成本和后期维护风险,其带来的稳定性和高质量输出是开源方案难以比拟的。
如果预算确实是零,并且愿意处理外部依赖和环境配置,LibreOffice Headless 是一个不错的备选方案,而 Apache POI 则更适合于那些只关心文档内容,而不关心其视觉呈现的场景。
