通过POI操作word文档,使用分段实现替换文本、替换表格。实现模板引擎,自定义报表配置
先认识一些基础操作
//获取WORD操作对象
XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(intputUrl));
//获取段落集合
List<XWPFParagraph> paragraphs = document.getParagraphs();
//分段 WORD中可识别的 ‘${}’、‘#{}’
List<XWPFRun> runs = paragraph.getRuns();
//获取表格对象集合
List<XWPFTable> tables = document.getTables();
//获取表格 I为循环值
XWPFTable table = tables.get(i);
//获取表格行 headerIndex表头的行索引,从0开始
XWPFTableRow copyRow = table.getRow(headerIndex);
//插入行
XWPFTableRow targetRow = table.insertNewTableRow(headerIndex + 1 + i);
//获取列
List<XWPFTableCell> cellList = copyRow.getTableCells();
//设置列属性
cellList.get(i).getCTTc().setTcPr();
//获取列属性
cellList.get(i).getCTTc().getTcPr()
替换、删除 段落文本
删除段落
document.removeBodyElement(document.getPosOfParagraph(paragraph));
/**
* 替换段落文本
*
* @param document docx解析对象
* @param textMap 需要替换的信息集合
*/
public static void changeText(XWPFDocument document, Map<String, Object> textMap) {
//获取段落集合
int pNumber = document.getParagraphs().size() -1;
while (pNumber >= 0) {
XWPFParagraph paragraph = document.getParagraphs().get(pNumber);
String text = paragraph.getText();
if (checkText(text)) {
List<XWPFRun> runs = paragraph.getRuns();
List<XWPFRun> stringResult = getStringResult(runs);
for (XWPFRun run : stringResult) {
//替换模板原来位置
run.setText(changeValue(run.toString(), textMap), 0);
}
}else if (checkTextW(text)){
//业务需求-删除段落
document.removeBodyElement(document.getPosOfParagraph(paragraph));
}
pNumber--;
}
}
/**
* 匹配传入信息集合与模板
*
* @param value 模板需要替换的区域
* @param textMap 传入信息集合
* @return 模板需要替换区域信息集合对应值
*/
public static String changeValue(String value, Map<String, Object> textMap) {
Set<Map.Entry<String, Object>> entries = textMap.entrySet();
for (Map.Entry<String, Object> textSet : entries) {
//匹配模板与替换值 格式${key}
String key =textSet.getKey();
if (value.contains("$")){
key = "${" + textSet.getKey() + "}";
}
if (value.indexOf(key) != -1) {
value = value.replace(key, textSet.getValue().toString());
}
}
return value;
}
替换表格
/**
* 替换表格对象方法
*
* @param document docx解析对象
* @param tableList 需要插入的表格信息集合
*/
public static void changeTable(XWPFDocument document, List<List<String[]>> tableList) {
//获取表格对象集合
List<XWPFTable> tables = document.getTables();
for (int i = 0; i < tableList.size(); i++) {
List<String[]> Result = tableList.get(i);
//只处理行数大于等于2的表格,且不循环表头
XWPFTable table = tables.get(i);
if (table.getRows().size() > 0) {
copyHeaderInsertText( table, Result, 0);
}
}
}
/**
* 复制表头 插入行数据,这里样式和表头一样
*
* @param table
* @param tableList 需要插入数据集合
* @param headerIndex 表头的行索引,从0开始
*/
public static void copyHeaderInsertText(XWPFTable table, List<String[]> tableList, int headerIndex) {
if (null == tableList) {
return;
}
CTTblBorders borders = table.getCTTbl().getTblPr().addNewTblBorders();
CTBorder hBorder = borders.addNewInsideH();
hBorder.setVal(STBorder.Enum.forString("dashed")); // 线条类型
hBorder.setSz(new BigInteger("1")); // 线条大小
hBorder.setColor("000000"); // 设置颜色
CTBorder vBorder = borders.addNewInsideV();
vBorder.setVal(STBorder.Enum.forString("dashed"));
vBorder.setSz(new BigInteger("1"));
vBorder.setColor("000000");
CTBorder lBorder = borders.addNewLeft();
lBorder.setVal(STBorder.Enum.forString("dashed"));
lBorder.setSz(new BigInteger("1"));
lBorder.setColor("000000");
CTBorder rBorder = borders.addNewRight();
rBorder.setVal(STBorder.Enum.forString("dashed"));
rBorder.setSz(new BigInteger("1"));
rBorder.setColor("000000");
CTBorder tBorder = borders.addNewTop();
tBorder.setVal(STBorder.Enum.forString("dashed"));
tBorder.setSz(new BigInteger("1"));
tBorder.setColor("000000");
CTBorder bBorder = borders.addNewBottom();
bBorder.setVal(STBorder.Enum.forString("dashed"));
bBorder.setSz(new BigInteger("1"));
bBorder.setColor("000000");
CTTbl ttbl = table.getCTTbl();
CTTblPr tblPr = ttbl.getTblPr() == null ? ttbl.addNewTblPr() : ttbl.getTblPr();
CTTblWidth tblWidth = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW();
CTJc cTJc=tblPr.addNewJc();
cTJc.setVal(STJc.Enum.forString("center"));
tblWidth.setW(new BigInteger("80000"));
// tblWidth.setType(STTblWidth.DXA);
XWPFTableRow copyRow = table.getRow(headerIndex);
List<XWPFTableCell> cellList = copyRow.getTableCells();
if (null == cellList) {
return;
}
//遍历要添加的数据的list
for (int i = 0; i < tableList.size(); i++) {
//插入一行
XWPFTableRow targetRow = table.insertNewTableRow(headerIndex + 1 + i);
String[] strings = tableList.get(i);
for (int j = 0; j < strings.length; j++) {
XWPFTableCell sourceCell = cellList.get(j);
//插入一个单元格
XWPFTableCell targetCell = targetRow.addNewTableCell();
//复制列属性
// targetCell.getCTTc().setTcPr(sourceCell.getCTTc().getTcPr());
// 居中
XWPFParagraph paragraph = targetCell.addParagraph();
paragraph.setSpacingBetween(1.5);
paragraph.setAlignment(ParagraphAlignment.CENTER);
targetCell.removeParagraph(0);
CTTc cttc = targetCell.getCTTc();
CTTcPr ctPr = cttc.addNewTcPr();
ctPr.addNewVAlign().setVal(STVerticalJc.CENTER);
if (Func.isEmpty(strings[j])){
targetCell.setText("");
}else{
targetCell.setText(strings[j].trim());
}
}
}
}
要注意一个小问题:替换文本时使用的${}占位符,尽量在文本编辑器中编辑好,粘贴到word中,避免识别不到