杰瑞科技汇

Java如何将Word文件转为PDF?

使用 Apache POI + iText (推荐,免费且功能强大)

这是最经典和流行的开源组合方案。

Java如何将Word文件转为PDF?-图1
(图片来源网络,侵删)
  • Apache POI: 用于读取和操作 Word 文档(.docx),它负责解析 Word 文件的结构和内容。
  • iText: 用于生成 PDF 文件,它提供了强大的 PDF 操作功能。

核心思路

  1. 使用 POI 加载 .docx 文件,提取其中的文本、图片、表格等元素。
  2. 遍历这些元素,并使用 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 代码示例

这个示例会处理文本、段落样式(粗体、斜体)、标题和表格。

Java如何将Word文件转为PDF?-图2
(图片来源网络,侵删)
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 仓库。

Java如何将Word文件转为PDF?-图3
(图片来源网络,侵删)
<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 直接。

转换思路

  1. 使用 docx4j 加载和操作 .docx 文件。
  2. .docx 的内容转换为 XHTML 或 HTML 格式。
  3. 使用 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)

希望这个详细的指南能帮助你选择最适合你的方案!

分享:
扫描分享到社交APP
上一篇
下一篇