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之后,導(dǎo)致Apache POI 相關(guān)的庫版本不一致導(dǎo)致,供參考。
1.2.2創(chuàng)建具體業(yè)務(wù)方法
這里沒有創(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()方法返回整個文檔的范圍,包括所有段落、表格、標(biāo)題等內(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();
// 從當(dāng)前索引 index 開始繼續(xù)查找下一個占位符,若找到下一個占位符,更新 index 為新位置
// 若找不到,index 將為 -1,循環(huán)結(jié)束
index = textBuilder.indexOf(entry.getKey(), index);
}
}
// 將替換后的文本重新設(shè)置到文本塊中
run.setText(textBuilder.toString(), 0);
}
}
}
}
}
}
1.3測試
使用postMan測試接口

1.4擴展
可以將文檔上傳到數(shù)據(jù)庫中,每次生成的時候先獲取文檔,再對文檔做處理;
這里是將文檔生成到指定位置,若是要在瀏覽器中生成-下載到具體位置,可利用
HttpServletResponse類,將其寫入HttpServletResponse的輸出流,然后設(shè)置適當(dāng)?shù)捻憫?yīng)頭,使瀏覽器將響應(yīng)內(nèi)容作為文件下載@GetMapping("/download") public void downloadDocument(HttpServletResponse response) { // 創(chuàng)建一個新的 XWPFDocument 對象 XWPFDocument document = new XWPFDocument(); //具體業(yè)務(wù)處理方法 ...... try { // .doc格式文檔,設(shè)置響應(yīng)內(nèi)容類型為 Word 文檔 response.setContentType("application/msword"); // .doc格式文檔,設(shè)置響應(yīng)頭,指示瀏覽器將響應(yīng)內(nèi)容作為文件下載 response.setHeader("Content-Disposition", "attachment; filename=sample.doc"); // .docx格式文檔,設(shè)置響應(yīng)內(nèi)容類型為 Word 文檔 response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document"); // .docx格式文檔,設(shè)置響應(yīng)頭,指示瀏覽器將響應(yīng)內(nèi)容作為文件下載 response.setHeader("Content-Disposition", "attachment; filename=sample.docx"); // 將文檔寫入響應(yīng)的輸出流 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-02
Idea調(diào)用WebService的關(guān)鍵步驟和注意事項
這篇文章主要介紹了如何在Idea中調(diào)用WebService,包括理解WebService的基本概念、獲取WSDL文件、閱讀和理解WSDL文件、選擇對接測試工具或方式、發(fā)送請求和接收響應(yīng)、處理響應(yīng)結(jié)果以及錯誤處理,需要的朋友可以參考下2025-01-01
Spring boot調(diào)用Oracle存儲過程的兩種方式及完整代碼
這篇文章主要給大家介紹了關(guān)于Spring boot調(diào)用Oracle存儲過程的兩種方式及完整代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
java利用url實現(xiàn)網(wǎng)頁內(nèi)容的抓取
本文主要介紹了java利用url實現(xiàn)網(wǎng)頁內(nèi)容抓取的示例。具有很好的參考價值。下面跟著小編一起來看下吧2017-03-03
maven插件spring-boot-starter-tomcat的使用方式
這篇文章主要介紹了maven插件spring-boot-starter-tomcat的使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07
Java設(shè)計模塊系列之書店管理系統(tǒng)單機版(二)
這篇文章主要為大家詳細(xì)介紹了Java單機版的書店管理系統(tǒng)設(shè)計模塊和思想第二章,感興趣的小伙伴們可以參考一下2016-08-08

