Java高效实现Word转PDF的完整指南
作者:咕白m625
Java开发中如何高效稳定地将Word文档转换为PDF格式? 这个看似简单的需求,在企业合同电子归档、财务报表批量生成等场景中,开发者往往会遇到不同的问题,如样式错乱、字体丢失等。
今天我们将通过实测代码,展示如何用 Spire.Doc for Java 库实现Word到PDF文档的快速转换,并解析其转换选项的灵活配置技巧。
方法一:三步实现核心功能
步骤1:添加Maven依赖
<repositories>
<repository>
<id>com.e-iceblue</id>
<name>e-iceblue</name>
<url>https://repo.e-iceblue.cn/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.xls</artifactId>
<version>15.7.7</version>
</dependency>
</dependencies>
步骤2:核心代码示例 (支持Doc和Docx格式)
// 创建文档对象模型
Document doc = new Document();
// 加载Word
doc.loadFromFile("input.docx");
// 保存为PDF
doc.saveToFile("output.pdf", FileFormat.PDF);
doc.dispose();
步骤3:异常处理
try {
// 转换代码...
} catch (DocumentException e) {
System.err.println("转换失败: " + e.getMessage());
throw new RuntimeException(e);
}
最佳实践
生产环境务必调用doc.close()释放资源,避免服务器出现文件句柄泄露
方法二:高级选项配置
转换过程中通过 ToPdfParameterList 对象可实现精细控制:
| 选项参数 | 作用描述 | 典型应用场景 |
|---|---|---|
| isEmbeddedAllFonts | 强制嵌入所有字体 | 跨系统排版一致性 |
| setDisableLink | 禁用超链接 | 安全文档转换 |
| setPdfConformanceLevel | 设置PDF标准规范 | 归档级文档(法律/医疗 |
| setCreateWordBookmarks | 保留书签 | 技术手册/论文等长文档导航 |
加密PDF代码示例:
// 高级转换配置示例
ToPdfParameterList options = new ToPdfParameterList();
options.setPdfConformanceLevel(PdfConformanceLevel.Pdf_A_1_B); // 符合PDF/A-1b标准
String password1 = "E-iceblue"; // 打开密码
String password2 = "123"; // 用户密码
options..getPdfSecurity().encrypt(password1, password2, PdfPermissionsFlags.None, PdfEncryptionKeySize.Key_128_Bit); // 加密PDF
// 转换Word为PDF
Document doc = new Document();
doc.loadFromFile("机密报告.docx");
doc.saveToFile("加密文档.pdf", options);
最佳实践
转换时还可通过 setJPEGQuality 设置图片压缩质量 (0-100),以优化PDF体积。
性能优化建议
内存管理: 处理50页以上文档时,采用分段加载减少单次内存占用
批量处理:
File[] files = new File("docs/").listFiles((dir, name) -> name.endsWith(".docx"));
for (File file : files) {
// 循环调用转换方法...
}
方法补充
Java 实现 Word 转PDF方案
转换方案选择
项目开发我主要使用过 Aspose 和 LibreOffice,两者代码实现都很简单,转换效果也不错。其他生成 pdf 的方案,比如使用 html 转换、xml、或者直接操作 pdf 模板,实际使用代码逻辑繁琐不易理解,且转换生成效果一般。LibreOffice主要是后期做复杂的 pdf 模板导出,使用 word 难以动态填充内容,后来使用 excel,在 java中计算后填充 excel,设置好格式在转换拼接 pdf 最后输出。
- Aspose:商业收费软件,免费版有水印。
- LibreOffice:开源免费, 需要部署环境安装LibreOffice,实际使用需要控制并发与文件大小,避免对服务器整体造成影响。
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. 实际使用
基本用法:
// 先创建一个临时文件用来存储 PDF
String 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);
}
}LibreOffice 实现方案(对应 excel 也可以直接使用)
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());
}
}
}
}到此这篇关于Java高效实现Word转PDF的完整指南的文章就介绍到这了,更多相关Java Word转PDF内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
