用JAVA处理Word文档
替换文档中指定的文本
选用依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
- 代码
package com.example.parseword.util;
import org.apache.poi.ooxml.POIXMLDocument;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@RestController
@RequestMapping("/parse")
public class Parse {
/**
* 替换段落中的占位符
* @param params 替换的参数,key=占位符,value=实际值
*/
@PostMapping("/replace")
public static void replaceInPara(@RequestBody Map<String,Object> params) throws IOException {
String filePath = "这里自己写路径";
String outPath = "这里自己写路径";
//获取.docx文件提取器
XWPFDocument doc = new XWPFDocument(POIXMLDocument.openPackage(filePath));
Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
XWPFParagraph para;
while (iterator.hasNext()) {
para = iterator.next();
if(!StringUtils.isEmpty(para.getParagraphText())){
replaceInPara(para, params);
replaceTable(doc,params);
}
}
FileOutputStream fileOutputStream = new FileOutputStream(outPath);
doc.write(fileOutputStream);
fileOutputStream.close();
}
/**
* 替换段落中的占位符
* @param para
*/
public static void replaceInPara(XWPFParagraph para, Map<String,Object> params) {
// 获取当前段落的文本
String sourceText = para.getParagraphText();
// 控制变量
boolean replace = false;
for (Map.Entry<String, Object> entry : params.entrySet()) {
String key = entry.getKey();
// 替换文本占位符
if(sourceText.contains(key)){
Object value = entry.getValue();
if(value instanceof String){
sourceText = sourceText.replace(key, value.toString());
replace = true;
}
}
}
if(replace){
// 获取段落中的行数
List<XWPFRun> runList = para.getRuns();
for (int i=runList.size();i>=0;i--){
// 删除之前的行
para.removeRun(i);
}
// 创建一个新的文本并设置为替换后的值 这样操作之后之前文本的样式就没有了,待改进
para.createRun().setText(sourceText);
}
}
/**
* 替换表格中的占位符
* @param doc
* @param params
*/
public static void replaceTable(XWPFDocument doc,Map<String,Object> params){
// 获取文档中所有的表格
Iterator<XWPFTable> iterator = doc.getTablesIterator();
XWPFTable table;
List<XWPFTableRow> rows;
List<XWPFTableCell> cells;
List<XWPFParagraph> paras;
while (iterator.hasNext()) {
table = iterator.next();
if (table.getRows().size() > 1) {
//判断表格是需要替换还是需要插入,判断逻辑有${为替换,
// if (matcher(table.getText()).find()) {
rows = table.getRows();
for (XWPFTableRow row : rows) {
cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
paras = cell.getParagraphs();
for (XWPFParagraph para : paras) {
replaceInPara(para, params);
}
}
}
// }
}
}
}
/**
* 正则匹配字符串
*
* @param str
* @return
*/
private static Matcher matcher(String str) {
Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(str);
return matcher;
}
}
这里我没有识别特殊符号比如${}这种的样式,如果有这个需求的,可以把我注释掉的那一行代码放开,亲测可用
放下效果图
这是我的参数,value就是我要替换成的值