Java 实现 Word 转PDF方案_java word转pdf
生成 Word 转 PDF
1. 转换方案选择
项目开发我主要使用过 Aspose 和 LibreOffice,两者代码实现都很简单,转换效果也不错。其他生成 pdf 的方案,比如使用 html 转换、xml、或者直接操作 pdf 模板,实际使用代码逻辑繁琐不易理解,且转换生成效果一般。LibreOffice主要是后期做复杂的 pdf 模板导出,使用 word 难以动态填充内容,后来使用 excel,在 java中计算后填充 excel,设置好格式在转换拼接 pdf 最后输出。
- Aspose:商业收费软件,免费版有水印。
 - LibreOffice:开源免费, 需要部署环境安装LibreOffice,实际使用需要控制并发与文件大小,避免对服务器整体造成影响。
 
2. Aspose 实现方案
a. 依赖注入
可以直接下载 jar 包,注入 maven 依赖后直接使用:
<dependency> <groupId>com.aspose</groupId> <artifactId>aspose-words</artifactId> <version>15.8.0</version> <scope>system</scope> <systemPath>${project.basedir}/src/main/resources/lib/aspose-words-15.8.0-jdk16.jar</systemPath></dependency>
b. 实际使用
基本用法:
// 先创建一个临时文件用来存储 PDFString pdfPath = FileUtils.getTempDirectoryPath() + System.currentTimeMillis() + \".pdf\";/** * 加载license 用于破解 不生成水印 */ @SneakyThrows private static void getLicense() { try (InputStream is = AsposeUtil.class.getClassLoader().getResourceAsStream(\"lib/License.xml\")) { License license = new License(); license.setLicense(is); } }/** * word转pdf * * @param wordPath word文件保存的路径 * @param pdfPath 转换后pdf文件保存的路径 */public static void wordToPdf(String wordPath, String pdfPath) throws Exception { // 获取许可证 getLicense(); // 加载 Word 文档 Document doc = new Document(wordPath); // 设置 PdfSaveOptions PdfSaveOptions options = new PdfSaveOptions(); options.setSaveFormat(SaveFormat.PDF); // 保存为 PDF try (FileOutputStream os = new FileOutputStream(pdfPath)) { doc.save(os, options); }}
<License> <Data> <Products>  <Product>Aspose.Total for Java</Product>  <Product>Aspose.Words for Java</Product> </Products> <EditionType>Enterprise</EditionType> <SubscriptionExpiry>20991231</SubscriptionExpiry> <LicenseExpiry>20991231</LicenseExpiry> <SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber> </Data> <Signature> sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU= </Signature> </License>
c. 常见问题与解决思路
1. 字体文件缺失导致转换乱码
- 
场景:在服务器或 Docker 环境下运行,可能会因缺少字体导致 PDF 乱码。
 - 
