Java實(shí)現(xiàn)WORD和PDF互相轉(zhuǎn)換以及數(shù)據(jù)填充示例
最近碰到一個(gè)需求,就是有一些 WORD 或者 PDF 的模板,然后根據(jù)用戶(hù)填入的數(shù)據(jù)填充進(jìn)去,還要根據(jù)用戶(hù)選擇要 PDF 還是 WORD 下載下來(lái)
所以綜合下來(lái)就是兩個(gè)功能:
- 1.WORD 和 PDF 模板填充
- 2.WORD 和 PDF 互相轉(zhuǎn)換
直接上代碼
首先是導(dǎo)入我們需要的 jar 包 (這里有點(diǎn)要注意,aspose其實(shí)是個(gè)收費(fèi)包,下面的代碼我這里用的網(wǎng)上找的破解證書(shū),當(dāng)然不用證書(shū)也可以,只是有些功能用不了,但是我試了下發(fā)現(xiàn)除了多了個(gè)提示也沒(méi)什么問(wèn)題,所以大家可以直接用)
<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>
這里要注意可能會(huì)出現(xiàn)導(dǎo)入不了的情況,要是導(dǎo)入不了可以加入下面的地址試一下,或者直接去阿里的倉(cāng)庫(kù)找一下下載下來(lái)導(dǎo)入,怎么導(dǎo)入大家自己百度一下很簡(jiǎn)單 阿里Maven倉(cāng)庫(kù)
<repositories>
<repository>
<id>aspose-maven-repo</id>
<url>https://repository.aspose.com/repo/</url>
</repository>
</repositories>

這里我封裝了一個(gè)工具類(lèi),里面帶測(cè)試方法的
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 模板并導(dǎo)出為 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); // 使填充的內(nèi)容不可編輯
stamper.close();
// 復(fù)制并保存 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 轉(zhuǎn) Word (docx),支持多頁(yè)轉(zhuǎn)換
*/
public static boolean convertPdfToWord(String pdfPath, String wordPath) {
try {
// 使用 Aspose PDF API 來(lái)加載 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 轉(zhuǎn) PDF,支持多頁(yè)轉(zhuǎn)換
*/
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轉(zhuǎn)PDF測(cè)試.pdf";
WordPdfUtils.convertWordToPdf(wordPath, pdfPath);
String pdfPath1 = "C:\\Users\\72364\\Desktop\\fsdownload\\PDF模板.pdf";
String wordPath1 = "C:\\Users\\72364\\Desktop\\fsdownload\\PDF轉(zhuǎn)WORD測(cè)試.docx";
WordPdfUtils.convertPdfToWord(pdfPath1, wordPath1);
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("name", "66666666666");
// 測(cè)試 Word 填充
String wordTemplatePath = "C:\\Users\\72364\\Desktop\\fsdownload\\WORD填充模板.docx";
String outputWordPath = "C:\\Users\\72364\\Desktop\\fsdownload\\WORD填充測(cè)試.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();
}
// 測(cè)試 PDF 填充
String pdfTemplatePath = "C:\\Users\\72364\\Desktop\\fsdownload\\PDF填充模板.pdf";
String outputPdfFilledPath = "C:\\Users\\72364\\Desktop\\fsdownload\\PDF填充測(cè)試.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();
}
}
}
下面是我的模板和測(cè)試后生成的文件,所以上面的功能都是測(cè)試后正常可用的

這里主要說(shuō)一下填充模板怎么制作
首先是 WORD填充模板
我們建一個(gè) WORD 文檔,直接用 WPS 打開(kāi),找到 插入 - 書(shū)簽

然后輸入屬性名稱(chēng)如 name 即可

接下來(lái)是 PDF填充模板,這個(gè)麻煩些,需要能編輯 PDF 的工具,WPS 編輯 PDF 要充會(huì)員,我比較窮肯定不會(huì)充會(huì)員(我要是有錢(qián)充會(huì)員我還寫(xiě)這些代碼干啥),所以這里我找了一個(gè)破解版的 Adobe Acrobat DC (找不到的可以私聊找我要),一樣的我們建一個(gè) PDF 文檔, 然后用 Adobe Acrobat DC 打開(kāi)
我們找到 工具 - 準(zhǔn)備表單 (WPS 好像也有類(lèi)似的功能,但是要錢(qián))

