杰瑞科技汇

Java如何将Word转换成PDF?

方法概览

方法 核心库 优点 缺点 适用场景
Apache POI + iText Apache POI, iText 开源免费,功能强大,对文档格式控制精细 实现复杂,需要手动处理样式、布局,转换效果可能不完美 需要深度定制,且对100%还原原格式要求不高的场景
docx4j docx4j 专门处理 Office Open XML 格式,API 相对友好 转换 PDF 需要额外依赖(如 Flying Saucer),效果可能不稳定 需要 Java 操控 .docx/.xlsx/.pptx 内容的场景
Aspose.Words Aspose.Words 效果最好,转换质量高,API 功能强大 商业收费,价格较贵,有免费试用版 对转换质量有高要求,且项目预算充足的企业级应用
Spire.Doc Spire.Doc 转换效果较好,API 简单易用 商业收费,有免费版但有页数和功能限制 中小型项目,寻求简单易用的商业解决方案

强烈推荐:对于大多数生产环境,Aspose.Words 是最佳选择,因为它能最大程度地保留 Word 的原始格式,如果预算有限,可以优先考虑 docx4jApache POI + iText 的组合,但需要投入更多精力处理细节。


使用 Aspose.Words (推荐)

这是目前市场上公认的在 Java 中转换 Word 到 PDF 效果最好的商业库。

添加 Maven 依赖

在你的 pom.xml 文件中添加 Aspose.Words 的依赖。

<dependency>
    <groupId>com.aspose</groupId>
    <artifactId>aspose-words</artifactId>
    <version>23.8</version> <!-- 请使用最新版本 -->
</dependency>

注意:这是一个商业库,你需要从 Aspose 官网 购买许可证并激活它,否则转换后的 PDF 会有水印,在试用模式下,功能是完整的,但每页会有一个评估水印。

添加许可证 (重要)

为了避免水印,你需要加载你的许可证文件,最好的做法是在应用程序启动时加载一次。

创建一个 LicenseHelper.java 工具类:

import com.aspose.words.License;
import java.io.InputStream;
public class LicenseHelper {
    public static void setLicense() {
        try (InputStream is = LicenseHelper.class.getClassLoader().getResourceAsStream("Aspose.Words.lic")) {
            if (is != null) {
                License license = new License();
                license.setLicense(is);
                System.out.println("Aspose.Words License loaded successfully.");
            } else {
                System.out.println("License file not found. Using evaluation mode.");
            }
        } catch (Exception e) {
            System.out.println("Error loading Aspose.Words License: " + e.getMessage());
            // 继续在试用模式下运行
        }
    }
}

将你的 Aspose.Words.lic 文件放在 src/main/resources 目录下。

编写转换代码

转换过程非常简单,只需几行代码。