解决方案一:将字体文件放在服务器的字体目录,Docker 可在启动时拷贝字体。
# 使用带完整字体库的基础镜像FROM openjdk:17-jdk-slim# 拷贝字体COPY fonts/ /usr/share/fonts/truetype/custom/# 刷新字体缓存RUN fc-cache -fv - 
解决方案二:将字体文件放在项目的
resources/fonts目录下,导出时拷贝到临时目录后再进行转换(只需转换一次)。private final static String[] FONT_PATHS = {\"fonts/Songti.ttc\"};fontPath = copyTempFileFont(FONT_PATHS);/** * 将项目中的字体文件拷贝到临时目录 * @return 字体目录路径 */private static String copyTempFileFont(String... fontPath) { String tempDir = System.getProperty(\"java.io.tmpdir\"); File fontDir = new File(tempDir, \"fonts\"); if (!fontDir.exists()) { fontDir.mkdirs(); // 创建目录 } for (String path : fontPath) { File tempFile = new File(fontDir, new File(path).getName()); if (!tempFile.exists()) { try (InputStream inputStream = Object.class.getClassLoader().getResourceAsStream(path)) { FileUtils.copyInputStreamToFile(inputStream, tempFile); } catch (IOException e) { throw new RuntimeException(\"字体文件转换失败,请稍候重试\"); } } } return fontDir.getPath() + \"/\";}带字体目录的转换方法:
/** * word转pdf(指定字体目录) * * @param wordPath word文件保存的路径 * @param pdfPath 转换后pdf文件保存的路径 * @param fontPath 字体目录 */public static void wordToPdf(String wordPath, String pdfPath, String fontPath) throws Exception { // 获取许可证 getLicense(); // 设置字体文件夹 FontSettings.setFontsFolder(fontPath, false); // 加载 Word 文档 Document doc = new Document(wordPath); // 设置 PdfSaveOptions PdfSaveOptions options = new PdfSaveOptions(); options.setSaveFormat(SaveFormat.PDF); // 保存为 PDF try (FileOutputStream os = new FileOutputStream(new File(pdfPath))) { doc.save(os, options); }} 
3. LibreOffice 实现方案(对应 excel 也可以直接使用)
- 官网下载安装: https://zh-cn.libreoffice.org/
 
a. JODConverter(调用 LibreOffice 转换)
- 引入依赖
 
<dependency> <groupId>org.jodconverter</groupId> <artifactId>jodconverter-local</artifactId> <version>4.4.4</version></dependency>
- 代码实现
 
/** * 转换为PDF(同时适用于 word excel) * @param file * @return * @throws OfficeException * @throws IOException */public File convertToPdf(File file) throws OfficeException, IOException { File tempPdfFile = File.createTempFile(String.valueOf(System.currentTimeMillis()), \".pdf\"); LocalOfficeManager officeManager = null; try { officeManager = (LocalOfficeManager.builder().install()).build(); officeManager.start(); (LocalConverter.builder().officeManager(officeManager)).build().convert(file).to(tempPdfFile).execute(); } finally { if (officeManager != null) { officeManager.stop(); } } return tempPdfFile;}
- 拼接pdf
a. 依赖 
<dependency> <groupId>com.itextpdf</groupId> <artifactId>itext7-core</artifactId> <version>7.1.15</version> </dependency>
b. 实现
/** * 合并PDF文件 */ private void mergePdfFiles(List<File> pdfFiles, String outputPath) throws IOException { try (PdfWriter writer = new PdfWriter(outputPath);  PdfDocument mergedDoc = new PdfDocument(writer)) { PdfMerger merger = new PdfMerger(mergedDoc); for (File pdfFile : pdfFiles) {  try (PdfReader reader = new PdfReader(pdfFile);  PdfDocument sourceDoc = new PdfDocument(reader)) {  merger.merge(sourceDoc, 1, sourceDoc.getNumberOfPages());  } } } }
4. 部署服务器、docker需要安装LibreOffice, 需要安装字体文件
DockerFile 参考示例:
# 使用带完整字体库的基础镜像FROM openjdk:17-jdk-slim# 1. 设置阿里云源并安装依赖(含中文字体支持)RUN sed -i \'s/deb.debian.org/mirrors.aliyun.com/g\' /etc/apt/sources.list && \\ echo \"deb http://mirrors.aliyun.com/debian bookworm main contrib non-free\" > /etc/apt/sources.list && \\ apt-get update && \\ apt-get install -y --no-install-recommends \\ dpkg \\ libssl3 \\ libnss3 \\ libxslt1.1 \\ libdbus-1-3 \\ libnspr4 \\ libcurl4 \\ libgtk-3-0 \\ libglib2.0-0 \\ libxinerama1 \\ libcairo2 \\ libfreetype6 \\ libxcb-shm0 \\ libx11-xcb1 \\ libxrender1 \\ libxtst6 \\ libxml2 \\ openssl \\ fontconfig \\ fonts-dejavu \\ fonts-wqy-microhei && \\ ln -sf /usr/lib/x86_64-linux-gnu/libssl.so.3 /usr/lib/x86_64-linux-gnu/libssl3.so && \\ ldconfig && \\ rm -rf /var/lib/apt/lists/*# 2. 拷贝中文字体(如 SimSun.ttc)并注册COPY fonts/ /usr/share/fonts/truetype/custom/RUN fc-cache -fv# 3. 安装 LibreOfficeWORKDIR /tmpCOPY LibreOffice_25.2.3_Linux_x86-64_deb.tar.gz .RUN tar -xzf LibreOffice_25.2.3_Linux_x86-64_deb.tar.gz && \\ DEB_DIR=$(find . -type d -name \"LibreOffice*\") && \\ dpkg -i $DEB_DIR/DEBS/*.deb && \\ rm -rf /tmp/LibreOffice*# 4. 验证 LibreOffice 所有依赖RUN ldd /opt/libreoffice25.2/program/soffice.bin | grep -v \"not found\"# 5. 设置环境变量ENV LIBREOFFICE_HOME=/opt/libreoffice25.2/program \\ PATH=\"${PATH}:/opt/libreoffice25.2/program\" \\ LANG=C.UTF-8 \\ TZ=Asia/Shanghai


