1、要填充的文件模板,里面需要填充的内容使用${xxxx}。
2、以map的形式,编辑要填充的数据内容
public class OtherDesignReportServiceImpl implements IOtherDesignReportService
{
private XWPFHelper xwpfHelper = null;
public OtherDesignReportServiceImpl() {
xwpfHelper = new XWPFHelper();
}
/**
* 导出报告
*
* @param busiApplyInfoList 报告列表
* @return 结果
*/
public void export(){
// 打开模板,获取表格
XWPFDocument document = xwpfHelper.openDoc("报告_1.docx");
// 编辑标题、填报信息
xwpfHelper.replaceInPara(document, editTitleAndFillData());
// 生成文件
xwpfHelper.saveDocument(document, "报告_2.docx");
}
/**
* 编辑报表标题、填充的数据
*/
private Map<String, Object> editTitleAndFillData() {
Map<String, Object> params = new HashMap<String, Object>();
params.put("city", "济南市");
params.put("season", "第四季度");
params.put("fillOrg", String.format("%-31s", "XXXX设计局"));
params.put("fillYear", String.format("%-4s", "2021"));
params.put("fillMonth", String.format("%-2s", "08"));
params.put("fillDay", String.format("%-2s", "04"));
params.put("fillUser", String.format("%-12s", "张华强"));
params.put("fillPhone", String.format("%-11s", "13398764567"));
return params;
}
}
3、进行占位符替换的操作
public class XWPFHelper {
/**
* 替换段落里面的变量
* @param doc 要替换的文档
* @param params 参数
*/
public void replaceInPara(XWPFDocument doc, Map<String, Object> params) {
for (XWPFParagraph para : doc.getParagraphs()) {
replaceInPara(para, params);
}
}
/**
* 替换段落里面的变量
* @param para 要替换的段落
* @param params 参数
*/
private void replaceInPara(XWPFParagraph para, Map<String, Object> params) {
List<XWPFRun> runs = null;
Matcher matcher = null;
if (this.matcher(para.getParagraphText()).find()) {
// 如果para拆分的不对,则用这个方法修改成正确的
runs = replaceText(para);
for (int i = 0; i < runs.size(); i++) {
XWPFRun run = runs.get(i);
String runText = run.toString();
String fontType = "";
matcher = this.matcher(runText);
if (matcher.find()) {
while ((matcher = this.matcher(runText)).find()) {
fontType = matcher.group(1);
runText = matcher.replaceFirst(String.valueOf(params.get(matcher.group(1))));
}
// 直接调用XWPFRun的setText()方法设置文本时,在底层会重新创建一个XWPFRun,把文本附加在当前文本后面,
// 所以我们不能直接设值,需要先删除当前run,然后再自己手动插入一个新的run。
para.removeRun(i);
XWPFRun runX = para.insertNewRun(i);
runX.setText(runText);
// 设置字体样式
if ("city".equals(fontType)) {
runX.setFontFamily("楷体");
runX.setFontSize(15);
runX.setBold(true);
runX.setUnderline(UnderlinePatterns.SINGLE);
} else if ("season".equals(fontType)) {
runX.setFontFamily("楷体");
runX.setFontSize(15);
runX.setBold(true);
} else if ("fillOrg".equals(fontType) || "fillYear".equals(fontType) ||
"fillMonth".equals(fontType) || "fillDay".equals(fontType) ||
"fillUser".equals(fontType) || "fillPhone".equals(fontType)) {
runX.setFontFamily("仿宋");
runX.setFontSize(12);
runX.setBold(false);
}
}
}
}
}
/**
* 合并runs中的内容
* @param para 要替换的段落
* @return
*/
private List<XWPFRun> replaceText(XWPFParagraph para) {
List<XWPFRun> runs = para.getRuns();
String str = "";
boolean flag = false;
for (int i = 0; i < runs.size(); i++) {
XWPFRun run = runs.get(i);
String runText = run.toString();
if (flag || runText.equals("${")) {
str = str + runText;
flag = true;
para.removeRun(i);
if (runText.equals("}")) {
flag = false;
para.insertNewRun(i).setText(str);
str = "";
}
i--;
}
}
return runs;
}
/**
* 正则匹配字符串
* @param str
* @return
*/
private Matcher matcher(String str) {
Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(str);
return matcher;
}
}
4、执行结果
5、OK,以上整理完毕!