使用 Apache POI + iText (推荐,免费且功能强大)
这是最经典和流行的开源组合方案。

- Apache POI: 用于读取和操作 Word 文档(
.docx),它负责解析 Word 文件的结构和内容。 - iText: 用于生成 PDF 文件,它提供了强大的 PDF 操作功能。
核心思路:
- 使用 POI 加载
.docx文件,提取其中的文本、图片、表格等元素。 - 遍历这些元素,并使用 iText 的 API 将它们重新“绘制”到一个新的 PDF 文档中。
⚠️ 重要提醒: 这种方法不是简单的“格式转换”,而是“内容重构”,对于复杂的 Word 布局(如复杂的页眉页脚、分栏、图文混排、特殊字体等),用 POI+IText 完美还原是非常困难的,它更适合于格式相对简单的文档转换。
添加 Maven 依赖
在你的 pom.xml 文件中添加以下依赖:
<!-- Apache POI for .docx files -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<!-- iText for PDF generation -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.3</version>
</dependency>
<!-- iText Asian for CJK fonts support (e.g., Chinese, Japanese, Korean) -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
Java 代码示例
这个示例会处理文本、段落样式(粗体、斜体)、标题和表格。

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import org.apache.poi.xwpf.usermodel.*;
import java.io.*;
import java.util.List;
public class DocxToPdfConverter {
public static void main(String[] args) {
// 输入的 Word 文件路径
String docxPath = "input.docx";
// 输出的 PDF 文件路径
String pdfPath = "output.pdf";
try {
convertDocxToPdf(docxPath, pdfPath);
System.out.println("转换成功!PDF 文件已保存至: " + pdfPath);
} catch (Exception e) {
e.printStackTrace();
System.err.println("转换失败!");
}
}
public static void convertDocxToPdf(String docxPath, String pdfPath) throws Exception {
// 1. 创建 Word 文档对象
XWPFDocument document = new XWPFDocument(new FileInputStream(docxPath));
// 2. 创建 PDF 文档对象
Document pdfDoc = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.getInstance(pdfDoc, new FileOutputStream(pdfPath));
pdfDoc.open();
// 3. 遍历 Word 文档中的所有段落
for (XWPFParagraph paragraph : document.getParagraphs()) {
// 获取段落的对齐方式
ParagraphAlignment alignment = paragraph.getAlignment();
com.itextpdf.text.Paragraph pdfParagraph = new com.itextpdf.text.Paragraph();
// 设置 PDF 段落对齐
if (alignment != null) {
switch (alignment) {
case LEFT:
pdfParagraph.setAlignment(Element.ALIGN_LEFT);
break;
case CENTER:
pdfParagraph.setAlignment(Element.ALIGN_CENTER);
break;
case RIGHT:
pdfParagraph.setAlignment(Element.ALIGN_RIGHT);
break;
case BOTH:
pdfParagraph.setAlignment(Element.ALIGN_JUSTIFIED);
break;
}
}
// 遍历段落中的所有文本运行
for (XWPFRun run : paragraph.getRuns()) {
String text = run.getText(0);
if (text != null && !text.isEmpty()) {
// 创建 PDF 的 Chunk 对象,可以设置字体、大小、样式等
Font font = getFont(run);
Chunk chunk = new Chunk(text, font);
pdfParagraph.add(chunk);
}
}
if (!pdfParagraph.isEmpty()) {
pdfDoc.add(pdfParagraph);
}
}
// 4. 遍历 Word 文档中的所有表格
for (XWPFTable table : document.getTables()) {
PdfPTable pdfTable = new PdfPTable(table.getNumberOfColumns());
pdfTable.setWidthPercentage(100); // 表格宽度为页面宽度的100%
for (XWPFTableRow row : table.getRows()) {
for (XWPFTableCell cell : row.getTableCells()) {
PdfPCell pdfCell = new PdfPCell();
// 处理单元格内容(同样包含段落)
for (XWPFParagraph paragraph : cell.getParagraphs()) {
com.itextpdf.text.Paragraph cellParagraph = new com.itextpdf.text.Paragraph();
for (XWPFRun run : paragraph.getRuns()) {
String text = run.getText(0);
if (text != null && !text.isEmpty()) {
cellParagraph.add(new Chunk(text, getFont(run)));
}
}
pdfCell.addElement(cellParagraph);
}
pdfCell.setBorder(Rectangle.BOX); // 设置边框
pdfCell.setBorderWidth(1); // 设置边框宽度
pdfTable.addCell(pdfCell);
}
}
pdfDoc.add(pdfTable);
}
// 5. 关闭文档
pdfDoc.close();
writer.close();
document.close();
}
/**
* 根据 XWPFRun 的样式创建 iText 的 Font 对象
*/
private static Font getFont(XWPFRun run) throws DocumentException, IOException {
String fontFamily = run.getFontFamily() != null ? run.getFontFamily() : "SimSun";
int fontSize = run.getFontSize() != -1 ? run.getFontSize() : 12;
int style = Font.NORMAL;
if (run.isBold()) {
style |= Font.BOLD;
}
if (run.isItalic()) {
style |= Font.ITALIC;
}
// 为了支持中文,需要加载中文字体
// 这里使用 iText 自带的亚洲字体,也可以加载系统字体如 "C:/Windows/Fonts/simhei.ttf"
BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
return new Font(baseFont, fontSize, style);
}
}
使用 Aspose.Words (商业库,效果最好)
Aspose.Words 是一个专业的商业文档处理库,它的 Word 转 PDF 功能非常强大和准确,能够高度还原原始 Word 文档的格式、布局和样式。
优点:
- 高保真度转换:几乎可以完美地还原 Word 文档的所有细节。
- API 简单:一行代码即可完成转换,非常简单。
- 性能稳定:经过长期市场验证,非常可靠。
缺点:
- 收费:需要购买许可证,但提供免费试用版。
添加 Maven 依赖
你需要从 Aspose 官网下载 JAR 包并手动添加到项目中,或者使用其 Maven 仓库。

