1.业务需求
在word的文件中,当生成一些模板时我们,我们经常使用“${**}”来标志需要替换的文件,如${name}就是要将name的字段替换成真实的姓名。所以我们需要用正则表达式来寻找到广本的内容是否包含了“${}”。正则表达式是:\\{.+?\\}。同时,我们需要用poi提供的XWPFRun的接口来替换文本。为了使用替换后的文本可以的换行的操作。
小编编写了一个工具类,希望对大家有用
package csyl.custom.demo;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.xwpf.usermodel.PositionInParagraph;
import org.apache.poi.xwpf.usermodel.TextSegement;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
/**
* @author wsg
* @创建时间: 2019年6月25日下午6:26:21
*/
public class WordUtils {
public static void replaceDocx(String readPath, String outPath, Map
// 解析docx模板并获取document对象
XWPFDocument document;
try {
document = new XWPFDocument(POIXMLDocument.openPackage(readPath));
// 修改表格对象
modifyTable(document, map);
// 修改内容
modifyText(document, map);
try {
storeDocx(document, outPath);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void modifyTable(XWPFDocument document, Map
Iterator
while (itTable.hasNext()) {
XWPFTable table = (XWPFTable) itTable.next();
replaceTableText(document, map, table);
}
}
public static void replaceTableText(XWPFDocument document, Map
// 获取table的行数
int count = table.getNumberOfRows();
for (int i = 0; i < count; i++) {
XWPFTableRow row = table.getRow(i);
List
for (XWPFTableCell cell : cells) {
List
for (int j = 0; j < paragraphs.size(); j++) {
XWPFParagraph xwpfParagraph = paragraphs.get(j);
List
for (Map.Entry
String oldText = replPair.getKey();
String newText = replPair.getValue();
replaceText(xwpfParagraph, runs, oldText, newText);
}
}
}
}
}
public static void modifyText(XWPFDocument document, Map
List
for (XWPFParagraph xwpfParagraph : paragraphs) {
// 文档下面的runs标签
List
for (Map.Entry
String oldText = replPair.getKey();
String newText = replPair.getValue();
replaceText(xwpfParagraph, runs, oldText, newText);
}
}
}
private static void replaceText(XWPFParagraph xwpfParagraph, List
// 获取文本段
TextSegement tSegement = xwpfParagraph.searchText(oldText, new PositionInParagraph());
if (tSegement != null) {
// 得到对应字符串出现的首个runs标签
int beginRun = tSegement.getBeginRun();
// 得到对应字符串出现的末尾runs标签
int endRun = tSegement.getEndRun();
// 在同一个runs标签
StringBuilder b = new StringBuilder();
for (int runPos = beginRun; runPos <= endRun; runPos++) {
XWPFRun run = runs.get(runPos);
b.append(run.getText(0));
}
String connectedRuns = b.toString();
String replaced = connectedRuns.replace(oldText, newText);
XWPFRun partOne = runs.get(beginRun);
partOne.setText(replaced, 0);
for (int runPos = beginRun + 1; runPos <= endRun; runPos++) {
XWPFRun partNext = runs.get(runPos);
partNext.setText("", 0);
}
if (endRun <= runs.size()) {
replaceText(xwpfParagraph, runs, oldText, newText);
}
}
}
public static void storeDocx(XWPFDocument document, String outPath) throws Exception {
File file = new File(outPath.trim());
OutputStream os = new FileOutputStream(file);
// 把document输出
document.write(os);
document.close();
os.close();
}
}