然后選那個(gè) 添加“文本”域,把里面的文字改成name

這樣模板就只做好了,我們執(zhí)行上面的測(cè)試方法,就可以得到下面的幾個(gè)文件
PDF填充測(cè)試
可以看到這個(gè)位置不對(duì),大家自己在模板里面慢慢拖到正確位置就可以了

PDF轉(zhuǎn)WORD測(cè)試
這里就是我說(shuō)的證書(shū)問(wèn)題,可以看到頭部有一行紅色的“Evaluation Only. Created with Aspose.Pdf. Copyright 2002-2017 Aspose Pty Ltd.”,大家手動(dòng)刪除一下就可以,因?yàn)樯厦婺莻€(gè)破解的證書(shū)里面只有 Aspose.Words for Java 所以 aspose-pdf 就用不了這個(gè)證書(shū),誰(shuí)要是找到了完整的證書(shū)希望可以給我一份

WORD填充測(cè)試
這里不知道為啥內(nèi)容旁邊有個(gè)括號(hào),還刪不掉

WORD轉(zhuǎn)PDF測(cè)試
可以看到第二頁(yè)還有樣式這些都是保留下來(lái)的

以上就是Java實(shí)現(xiàn)WORD和PDF互相轉(zhuǎn)換以及數(shù)據(jù)填充示例的詳細(xì)內(nèi)容,更多關(guān)于Java WORD和PDF互轉(zhuǎn)及填充的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Java實(shí)現(xiàn)Word轉(zhuǎn)PDF的全過(guò)程
- Java調(diào)用py或者exe文件實(shí)現(xiàn)Word轉(zhuǎn)PDF
- Java實(shí)現(xiàn)一鍵將Word文檔轉(zhuǎn)為PDF
- java將word轉(zhuǎn)pdf的方法示例詳解
- Java將Word文檔轉(zhuǎn)換為PDF文件的幾種常用方法總結(jié)
- Java中Word與PDF轉(zhuǎn)換為圖片的方法詳解
- Java將Word轉(zhuǎn)換成PDF的常用用法
- 探討Java 將Markdown文件轉(zhuǎn)換為Word和PDF文檔
- Java將word文件轉(zhuǎn)成pdf文件的操作方法
- Java實(shí)現(xiàn)word/pdf轉(zhuǎn)html并在線(xiàn)預(yù)覽
- Java實(shí)現(xiàn)一鍵將Word文檔轉(zhuǎn)為PDF的兩種方法
相關(guān)文章
SpringBoot基于自定義注解實(shí)現(xiàn)切面編程
這篇文章主要介紹了SpringBoot基于自定義注解實(shí)現(xiàn)切面編程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11
詳解如何讓Spring MVC顯示自定義的404 Not Found頁(yè)面
這篇文章主要介紹了詳解如何讓Spring MVC顯示自定義的404 Not Found頁(yè)面,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-10-10
Spring Security常用過(guò)濾器實(shí)例解析
這篇文章主要介紹了Spring Security常用過(guò)濾器實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
帶你詳細(xì)了解Spring Security的注解方式開(kāi)發(fā)
這篇文章主要介紹了詳解spring security四種實(shí)現(xiàn)方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-08-08
IntelliJ IDEA的build path設(shè)置方法
這篇文章主要介紹了IntelliJ IDEA的build path設(shè)置方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04
Java中的SynchronousQueue阻塞隊(duì)列使用代碼實(shí)例
這篇文章主要介紹了Java中的SynchronousQueue阻塞隊(duì)列使用代碼實(shí)例,SynchronousQueue是無(wú)緩沖區(qū)的阻塞隊(duì)列,即不能直接向隊(duì)列中添加數(shù)據(jù),會(huì)報(bào)隊(duì)列滿(mǎn)異常,需要的朋友可以參考下2023-12-12

