Java WORD和PDF互相转换以及数据填充示例
最近碰到一个需求,就是有一些 WORD 或者 PDF 的模板,然后根据用户填入的数据填充进去,还要根据用户选择要 PDF 还是 WORD 下载下来
所以综合下来就是两个功能:
1.WORD 和 PDF 模板填充
2.WORD 和 PDF 互相转换
直接上代码
首先是导入我们需要的 jar 包 (这里有点要注意,aspose其实是个收费包,下面的代码我这里用的网上找的破解证书,当然不用证书也可以,只是有些功能用不了,但是我试了下发现除了多了个提示也没什么问题,所以大家可以直接用)
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.11</version>
</dependency>
<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-words</artifactId>
<version>16.8.0</version>
</dependency>
<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-pdf</artifactId>
<version>17.3.0</version>
</dependency>
这里要注意可能会出现导入不了的情况,要是导入不了可以加入下面的地址试一下,或者直接去阿里的仓库找一下下载下来导入,怎么导入大家自己百度一下很简单 阿里Maven仓库
<repositories>
<repository>
<id>aspose-maven-repo</id>
<url>https://repository.aspose.com/repo/</url>
</repository>
</repositories>
这里我封装了一个工具类,里面带测试方法的
package com.yatai.common.tool;
import com.aspose.words.*;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.*;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
/**
* @author Sakura
* @date 2025/2/7 13:26
*/
public class WordPdfUtils {
/**
* 加载 Aspose License
*/
private static boolean loadAsposeLicense() {
try {
// 凭证
String licenseStr =
"<License>\n" +
" <Data>\n" +
" <Products>\n" +
" <Product>Aspose.Total for Java</Product>\n" +
" <Product>Aspose.Words for Java</Product>\n" +
" </Products>\n" +
" <EditionType>Enterprise</EditionType>\n" +
" <SubscriptionExpiry>20991231</SubscriptionExpiry>\n" +
" <LicenseExpiry>20991231</LicenseExpiry>\n" +
" <SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>\n" +
" </Data>\n" +
" <Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature>\n" +
"</License>";
InputStream license = new ByteArrayInputStream(licenseStr.getBytes("UTF-8"));
License asposeLic = new License();
asposeLic.setLicense(license);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 使用 Aspose 填充 Word 模板并导出为 Word
*/
public static boolean fillWordTemplate(String templatePath, String outputWordPath, Map<String, Object> dataMap) throws Exception {
if (!loadAsposeLicense()) {
return false;
}
// 加载 Word 模板
Document document = new Document(new FileInputStream(templatePath));
DocumentBuilder builder = new DocumentBuilder(document);
// 填充 Word 文档的占位符
for (String key : dataMap.keySet()) {
if (builder.moveToBookmark(key)) {
builder.write(String.valueOf(dataMap.get(key)));
}
}
// 保存为 Word 文件
document.save(outputWordPath, SaveFormat.DOCX);
return true;
}
/**
* 使用 iTextPDF 填充 PDF 模板
*/
public static boolean fillPdfTemplate(String templatePath, String outputPdfPath, Map<String, Object> dataMap, int pageCount) {
PdfReader reader = null;
PdfStamper stamper = null;
ByteArrayOutputStream bos = null;
com.itextpdf.text.Document doc = null;
PdfCopy copy = null;
try {
// 加载 PDF 模板
reader = new PdfReader(templatePath);
bos = new ByteArrayOutputStream();
stamper = new PdfStamper(reader, bos);
AcroFields form = stamper.getAcroFields();
BaseFont baseFont = BaseFont.createFont("C:\\WINDOWS\\Fonts\\simsun.ttc,1", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
form.addSubstitutionFont(baseFont);
// 填充 PDF 表单字段
for (String key : dataMap.keySet()) {
form.setField(key, String.valueOf(dataMap.get(key)));
}
stamper.setFormFlattening(true); // 使填充的内容不可编辑
stamper.close();
// 复制并保存 PDF
doc = new com.itextpdf.text.Document();
copy = new PdfCopy(doc, new FileOutputStream(outputPdfPath));
doc.open();
PdfReader finalReader = new PdfReader(bos.toByteArray());
for (int i = 1; i <= pageCount; i++) {
PdfImportedPage importPage = copy.getImportedPage(finalReader, i);
copy.addPage(importPage);
}
finalReader.close();
} catch (IOException | DocumentException e) {
e.printStackTrace();
return false;
} finally {
try {
if (copy != null) copy.close();
if (doc != null) doc.close();
if (stamper != null) stamper.close();
if (reader != null) reader.close();
if (bos != null) bos.close();
} catch (IOException | DocumentException e) {
e.printStackTrace();
}
}
return true;
}
/**
* PDF 转 Word (docx),支持多页转换
*/
public static boolean convertPdfToWord(String pdfPath, String wordPath) {
try {
// 使用 Aspose PDF API 来加载 PDF 文件
com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(pdfPath);
// 保存为 Word 文件
pdfDocument.save(wordPath, com.aspose.pdf.SaveFormat.DocX);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* Word 转 PDF,支持多页转换
*/
public static boolean convertWordToPdf(String wordPath, String pdfPath) {
if (!loadAsposeLicense()) {
return false;
}
try {
Document wordDocument = new Document(wordPath);
wordDocument.save(pdfPath, SaveFormat.PDF);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static void main(String[] args) {
String wordPath = "C:\\Users\\72364\\Desktop\\fsdownload\\WORD模板.docx";
String pdfPath = "C:\\Users\\72364\\Desktop\\fsdownload\\WORD转PDF测试.pdf";
WordPdfUtils.convertWordToPdf(wordPath, pdfPath);
String pdfPath1 = "C:\\Users\\72364\\Desktop\\fsdownload\\PDF模板.pdf";
String wordPath1 = "C:\\Users\\72364\\Desktop\\fsdownload\\PDF转WORD测试.docx";
WordPdfUtils.convertPdfToWord(pdfPath1, wordPath1);
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("name", "66666666666");
// 测试 Word 填充
String wordTemplatePath = "C:\\Users\\72364\\Desktop\\fsdownload\\WORD填充模板.docx";
String outputWordPath = "C:\\Users\\72364\\Desktop\\fsdownload\\WORD填充测试.docx";
try {
boolean result = WordPdfUtils.fillWordTemplate(wordTemplatePath, outputWordPath, dataMap);
if (result) {
System.out.println("Word 模板填充成功!");
} else {
System.out.println("Word 模板填充失败!");
}
} catch (Exception e) {
e.printStackTrace();
}
// 测试 PDF 填充
String pdfTemplatePath = "C:\\Users\\72364\\Desktop\\fsdownload\\PDF填充模板.pdf";
String outputPdfFilledPath = "C:\\Users\\72364\\Desktop\\fsdownload\\PDF填充测试.pdf";
try {
boolean result = WordPdfUtils.fillPdfTemplate(pdfTemplatePath, outputPdfFilledPath, dataMap, 1);
if (result) {
System.out.println("PDF 模板填充成功!");
} else {
System.out.println("PDF 模板填充失败!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
下面是我的模板和测试后生成的文件,所以上面的功能都是测试后正常可用的
这里主要说一下填充模板怎么制作
首先是 WORD填充模板
我们建一个 WORD 文档,直接用 WPS 打开,找到 插入 - 书签
然后输入属性名称如 name 即可
接下来是 PDF填充模板,这个麻烦些,需要能编辑 PDF 的工具,WPS 编辑 PDF 要充会员,我比较穷肯定不会充会员(我要是有钱充会员我还写这些代码干啥),所以这里我找了一个破解版的 Adobe Acrobat DC (找不到的可以私聊找我要),一样的我们建一个 PDF 文档, 然后用 Adobe Acrobat DC 打开
我们找到 工具 - 准备表单 (WPS 好像也有类似的功能,但是要钱)
然后选那个 添加“文本”域,把里面的文字改成name
这样模板就只做好了,我们执行上面的测试方法,就可以得到下面的几个文件
PDF填充测试
可以看到这个位置不对,大家自己在模板里面慢慢拖到正确位置就可以了
PDF转WORD测试
这里就是我说的证书问题,可以看到头部有一行红色的“Evaluation Only. Created with Aspose.Pdf. Copyright 2002-2017 Aspose Pty Ltd.”,大家手动删除一下就可以,因为上面那个破解的证书里面只有 Aspose.Words for Java 所以 aspose-pdf 就用不了这个证书,谁要是找到了完整的证书希望可以给我一份
WORD填充测试
这里不知道为啥内容旁边有个括号,还删不掉
WORD转PDF测试
可以看到第二页还有样式这些都是保留下来的