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