Java使用poi的XWPFDocument 实现word模板动态添加表格行并进行变量替换
Java使用poi的XWPFDocument 实现word模板动态添加表格行并进行变量替换
场景分析
用户在前端页面进行构建理财产品组合时会选择1~N种产品,所以需要word模板对应区域动态生成多行产品行,并将其中内容替换,模板类似下图。
注意!!!!!!模板中的${E1} 这种替换符,一定要从txt等文本中写好再整体粘贴到word模板中,否则可能替换时识别不到完整的替换符。
依赖引入
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.9</version>
</dependency>
代码参考
代码如下(示例):
public static void main(String[] args) throws Exception {
//自行放一个word模板
XWPFDocument document = new XWPFDocument(new FileInputStream("D:\\word\\template.docx"));
//这里代表获取word里面第一个表格。
XWPFTable table = document.getTables().get(0);
//模拟前端数据
Map<String, String> map = new HashMap<>();
map.put("${E1}", "张三");
map.put("${E2}", "6R");
map.put("${E3}", "均衡型");
map.put("${E4}", "李丹");
map.put("${A1}", "15%");
map.put("${A2}", "6%");
map.put("${A3}", "3%");
map.put("${B1}", "理财产品1");
map.put("${B2}", "pro001");
map.put("${B3}", "100w");
map.put("${B4}", "交银");
map.put("${B5}", "基金产品2");
map.put("${B6}", "pro002");
map.put("${B7}", "10w");
map.put("${B8}", "沃德");
map.put("${B9}", "保险产品3");
map.put("${B10}", "pro003");
map.put("${B11}", "33w");
map.put("${B12}", "快捷");
map.put("${C1}", "c1c1c1");
map.put("${C2}", "c2c2c2");
map.put("${C3}", "c3c3c3");
map.put("${C4}", "c4c4c4");
map.put("${C5}", "c5c5c5");
map.put("${D1}", "d1d1d1");
map.put("${D2}", "d2d2d2");
map.put("${D3}", "d3d3d3");
map.put("${D4}", "d4d4d4");
map.put("${D5}", "d5d5d5");
//前端传入:一共几类产品
int productCount = 3;
//模板中的动态表格的变量 ${B?} 从多少开始
int startIndex = 5;
//从目标第几行开始插入,索引从0开始
int newRowIndex = 7;
//复制第七行表格
InputStream inputStream = table.getRow(6).getCtRow().newInputStream();
CTRow ctrow = CTRow.Factory.parse(inputStream);
//for循环复制第7行表格,添加表格行,并将前端穿的参数变量值直接赋上值
for (int i = 0; i < productCount - 1; i++) {
XWPFTableRow row = new XWPFTableRow(ctrow, table);
for (int j = 0; j < 4; j++) {
XWPFTableCell cell = row.getCell(j);
cell.removeParagraph(0);
cell.setText(map.get("${B" + startIndex++ + "}"));
//表格样式一致-->没有此段表格会默认左对齐
//有此段会使表格格式一致
CTTc cttc = cell.getCTTc();
CTTcPr ctPr = cttc.addNewTcPr();
ctPr.addNewVAlign().setVal(STVerticalJc.CENTER);
cttc.getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);
}
table.addRow(row,newRowIndex++);
}
//将其他变量赋值
for (int i = 0; i < table.getNumberOfRows(); i++) {
XWPFTableRow row = table.getRow(i);
List<XWPFTableCell> tableCells = row.getTableCells();
for (XWPFTableCell tableCell : tableCells) {
for (Map.Entry<String, String> entry : map.entrySet()) {
if (tableCell.getText().equals(entry.getKey())) {
tableCell.removeParagraph(0);
tableCell.setText(entry.getValue());
//表格样式一致-->没有此段表格会默认左对齐
//有此段会使表格格式一致
CTTc cttc = cell.getCTTc();
CTTcPr ctPr = cttc.addNewTcPr();
ctPr.addNewVAlign().setVal(STVerticalJc.CENTER);
cttc.getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);
}
}
}
}
//写入另一个word文档中
File docx = new File("D:\\word\\write.docx");
FileOutputStream out = new FileOutputStream(docx);
document.write(out);
//关闭流
out.close();
inputStream.close();
}
生成word效果如下图
总结
动态生成的那几行表格 样式有点变了,暂未解决