import com.aspose.words.Document;
import com.aspose.words.SaveFormat;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class AsposeWordToPdfConverter {
    public static void main(String[] args) {
        // 1. 加载许可证 (推荐)
        LicenseHelper.setLicense();
        // 2. 定义输入和输出文件路径
        String inputPath = "input.docx"; // 放在项目根目录或指定完整路径
        String outputPath = "output_aspose.pdf";
        try {
            // 3. 加载 Word 文档
            // 使用 FileInputStream 加载本地文件
            Document doc = new Document(new FileInputStream(inputPath));
            // 4. 保存为 PDF
            // 使用 FileOutputStream 输出到本地文件
            doc.save(outputPath, SaveFormat.PDF);
            System.out.println("Word 文档已成功转换为 PDF,文件路径: " + new File(outputPath).getAbsolutePath());
        } catch (Exception e) {
            System.err.println("转换过程中发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

优点

  • 保真度高:能完美保留 Word 中的字体、图片、表格、页眉页脚、页码、分栏等复杂格式。
  • API 强大:除了转换,还可以进行文档的创建、修改、合并、拆分等复杂操作。
  • 稳定可靠:商业库,有完善的技术支持。

使用 docx4j (开源免费)

docx4j 是一个专门用于处理 Office Open XML 格式(.docx, .xlsx, .pptx)的开源 Java 库,它本身不直接生成 PDF,但可以调用 Flying Saucer (xhtmlrenderer) 来实现。

添加 Maven 依赖

<dependencies>
    <!-- docx4j core -->
    <dependency>
        <groupId>org.docx4j</groupId>
        <artifactId>docx4j-core</artifactId>
        <version>11.4.4</version> <!-- 请使用最新版本 -->
    </dependency>
    <!-- 用于转换到 Flying Saucer -->
    <dependency>
        <groupId>org.docx4j</groupId>
        <artifactId>docx4j-export-fo</artifactId>
        <version>11.4.4</version>
    </dependency>
    <!-- Flying Saucer itself -->
    <dependency>
        <groupId>org.xhtmlrenderer</groupId>
        <artifactId>flying-saucer-pdf</artifactId>
        <version>9.1.22</version>
    </dependency>
</dependencies>

编写转换代码

import org.docx4j.Docx4J;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.convert.in.xhtml.XHTMLImporterImpl;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFont;
import org.docx4j.fonts.PhysicalFonts;
import java.io.File;
public class Docx4jWordToPdfConverter {
    public static void main(String[] args) {
        String inputPath = "input.docx";
        String outputPath = "output_docx4j.pdf";
        try {
            // 1. 加载 Word 文档
            WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new File(inputPath));
            // 2. 设置字体映射 (非常重要,否则中文等字体可能无法显示)
            Mapper fontMapper = new IdentityPlusMapper();
            // 添加一个系统字体,"SimSun" (宋体)
            // 你需要确保系统中安装了这些字体,或者提供字体文件路径
            PhysicalFont font = PhysicalFonts.get("SimSun");
            if (font == null) {
                System.out.println("警告: 未找到 SimSun 字体,转换后中文可能显示异常。");
            } else {
                fontMapper.getFontMappings().put("SimSun", font);
            }
            wordMLPackage.setFontMapper(fontMapper);
            // 3. 将 Word 内容转换为 XHTML
            XHTMLImporterImpl xhtmlImporter = new XHTMLImporterImpl(wordMLPackage);
            org.w3c.dom.Document xhtml = xhtmlImporter.convert(wordMLPackage.getMainDocumentPart());
            // 4. 使用 Flying Saucer 将 XHTML 渲染为 PDF
            // Docx4J 的这个方法会自动处理转换过程
            Docx4J.toPDF(wordMLPackage, new File(outputPath));
            System.out.println("Word 文档已成功转换为 PDF,文件路径: " + new File(outputPath).getAbsolutePath());
        } catch (Exception e) {
            System.err.println("转换过程中发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

优点

  • 开源免费:没有版权和费用问题。
  • 专注 OOXML:对 Word 文档的结构有很好的理解。

缺点

  • 依赖链复杂:依赖多个库,版本兼容性需要小心。
  • 字体处理麻烦:需要手动配置字体映射,否则容易出现乱码或字体替换问题。
  • 转换效果不稳定:对于非常复杂的 Word 布局(如复杂的页眉页脚、图文混排),转换结果可能不如 Aspose 精确。

使用 Apache POI + iText (开源,但实现复杂)

这种方法是“手动”转换,Apache POI 用于读取 Word 文档的内容和样式,然后使用 iText 库根据这些信息重新生成一个 PDF,这种方法最灵活,但也最繁琐。

添加 Maven 依赖

<dependencies>
    <!-- Apache POI for reading .docx -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.3</version> <!-- 请使用最新版本 -->
    </dependency>
    <!-- iText for generating PDF -->
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itextpdf</artifactId>
        <version>5.5.13.3</version>
    </dependency>
    <!-- iText for HTML parsing (optional, but can help) -->
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itext-asian</artifactId>
        <version>5.2.0</version>
    </dependency>
</dependencies>

编写转换代码 (简化示例)

这是一个概念性的示例,真实的实现需要处理段落、表格、图片、列表、字体、颜色、对齐方式等无数细节,工作量巨大。

import org.apache.poi.xwpf.usermodel.*;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class PoiITextWordToPdfConverter {
    public static void main(String[] args) {
        String inputPath = "input.docx";
        String outputPath = "output_poi_itext.pdf";
        try (FileInputStream fis = new FileInputStream(inputPath);
             XWPFDocument document = new XWPFDocument(fis);
             FileOutputStream fos = new FileOutputStream(outputPath)) {
            // 1. 创建 iText Document
            Document pdfDoc = new Document(PageSize.A4);
            PdfWriter.getInstance(pdfDoc, fos);
            pdfDoc.open();
            // 2. 遍历 Word 文档中的段落
            for (XWPFParagraph paragraph : document.getParagraphs()) {
                // 创建 iText 段落
                com.itextpdf.text.pdf.PdfPChunk chunk = new com.itextpdf.text.pdf.PdfPChunk(paragraph.getText());
                // ... 这里需要手动设置字体、大小、颜色、对齐方式等
                // pdfDoc.add(new Paragraph(chunk));
            }
            // 3. 遍历 Word 文档中的表格
            for (XWPFTable table : document.getTables()) {
                PdfPTable pdfTable = new PdfPTable(table.getNumberOfColumns());
                for (XWPFTableRow row : table.getRows()) {
                    for (XWPFTableCell cell : row.getTableCells()) {
                        PdfPCell pdfCell = new PdfPCell(new Paragraph(cell.getText()));
                        // ... 设置单元格样式
                        pdfTable.addCell(pdfCell);
                    }
                }
                pdfDoc.add(pdfTable);
            }
            // 4. 关闭文档
            pdfDoc.close();
            System.out.println("Word 文档已成功转换为 PDF,文件路径: " + new File(outputPath).getAbsolutePath());
        } catch (Exception e) {
            System.err.println("转换过程中发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

优点

  • 完全控制:你可以精确控制 PDF 的每一个像素。
  • 无外部依赖:除了 POI 和 iText,没有其他黑盒操作。

缺点

  • 开发成本极高:需要将 Word 的所有复杂格式(样式、主题、页眉页脚、页码、脚注等)手动映射到 iText 的对象上,工作量巨大。
  • 容易出错:很难做到 100% 的格式还原,总有细节被遗漏。

总结与建议

场景 推荐方案
企业级应用、对质量要求高、有预算 Aspose.Words
个人项目、学习、或预算有限的开源项目 docx4j (需要耐心处理字体和兼容性问题)
需要深度定制 PDF 输出,且不介意自己实现所有细节 Apache POI + iText (不推荐,除非有特殊需求)

对于绝大多数 Java 直接使用 Aspose.Words 是最省心、效果最好的选择,你可以先去它的官网下载试用版,体验一下转换效果,如果满意再考虑购买。

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