From fd7bc95a3c91fb7d90a921b0ff762fa6095fabd1 Mon Sep 17 00:00:00 2001 From: zss <zss@example.com> Date: 星期四, 06 三月 2025 17:21:00 +0800 Subject: [PATCH] Merge branch 'dev' into dev_zj --- inspect-server/src/main/java/com/ruoyi/inspect/util/HackLoopTableRenderPolicy.java | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 154 insertions(+), 0 deletions(-) diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/util/HackLoopTableRenderPolicy.java b/inspect-server/src/main/java/com/ruoyi/inspect/util/HackLoopTableRenderPolicy.java new file mode 100644 index 0000000..9343a26 --- /dev/null +++ b/inspect-server/src/main/java/com/ruoyi/inspect/util/HackLoopTableRenderPolicy.java @@ -0,0 +1,154 @@ +/* + * Copyright 2014-2020 Sayi + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.ruoyi.inspect.util; + +import com.deepoove.poi.XWPFTemplate; +import com.deepoove.poi.exception.RenderException; +import com.deepoove.poi.policy.RenderPolicy; +import com.deepoove.poi.render.compute.RenderDataCompute; +import com.deepoove.poi.render.processor.DocumentProcessor; +import com.deepoove.poi.resolver.TemplateResolver; +import com.deepoove.poi.template.ElementTemplate; +import com.deepoove.poi.template.MetaTemplate; +import com.deepoove.poi.template.run.RunTemplate; +import com.deepoove.poi.util.ReflectionUtils; +import com.deepoove.poi.util.TableTools; +import org.apache.poi.xwpf.usermodel.*; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlObject; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge; + +import java.util.Iterator; +import java.util.List; + +/** + * Hack for loop table row + * + * @author Sayi + * + */ +public class HackLoopTableRenderPolicy implements RenderPolicy { + + private String prefix; + private String suffix; + private boolean onSameLine; + + public HackLoopTableRenderPolicy() { + this(false); + } + + public HackLoopTableRenderPolicy(boolean onSameLine) { + this("[", "]", onSameLine); + } + + public HackLoopTableRenderPolicy(String prefix, String suffix) { + this(prefix, suffix, false); + } + + public HackLoopTableRenderPolicy(String prefix, String suffix, boolean onSameLine) { + this.prefix = prefix; + this.suffix = suffix; + this.onSameLine = onSameLine; + } + + @Override + public void render(ElementTemplate eleTemplate, Object data, XWPFTemplate template) { + 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; + while (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(iterator.next()); + List<XWPFTableCell> cells = nextRow.getTableCells(); + cells.forEach(cell -> { + List<MetaTemplate> templates = resolver.resolveBodyElements(cell.getBodyElements()); + new DocumentProcessor(template, resolver, dataCompute).process(templates); + }); + } + } + + 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); + } + +} -- Gitblit v1.9.3