<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-words</artifactId>
<version>23.8</version> <!-- 请使用最新版本 -->
</dependency>
Java 代码示例
代码极其简单,堪称“傻瓜式”操作。
import com.aspose.words.*;
public class AsposeDocxToPdfConverter {
public static void main(String[] args) {
// 输入的 Word 文件路径
String docxPath = "input.docx";
// 输出的 PDF 文件路径
String pdfPath = "output_aspose.pdf";
try {
// 加载 Word 文档
Document doc = new Document(docxPath);
// 保存为 PDF,LoadFormat.DOCX 表示输入是 DOCX 格式
// SaveFormat.PDF 表示输出是 PDF 格式
doc.save(pdfPath, SaveFormat.PDF);
System.out.println("转换成功!PDF 文件已保存至: " + pdfPath);
} catch (Exception e) {
e.printStackTrace();
System.err.println("转换失败!");
}
}
}
使用 docx4j (纯 Java,适合 .docx)
docx4j 是另一个专门处理 Office Open XML 格式(如 .docx, .xlsx, .pptx)的开源 Java 库,它也可以用于转换,但通常需要结合其他库(如 Flying Saucer 或 iText)来生成最终的 PDF。
优点:
- 专注于处理
.docx,API 对 OOXML 结构支持很好。 - 纯 Java 实现。
缺点:
- 转换逻辑相对复杂,不如 Aspose.Words 直接。
转换思路:
- 使用 docx4j 加载和操作
.docx文件。 - 将
.docx的内容转换为 XHTML 或 HTML 格式。 - 使用 Flying Saucer (xhtmlrenderer) 这个库将 XHTML 渲染成 PDF。
这种方法比 POI+IText 更复杂,通常用于需要对 .docx 内容进行深度处理后再转换的场景。
总结与对比
| 特性 | Apache POI + iText | Aspose.Words | docx4j + Flying Saucer |
|---|---|---|---|
| 费用 | 免费 (开源) | 商业 (收费) | 免费 (开源) |
| 易用性 | 复杂,需要手动处理内容和样式 | 非常简单,一行代码搞定 | 复杂,涉及多步转换 |
| 转换质量 | 一般,简单文档效果好,复杂文档布局易错乱 | 极高,几乎完美还原 | 较好,取决于 XHTML 渲染效果 |
| 适用场景 | 预算有限,文档格式简单,需要深度定制转换逻辑 | 对转换质量要求高,项目预算充足 | 需要对 .docx 内容进行深度处理,再输出 PDF |
| 依赖库 | POI, iText | Aspose.Words | docx4j, Flying Saucer |
如何选择?
- 如果你的项目是个人学习、小型应用,且对成本敏感,Word 文档格式不复杂,推荐使用方法一(POI + iText)。
- 如果你的项目是商业应用,对文档格式还原度有严格要求,且预算充足,强烈推荐使用方法二(Aspose.Words),它能为你节省大量的开发时间和维护成本。
- 如果你的核心需求是深度处理
.docx的内部结构,而不是单纯的转换,可以考虑 方法三(docx4j)。
希望这个详细的指南能帮助你选择最适合你的方案!
