Java實(shí)現(xiàn)WORD和PDF互相轉(zhuǎn)換以及數(shù)據(jù)填充示例
最近碰到一個(gè)需求,就是有一些 WORD 或者 PDF 的模板,然后根據(jù)用戶填入的數(shù)據(jù)填充進(jìn)去,還要根據(jù)用戶選擇要 PDF 還是 WORD 下載下來
所以綜合下來就是兩個(gè)功能:
- 1.WORD 和 PDF 模板填充
- 2.WORD 和 PDF 互相轉(zhuǎn)換
直接上代碼
首先是導(dǎo)入我們需要的 jar 包 (這里有點(diǎn)要注意,aspose其實(shí)是個(gè)收費(fèi)包,下面的代碼我這里用的網(wǎng)上找的破解證書,當(dāng)然不用證書也可以,只是有些功能用不了,但是我試了下發(fā)現(xiàn)除了多了個(gè)提示也沒什么問題,所以大家可以直接用)
<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ù)找一下下載下來導(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è)工具類,里面帶測(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 來加載 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è)試后正常可用的
這里主要說一下填充模板怎么制作
首先是 WORD填充模板
我們建一個(gè) WORD 文檔,直接用 WPS 打開,找到 插入 - 書簽
然后輸入屬性名稱如 name 即可
接下來是 PDF填充模板,這個(gè)麻煩些,需要能編輯 PDF 的工具,WPS 編輯 PDF 要充會(huì)員,我比較窮肯定不會(huì)充會(huì)員(我要是有錢充會(huì)員我還寫這些代碼干啥),所以這里我找了一個(gè)破解版的 Adobe Acrobat DC (找不到的可以私聊找我要),一樣的我們建一個(gè) PDF 文檔, 然后用 Adobe Acrobat DC 打開
我們找到 工具 - 準(zhǔn)備表單 (WPS 好像也有類似的功能,但是要錢)
然后選那個(gè) 添加“文本”域,把里面的文字改成name
這樣模板就只做好了,我們執(zhí)行上面的測(cè)試方法,就可以得到下面的幾個(gè)文件
PDF填充測(cè)試
可以看到這個(gè)位置不對(duì),大家自己在模板里面慢慢拖到正確位置就可以了
PDF轉(zhuǎn)WORD測(cè)試
這里就是我說的證書問題,可以看到頭部有一行紅色的“Evaluation Only. Created with Aspose.Pdf. Copyright 2002-2017 Aspose Pty Ltd.”,大家手動(dòng)刪除一下就可以,因?yàn)樯厦婺莻€(gè)破解的證書里面只有 Aspose.Words for Java 所以 aspose-pdf 就用不了這個(gè)證書,誰(shuí)要是找到了完整的證書希望可以給我一份
WORD填充測(cè)試
這里不知道為啥內(nèi)容旁邊有個(gè)括號(hào),還刪不掉
WORD轉(zhuǎn)PDF測(cè)試
可以看到第二頁(yè)還有樣式這些都是保留下來的
以上就是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的全過程
- 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并在線預(yù)覽
- Java實(shí)現(xiàn)一鍵將Word文檔轉(zhuǎn)為PDF的兩種方法
相關(guān)文章
SpringBoot基于自定義注解實(shí)現(xiàn)切面編程
這篇文章主要介紹了SpringBoot基于自定義注解實(shí)現(xiàn)切面編程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11詳解如何讓Spring MVC顯示自定義的404 Not Found頁(yè)面
這篇文章主要介紹了詳解如何讓Spring MVC顯示自定義的404 Not Found頁(yè)面,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-10-10帶你詳細(xì)了解Spring Security的注解方式開發(fā)
這篇文章主要介紹了詳解spring security四種實(shí)現(xiàn)方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-08-08IntelliJ IDEA的build path設(shè)置方法
這篇文章主要介紹了IntelliJ IDEA的build path設(shè)置方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04Java中的SynchronousQueue阻塞隊(duì)列使用代碼實(shí)例
這篇文章主要介紹了Java中的SynchronousQueue阻塞隊(duì)列使用代碼實(shí)例,SynchronousQueue是無緩沖區(qū)的阻塞隊(duì)列,即不能直接向隊(duì)列中添加數(shù)據(jù),會(huì)報(bào)隊(duì)列滿異常,需要的朋友可以參考下2023-12-12