package com.product.print.service;
|
|
|
import cn.hutool.core.collection.CollectionUtil;
|
import com.deepoove.poi.NiceXWPFDocument;
|
import com.deepoove.poi.XWPFTemplate;
|
import com.deepoove.poi.policy.RenderPolicy;
|
import com.deepoove.poi.template.ElementTemplate;
|
import com.deepoove.poi.template.run.RunTemplate;
|
import com.product.common.lang.StringUtils;
|
import org.apache.poi.xwpf.usermodel.*;
|
import org.apache.xmlbeans.XmlCursor;
|
import org.apache.xmlbeans.XmlObject;
|
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
|
|
import java.util.Collections;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.regex.Matcher;
|
import java.util.regex.Pattern;
|
|
/**
|
* @author cheng
|
* @desc poi-tl 自定义字表渲染
|
* @date 2022年5月6日17:04:31
|
*/
|
public class HackLoopTableRenderPolicy implements RenderPolicy {
|
|
@Override
|
public void render(ElementTemplate eleTemplate, Object data, XWPFTemplate template) {
|
NiceXWPFDocument doc = template.getXWPFDocument();
|
RunTemplate runTemplate = (RunTemplate) eleTemplate;
|
XWPFRun run = runTemplate.getRun();
|
String text = run.getText(0);
|
try {
|
// w:tbl-w:tr-w:tc-w:p-w:tr
|
XmlCursor newCursor = ((XWPFParagraph) run.getParent()).getCTP().newCursor();
|
newCursor.toParent();
|
newCursor.toParent();
|
newCursor.toParent();
|
XmlObject object = newCursor.getObject();
|
XWPFTable table = doc.getAllTable((CTTbl) object);
|
render(text, table, (List<Map<String, String>>) data, template, text.substring(2).substring(0, text.length() - 4));
|
run.setText("", 0);
|
} catch (Exception e) {
|
logger.error("dynamic table error:" + e.getMessage(), e);
|
}
|
}
|
|
private void render(String text, XWPFTable table, List<Map<String, String>> subListData, XWPFTemplate template, String subTableName) {
|
List<XWPFTableRow> rows = table.getRows();
|
if (rows != null && rows.size() > 0) {
|
//表格渲染开始行(子表字段表达式所在行)
|
int tableRowIndex = -1;
|
for (int i = 0; i < rows.size(); i++) {
|
XWPFTableCell cell = rows.get(i).getCell(0);
|
if (cell != null && cell.getText().indexOf(text) != -1) {
|
tableRowIndex = i + 1;
|
break;
|
}
|
}
|
if (tableRowIndex > -1) {
|
XWPFTableRow xwpfTableRow = rows.get(tableRowIndex);
|
List<XWPFTableCell> cells = xwpfTableRow.getTableCells();
|
if (cells != null && cells.size() > 0) {
|
String[] keys = new String[cells.size()];
|
for (int i = 0; i < cells.size(); i++) {
|
XWPFTableCell xwpfTableCell = cells.get(i);
|
String expression = xwpfTableCell.getText();
|
if (!StringUtils.isEmpty(expression.trim())) {
|
expression = expression.trim();
|
keys[i] = parseString(expression, subTableName);
|
}
|
}
|
table.removeRow(tableRowIndex);
|
if (CollectionUtil.isEmpty(subListData)) {
|
return;
|
}
|
for (int i = 0; i < subListData.size(); i++) {
|
table.insertNewTableRow(tableRowIndex);
|
XWPFTableRow currentRow = table.getRow(tableRowIndex);
|
int cellCount = cells.size() < keys.length ? keys.length : cells.size();
|
for (int j = 0; j < cellCount; j++) {
|
currentRow.addNewTableCell();
|
}
|
setValues(table.getRow(tableRowIndex).getTableCells(), keys, subListData.get(i));
|
tableRowIndex++;
|
}
|
}
|
}
|
}
|
}
|
|
private void setValues(List<XWPFTableCell> cells, String[] keys, Map subData) {
|
if (cells != null && keys != null && cells.size() > 0 && subData != null && subData.size() > 0) {
|
for (int i = 0; i < cells.size(); i++) {
|
String key = keys[i];
|
if (StringUtils.isEmpty(key)) {
|
continue;
|
}
|
Object val = subData.get(key) ;
|
if (val == null) {
|
val = "";
|
}
|
cells.get(i).setText(val+"");
|
}
|
}
|
|
}
|
|
|
/**
|
* 解析字符串
|
*/
|
public static String parseString(String text, String table) {
|
Matcher matcher = Pattern.compile("(\\$\\{)(" + makeQueryStringAllRegExp(table) + "\\.+)([\\w]+)(\\})").matcher(text);
|
StringBuilder sb = new StringBuilder();
|
while (matcher.find()) {
|
System.out.println(matcher.group());
|
sb.append(matcher.group(3));
|
}
|
return sb.length() > 0 ? sb.toString() : null;
|
}
|
|
/**
|
* 转义正则特殊字符 ($()*+.[]?\^{}
|
* \\需要第一个替换,否则replace方法替换时会有逻辑bug
|
*/
|
public static String makeQueryStringAllRegExp(String str) {
|
if (StringUtils.isBlank(str)) {
|
return str;
|
}
|
|
return str.replace("\\", "\\\\").replace("*", "\\*")
|
.replace("+", "\\+").replace("|", "\\|")
|
.replace("{", "\\{").replace("}", "\\}")
|
.replace("(", "\\(").replace(")", "\\)")
|
.replace("^", "\\^").replace("$", "\\$")
|
.replace("[", "\\[").replace("]", "\\]")
|
.replace("?", "\\?").replace(",", "\\,")
|
.replace(".", "\\.").replace("&", "\\&");
|
}
|
|
|
}
|