Word表格模板
导出word表格图例
解决方案:重写LoopRowTableRenderPolicy插件。
public class MyTableRenderPolicy implements RenderPolicy {
private String prefix;
private String suffix;
private boolean onSameLine;
public MyTableRenderPolicy() {
this(false);
}
public MyTableRenderPolicy(boolean onSameLine) {
this("[", "]", onSameLine);
}
public MyTableRenderPolicy(String prefix, String suffix) {
this(prefix, suffix, false);
}
public MyTableRenderPolicy(String prefix, String suffix, boolean onSameLine) {
this.prefix = prefix;
this.suffix = suffix;
this.onSameLine = onSameLine;
}
@Override
public void render(ElementTemplate eleTemplate, Object data_array, XWPFTemplate template) {
Object data=null;
Map data_array_map= (Map) data_array;
data=data_array_map.get("data_list");
List<Map> row_map_list= (List<Map>) data_array_map.get("row_map_list");
RunTemplate runTemplate = (RunTemplate) eleTemplate;
XWPFRun run = runTemplate.getRun();
try {
if (!TableTools.isInsideTable(run)) {
throw new IllegalStateException(
"The template tag " + runTemplate.getSource() + " must be inside a table");
}
XWPFTableCell tagCell = (XWPFTableCell) ((XWPFParagraph) run.getParent()).getBody();
XWPFTable table = tagCell.getTableRow().getTable();
run.setText("", 0);
int templateRowIndex = getTemplateRowIndex(tagCell);
if (null != data && data instanceof Iterable) {
Iterator<?> iterator = ((Iterable<?>) data).iterator();
XWPFTableRow templateRow = table.getRow(templateRowIndex);
int insertPosition = templateRowIndex;
TemplateResolver resolver = new TemplateResolver(template.getConfig().copy(prefix, suffix));
boolean firstFlag = true;
int index = 0;
boolean hasNext = iterator.hasNext();
while (hasNext) {
Object root = iterator.next();
hasNext = iterator.hasNext();
insertPosition = templateRowIndex++;
XWPFTableRow nextRow = table.insertNewTableRow(insertPosition);
setTableRow(table, templateRow, insertPosition);
// double set row
XmlCursor newCursor = templateRow.getCtRow().newCursor();
newCursor.toPrevSibling();
XmlObject object = newCursor.getObject();
nextRow = new XWPFTableRow((CTRow) object, table);
if (!firstFlag) {
// update VMerge cells for non-first row
List<XWPFTableCell> tableCells = nextRow.getTableCells();
for (XWPFTableCell cell : tableCells) {
CTTcPr tcPr = TableTools.getTcPr(cell);
CTVMerge vMerge = tcPr.getVMerge();
if (null == vMerge) continue;
if (STMerge.RESTART == vMerge.getVal()) {
vMerge.setVal(STMerge.CONTINUE);
}
}
} else {
firstFlag = false;
}
setTableRow(table, nextRow, insertPosition);
RenderDataCompute dataCompute = template.getConfig()
.getRenderDataComputeFactory()
.newCompute(EnvModel.of(root, EnvIterator.makeEnv(index++, hasNext)));
List<XWPFTableCell> cells = nextRow.getTableCells();
cells.forEach(cell -> {
List<MetaTemplate> templates = resolver.resolveBodyElements(cell.getBodyElements());
new DocumentProcessor(template, resolver, dataCompute).process(templates);
});
}
for(Map row_map:row_map_list){
//合并开头得单位
TableTools.mergeCellsVertically(table, 0, (int)row_map.get("fromrow"), (int)row_map.get("torow"));
}
}
table.removeRow(templateRowIndex);
afterloop(table, data);
} catch (Exception e) {
throw new RenderException("HackLoopTable for " + eleTemplate + "error: " + e.getMessage(), e);
}
}
private int getTemplateRowIndex(XWPFTableCell tagCell) {
XWPFTableRow tagRow = tagCell.getTableRow();
return onSameLine ? getRowIndex(tagRow) : (getRowIndex(tagRow) + 1);
}
protected void afterloop(XWPFTable table, Object data) {
}
@SuppressWarnings("unchecked")
private void setTableRow(XWPFTable table, XWPFTableRow templateRow, int pos) {
List<XWPFTableRow> rows = (List<XWPFTableRow>) ReflectionUtils.getValue("tableRows", table);
rows.set(pos, templateRow);
table.getCTTbl().setTrArray(pos, templateRow.getCtRow());
}
private int getRowIndex(XWPFTableRow row) {
List<XWPFTableRow> rows = row.getTable().getRows();
return rows.indexOf(row);
}
}
public class WordPoiTest {
public static void main(String[]args) throws IOException {
WordPoiTest wordPoiTest=new WordPoiTest();
wordPoiTest.test();
}
public void test() throws IOException {
LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
Configure config = Configure.builder()
.bind("tables_2", new MyTableRenderPolicy()).build();
XWPFTemplate template = XWPFTemplate.compile("C:\\Users\\QYF\\Desktop\\template.docx",config);
Map map=new HashMap();
map.put("title", "Hi, poi-tl Word模板引擎");
List listList=new ArrayList<>();
Tables tables1=new Tables("type1",1,"占山占山占山占山占山占山占山占占山占山占山占山占山山占山占山","123456");
Tables tables2=new Tables("type1",2,"占山","123456");
Tables tables3=new Tables("type1",3,"占山","123456");
listList.add(tables1);
listList.add(tables2);
listList.add(tables3);
Tables tables4=new Tables("type2",4,"占山","123456");
Tables tables5=new Tables("type2",1,"占山占山占山占山占山占山占山占占山占山占山占山占山山占山占山","123456");
Tables tables6=new Tables("type2",2,"占山","123456");
listList.add(tables4);
listList.add(tables5);
listList.add(tables6);
Tables tables7=new Tables("type3",3,"占山","123456");
listList.add(tables7);
Map data_array=new HashMap();
data_array.put("data_list",listList);
List<Map> row_map_list=new ArrayList<>();
Map row_map=new HashMap();
row_map.put("fromrow",1);
row_map.put("torow",3);
row_map_list.add(row_map);
data_array.put("row_map_list",row_map_list);
map.put("tables_2",data_array);
template.render(map);
template.writeAndClose(new FileOutputStream("C:\\Users\\QYF\\Desktop\\output.docx"));
}
}
class Tables{
private String type;
private int num;
private String name;
private String product_num;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getProduct_num() {
return product_num;
}
public void setProduct_num(String product_num) {
this.product_num = product_num;
}
public Tables(String type, int num, String name, String product_num) {
this.type = type;
this.num = num;
this.name = name;
this.product_num = product_num;
}
public Tables() {
}
}
加载插件时,加载自定义的插件
Configure config = Configure.builder()
.bind("tables_2", new MyTableRenderPolicy()).build();