Java实现Word转PDF的完整指南:从基础到实战

1. 引言

在日常企业级开发中,将Word文档转换为PDF是一项常见需求。PDF格式具有跨平台、不易编辑、保持排版等优点。Java作为主流后端语言,提供了多种实现方案。本文将从零开始,介绍几种主流的Word转PDF方法,并对比其优缺点。

2. 方案一:Apache POI + iText

Apache POI可以读取Word文档(.doc和.docx),iText则用于生成PDF。基本思路是:先用POI解析Word内容,再通过iText重新排版为PDF。这种方式适用于简单的表格和文本,但对复杂样式支持较差。

2.1 添加依赖

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.3</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext7-core</artifactId>
    <version>7.2.5</version>
</dependency>

2.2 核心代码

import org.apache.poi.xwpf.usermodel.*;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;

public void convertWordToPdf(String wordPath, String pdfPath) throws Exception {
    try (FileInputStream fis = new FileInputStream(wordPath);
         XWPFDocument doc = new XWPFDocument(fis);
         PdfWriter writer = new PdfWriter(pdfPath);
         PdfDocument pdfDoc = new PdfDocument(writer);
         Document document = new Document(pdfDoc)) {

        for (IBodyElement element : doc.getBodyElements()) {
            if (element instanceof XWPFParagraph) {
                XWPFParagraph para = (XWPFParagraph) element;
                Paragraph pdfPara = new Paragraph(para.getText());
                document.add(pdfPara);
            } else if (element instanceof XWPFTable) {
                // 处理表格(省略)
            }
        }
    }
}

3. 方案二:Docx4j

Docx4j是一个纯Java库,可以直接将.docx文件转换为PDF,内部使用iText或Apache FOP实现。它支持大多数Word特性,包括样式、表格、图片等。

3.1 添加依赖

<dependency>
    <groupId>org.docx4j</groupId>
    <artifactId>docx4j-JAXB-ReferenceImpl</artifactId>
    <version>11.4.9</version>
</dependency>
<dependency>
    <groupId>org.docx4j</groupId>
    <artifactId>docx4j-export-fo</artifactId>
    <version>11.4.9</version>
</dependency>

3.2 核心代码

import org.docx4j.Docx4J;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;

public void convertDocx4j(String wordPath, String pdfPath) throws Exception {
    WordprocessingMLPackage wordPackage = WordprocessingMLPackage.load(new java.io.File(wordPath));
    Docx4J.toPDF(wordPackage, new java.io.FileOutputStream(pdfPath));
}

4. 方案三:调用LibreOffice/OpenOffice命令行

这种方法通过Java执行外部命令,调用LibreOffice或OpenOffice的转换功能。它支持几乎所有格式,且转换质量高,但需要安装第三方软件。

4.1 命令示例

soffice --headless --convert-to pdf --outdir /output /path/to/input.docx

4.2 Java调用

import java.io.BufferedReader;
import java.io.InputStreamReader;

public void convertByLibreOffice(String inputPath, String outputDir) throws Exception {
    String[] cmd = {"soffice", "--headless", "--convert-to", "pdf", "--outdir", outputDir, inputPath};
    ProcessBuilder pb = new ProcessBuilder(cmd);
    Process process = pb.start();
    int exitCode = process.waitFor();
    if (exitCode != 0) {
        throw new RuntimeException("转换失败,退出码: " + exitCode);
    }
}

5. 方案对比与总结

方案优点缺点
POI+iText纯Java,无需外部依赖样式支持差,复杂文档可能变形
Docx4j支持样式完整,纯Java大文档性能一般,依赖较多
LibreOffice转换质量高,支持复杂格式需要安装额外软件,依赖系统环境

如果项目对格式要求不高,推荐使用Docx4j,它平衡了方便性和质量。若生产环境允许安装LibreOffice,则首选该方案,稳定性最佳。对于简单文本,POI+iText足够。

6. 注意事项

  • 处理中文时,确保字体支持,否则PDF中可能出现乱码。
  • 大型文档转换时注意内存设置。
  • 考虑异步处理,避免阻塞主线程。

希望本文能帮助你快速实现Java中的Word转PDF功能。根据实际需求选择合适的方案,并进行充分的测试。