java方法替換word文檔中需要替換的部分操作步驟
1.提供一個word文檔,java方法替換需要替換的內(nèi)容
測試文檔:
測試文檔HWPFDocument.doc;測試文檔XWPFDocument.docx
文檔內(nèi)容:
替換后的文檔內(nèi)容:
1.1概述
處理 .doc 文件,使用POI依賴的HWPFDocument類和相關(guān)的類Range和Paragraph來處理;
處理 .docx 文件,使用POI依賴的XWPFParagraph類和XWPFRun的結(jié)構(gòu)化方法來逐段處理文檔。
1.2操作步驟
1.2.1引入依賴
本項目使用的aliyun的鏡像庫,處理word文檔引入的是POI依賴,這是一套可以兼容處理doc和docx文件的依賴版本。
<!-- Apache POI dependencies --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.apache.xmlbeans</groupId> <artifactId>xmlbeans</artifactId> <version>3.1.0</version> </dependency> <!-- Apache POI dependencies for OOXML (.docx) --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>4.1.2</version> </dependency> <!-- Apache POI dependencies for OLE2 (.doc) --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-scratchpad</artifactId> <version>4.1.2</version> </dependency>
我這里是引入poi-scratchpad
之后不兼容,報錯:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.NoSuchFieldError: Factory] with root cause
就是因為引入poi-scratchpad
之后,導致Apache POI 相關(guān)的庫版本不一致導致,供參考。
1.2.2創(chuàng)建具體業(yè)務方法
這里沒有創(chuàng)建service層,直接在controller層實現(xiàn)方法
@RestController @RequestMapping("/word") public class DocumentWordController { @PostMapping("/uploadAndReplaceWord") public String uploadAndReplace(@RequestParam("file") MultipartFile file, @RequestParam Map<String, String> replacements) { // MultipartFile 接口的方法之一,返回上傳文件的內(nèi)容類型(MIME 類型) String contentType = file.getContentType(); // 保存修改后的文檔 String outputPath = "C:\\*****\\*****\\*****\\result"; try { if (contentType != null && contentType.equals("application/msword")) { // 處理 .doc 文件 HWPFDocument document = new HWPFDocument(file.getInputStream()); replacePlaceholdersInDoc(document, replacements); outputPath += ".doc"; try (FileOutputStream out = new FileOutputStream(outputPath)) { document.write(out); } } else if (contentType != null && contentType.equals("application/vnd.openxmlformats-officedocument.wordprocessingml.document")) { // 處理 .docx 文件 XWPFDocument document = new XWPFDocument(file.getInputStream()); replacePlaceholdersInDocx(document, replacements); outputPath += ".docx"; try (FileOutputStream out = new FileOutputStream(outputPath)) { document.write(out); } } else { return "文件類型不支持:" + contentType; } return "文檔處理完成,保存至:" + outputPath; } catch (IOException e) { e.printStackTrace(); return "文檔處理失敗"; } } // 處理 .doc 文件 // HWPFDocument類沒有與XWPFParagraph和XWPFRun類似的結(jié)構(gòu)化方法來逐段處理文檔 // 所以需要使用HWPFDocument和相關(guān)的類Range和Paragraph來處理 private void replacePlaceholdersInDoc(HWPFDocument document, Map<String, String> replacements) { // Range對象表示W(wǎng)ord文檔中的一段文本范圍 // document.getRange()方法返回整個文檔的范圍,包括所有段落、表格、標題等內(nèi)容 Range range = document.getRange(); // 遍歷替換映射中的每個鍵值對,并將文本塊中的占位符替換為指定的值,entry.getKey() 是占位符(如${name}) for (Map.Entry<String, String> entry : replacements.entrySet()) { // 替換范圍內(nèi)的文本:在整個文本內(nèi)找到所有匹配entry.getKey()的文本,并用entry.getValue()替換它們 range.replaceText(entry.getKey(), entry.getValue()); } } // 處理 .docx 文件 private void replacePlaceholdersInDocx(XWPFDocument document, Map<String, String> replacements) { // 對文檔所有的段落做遍歷 for (XWPFParagraph paragraph : document.getParagraphs()) { // 獲取段落中的文本塊 // 每個段落 (XWPFParagraph) 由一個或多個文本塊 (XWPFRun) 組成,文本塊是段落中的最小文本單位,可以包含格式化信息(如字體、顏色)。 List<XWPFRun> runs = paragraph.getRuns(); // 若包含文本塊,對其做處理 if (runs != null) { for (XWPFRun run : runs) { // 獲取文本塊中的文本內(nèi)容,參數(shù)0表示獲取文本塊中的第一段文本(注:通常只有一段文本) String text = run.getText(0); if (text != null) { // 創(chuàng)建StringBuilder處理字符串替換操作,提高性能,減少 String 對象的創(chuàng)建和銷毀 StringBuilder textBuilder = new StringBuilder(text); // 遍歷替換映射中的每個鍵值對,并將文本塊中的占位符替換為指定的值,entry.getKey() 是占位符(如${name}) // 使用 StringBuilder 的 indexOf 方法找到占位符的位置,并使用 replace 方法進行替換 // 循環(huán)確保所有出現(xiàn)的占位符都被替換 for (Map.Entry<String, String> entry : replacements.entrySet()) { int index = textBuilder.indexOf(entry.getKey()); while (index != -1) { // replace 方法的參數(shù)分別是開始索引、結(jié)束索引和替換內(nèi)容 textBuilder.replace(index, index + entry.getKey().length(), entry.getValue()); // 將其移動到剛替換的文本的末尾 index += entry.getValue().length(); // 從當前索引 index 開始繼續(xù)查找下一個占位符,若找到下一個占位符,更新 index 為新位置 // 若找不到,index 將為 -1,循環(huán)結(jié)束 index = textBuilder.indexOf(entry.getKey(), index); } } // 將替換后的文本重新設置到文本塊中 run.setText(textBuilder.toString(), 0); } } } } } }
1.3測試
使用postMan測試接口
1.4擴展
可以將文檔上傳到數(shù)據(jù)庫中,每次生成的時候先獲取文檔,再對文檔做處理;
這里是將文檔生成到指定位置,若是要在瀏覽器中生成-下載到具體位置,可利用
HttpServletResponse
類,將其寫入HttpServletResponse
的輸出流,然后設置適當?shù)捻憫^,使瀏覽器將響應內(nèi)容作為文件下載@GetMapping("/download") public void downloadDocument(HttpServletResponse response) { // 創(chuàng)建一個新的 XWPFDocument 對象 XWPFDocument document = new XWPFDocument(); //具體業(yè)務處理方法 ...... try { // .doc格式文檔,設置響應內(nèi)容類型為 Word 文檔 response.setContentType("application/msword"); // .doc格式文檔,設置響應頭,指示瀏覽器將響應內(nèi)容作為文件下載 response.setHeader("Content-Disposition", "attachment; filename=sample.doc"); // .docx格式文檔,設置響應內(nèi)容類型為 Word 文檔 response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document"); // .docx格式文檔,設置響應頭,指示瀏覽器將響應內(nèi)容作為文件下載 response.setHeader("Content-Disposition", "attachment; filename=sample.docx"); // 將文檔寫入響應的輸出流 document.write(response.getOutputStream()); // 刷新和關(guān)閉輸出流 response.getOutputStream().flush(); response.getOutputStream().close(); } catch (IOException e) { e.printStackTrace(); } }
總結(jié)
到此這篇關(guān)于java方法替換word文檔中需要替換的部分的文章就介紹到這了,更多相關(guān)java替換word文檔部分內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
排查Failed?to?validate?connection?com.mysql.cj.jdbc.Connec
這篇文章主要介紹了Failed?to?validate?connection?com.mysql.cj.jdbc.ConnectionImpl問題排查,具有很好的參考價值,希望對大家有所幫助2023-02-02Idea調(diào)用WebService的關(guān)鍵步驟和注意事項
這篇文章主要介紹了如何在Idea中調(diào)用WebService,包括理解WebService的基本概念、獲取WSDL文件、閱讀和理解WSDL文件、選擇對接測試工具或方式、發(fā)送請求和接收響應、處理響應結(jié)果以及錯誤處理,需要的朋友可以參考下2025-01-01Spring boot調(diào)用Oracle存儲過程的兩種方式及完整代碼
這篇文章主要給大家介紹了關(guān)于Spring boot調(diào)用Oracle存儲過程的兩種方式及完整代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧2020-08-08java利用url實現(xiàn)網(wǎng)頁內(nèi)容的抓取
本文主要介紹了java利用url實現(xiàn)網(wǎng)頁內(nèi)容抓取的示例。具有很好的參考價值。下面跟著小編一起來看下吧2017-03-03maven插件spring-boot-starter-tomcat的使用方式
這篇文章主要介紹了maven插件spring-boot-starter-tomcat的使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07