瀏覽代碼

1.成本监审提取资料登记表模板下载

赵越越 4 周之前
父節點
當前提交
636fe3c072

+ 4 - 0
assistMg/src/main/java/com/hotent/project/manager/CostProjectTaskEvidenceManager.java

@@ -3,6 +3,8 @@ package com.hotent.project.manager;
 import com.hotent.project.model.CostProjectTaskEvidence;
 import com.hotent.base.manager.BaseManager;
 
+import java.util.List;
+
 /**
  * 子任务资料登记表 服务类
  *
@@ -18,4 +20,6 @@ public interface CostProjectTaskEvidenceManager extends BaseManager<CostProjectT
      * @return
      */
     void createOrUpdate(CostProjectTaskEvidence costProjectTaskEvidence);
+
+    List<CostProjectTaskEvidence> findEvidenceListByTaskIds(String projectId, String enterpriseId);
 }

+ 2 - 0
assistMg/src/main/java/com/hotent/project/manager/CostProjectTaskManager.java

@@ -42,4 +42,6 @@ public interface CostProjectTaskManager extends BaseManager<CostProjectTask> {
 	List<CostNotice> getDoMsgList();
 
 	IPage<CostProjectTask> pageListForReviewTaskChild(CostTaskReviewPageReq req);
+
+    List<CostProjectTask> findTaskByProjectId(String projectId, String enterpriseId);
 }

+ 27 - 2
assistMg/src/main/java/com/hotent/project/manager/impl/CostProjectDocumentManagerImpl.java

@@ -20,12 +20,14 @@ import com.hotent.config.EipConfig;
 import com.hotent.constant.BaseConstant;
 import com.hotent.project.manager.CostProjectApprovalManager;
 import com.hotent.project.manager.CostProjectDocumentFileManager;
+import com.hotent.project.manager.CostProjectTaskEvidenceManager;
 import com.hotent.project.model.CostProjectApproval;
 import com.hotent.project.model.CostProjectDocument;
 import com.hotent.project.dao.CostProjectDocumentDao;
 import com.hotent.project.manager.CostProjectDocumentManager;
 import com.hotent.base.manager.impl.BaseManagerImpl;
 import com.hotent.project.model.CostProjectDocumentFile;
+import com.hotent.project.model.CostProjectTaskEvidence;
 import com.hotent.project.req.CostProjectDocumentPageReq;
 import com.hotent.project.req.CostProjectDocumentReq;
 import com.hotent.project.resp.CostProjectDocumentResp;
@@ -53,6 +55,8 @@ import java.util.stream.Collectors;
 
 import com.hotent.util.FileUploadUtil;
 
+import static org.apache.tools.ant.util.DateUtils.ISO8601_DATE_PATTERN;
+
 
 /**
  * 监审项目文书表 服务实现类
@@ -77,6 +81,9 @@ public class CostProjectDocumentManagerImpl extends BaseManagerImpl<CostProjectD
     private CostDocumentTemplateFileManager costDocumentTemplateFileManager;
 
     @Autowired
+    private CostProjectTaskEvidenceManager costProjectTaskEvidenceManager;
+
+    @Autowired
     private CostDocumentWhManager costDocumentWhManager;
 
     @Autowired
@@ -543,10 +550,28 @@ public class CostProjectDocumentManagerImpl extends BaseManagerImpl<CostProjectD
             //SimpleStylePreserver.smartReplaceKeepStyle(document,map);
             //BestPracticeReplacer.replaceTextBestPractice(document,map);
             //BestPracticeReplacer.applySmartStyles(document);
-            if (!costProjectDocument.getDocumentAlias().equals("cbjstqzldjb")) {
+            if (!costProjectDocument.getDocumentAlias().equals("cbjstqzldjb2")) {
                 SmartTemplateWriter.writeToTemplate(document,map);
             }else {
-
+               List<CostProjectTaskEvidence> costProjectTaskEvidences= costProjectTaskEvidenceManager.findEvidenceListByTaskIds(costProjectDocument.getProjectId(),costProjectDocument.getEnterpriseId());
+                if (!costProjectTaskEvidences.isEmpty()) {
+                    List<CompleteTemplateProcessor.TableRowData> mapList = costProjectTaskEvidences.stream().map(c -> {
+                        CompleteTemplateProcessor.TableRowData tableRowData = new CompleteTemplateProcessor.TableRowData();
+                        /*Map<String, Object> hashMap = new HashMap<>();
+                        hashMap.put("pageCount",c.getPageCount());
+                        hashMap.put("remark",c.getRemark());
+                        hashMap.put("documentName",c.getMaterialName());*/
+                        tableRowData.setDocumentName(c.getMaterialName());
+                        tableRowData.setRemark(c.getRemark());
+                        tableRowData.setPageCount(c.getPageCount());
+                        return tableRowData;
+                    }).collect(Collectors.toList());
+                    //int sum = costProjectTaskEvidences.stream().mapToInt(CostProjectTaskEvidence::getPageCount).sum();
+                    //SimpleTableFiller.fillTableSimple(document,null,mapList,costProjectTaskEvidences.size(),sum,DateUtils.format(new Date(),ISO8601_DATE_PATTERN));
+                    AuditedUnit auditedUnit = auditedUnitManager.get(costProjectDocument.getEnterpriseId());
+
+                    CompleteTemplateProcessor.processTemplateComplete(document,auditedUnit.getUnitName(),mapList,DateUtils.format(new Date(),ISO8601_DATE_PATTERN));
+                }
             }
             document.write(fos);
         } catch (IOException e) {

+ 22 - 0
assistMg/src/main/java/com/hotent/project/manager/impl/CostProjectTaskEvidenceManagerImpl.java

@@ -1,12 +1,20 @@
 package com.hotent.project.manager.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.hotent.project.manager.CostProjectTaskManager;
+import com.hotent.project.model.CostProjectTask;
 import com.hotent.project.model.CostProjectTaskEvidence;
 import com.hotent.project.dao.CostProjectTaskEvidenceDao;
 import com.hotent.project.manager.CostProjectTaskEvidenceManager;
 import com.hotent.base.manager.impl.BaseManagerImpl;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
 /**
  * 子任务资料登记表 服务实现类
  *
@@ -17,6 +25,8 @@ import org.springframework.transaction.annotation.Transactional;
 @Service
 public class CostProjectTaskEvidenceManagerImpl extends BaseManagerImpl<CostProjectTaskEvidenceDao, CostProjectTaskEvidence> implements CostProjectTaskEvidenceManager {
 
+    @Autowired
+    private CostProjectTaskManager costProjectTaskManager;
 
 
     @Override
@@ -25,4 +35,16 @@ public class CostProjectTaskEvidenceManagerImpl extends BaseManagerImpl<CostProj
         //新建或更新
         this.saveOrUpdate(costProjectTaskEvidence);
     }
+
+    @Override
+    public List<CostProjectTaskEvidence> findEvidenceListByTaskIds(String projectId, String enterpriseId) {
+         List<CostProjectTask> tasks= costProjectTaskManager.findTaskByProjectId(projectId,enterpriseId);
+        QueryWrapper<CostProjectTaskEvidence> wrapper = new QueryWrapper<>();
+        List<String> collect = tasks.stream().map(CostProjectTask::getId).collect(Collectors.toList());
+        if (!collect.isEmpty()) {
+            wrapper.in("task_id",collect);
+            return this.list(wrapper);
+        }
+        return Collections.emptyList();
+    }
 }

+ 9 - 0
assistMg/src/main/java/com/hotent/project/manager/impl/CostProjectTaskManagerImpl.java

@@ -1,6 +1,7 @@
 package com.hotent.project.manager.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -1146,6 +1147,14 @@ public class CostProjectTaskManagerImpl extends BaseManagerImpl<CostProjectTaskD
         return result;
     }
 
+    @Override
+    public List<CostProjectTask> findTaskByProjectId(String projectId, String enterpriseId) {
+        QueryWrapper<CostProjectTask> wrapper = new QueryWrapper<>();
+        wrapper.eq("project_id",projectId);
+        wrapper.eq("audited_unit_id",enterpriseId);
+        return this.list(wrapper);
+    }
+
     private List<String> getAllChildCatalogIds(String catalogId) {
         List<String> result = new ArrayList<>();
         result.add(catalogId);

+ 387 - 0
assistMg/src/main/java/com/hotent/util/wordexcelutils/CompleteTemplateProcessor.java

@@ -0,0 +1,387 @@
+package com.hotent.util.wordexcelutils;/**
+ * @program: cbjs-mvue-master
+ * @description:
+ * @author: zhao yue yue
+ * @create: 2025-11-27 15:34
+ */
+
+import com.hotent.base.util.StringUtil;
+import lombok.Data;
+import lombok.Getter;
+import org.apache.poi.xwpf.usermodel.*;
+import java.util.*;
+import java.io.*;
+
+/**
+ *@author: zhao yue yue
+ *@create: 2025-11-27 15:34
+ */
+public class CompleteTemplateProcessor {
+
+    /**
+     * 完整处理模板:替换占位符 + 填充表格数据
+     */
+    public static void processTemplateComplete(XWPFDocument document,
+                                               String organizationName,
+                                               List<TableRowData> rowDataList,
+                                               String generateDate) {
+
+        // 1. 计算汇总信息
+        int totalPages = calculateTotalPages(rowDataList);
+        int totalDocuments = rowDataList.size();
+
+        System.out.println("开始处理模板...");
+        System.out.println("单位名称: " + organizationName);
+        System.out.println("数据行数: " + totalDocuments);
+        System.out.println("总页数: " + totalPages);
+        System.out.println("生成日期: " + generateDate);
+
+        // 2. 替换文档中的占位符
+        //replaceDocumentPlaceholders(document, organizationName, totalDocuments, totalPages, generateDate);
+        // 替换映射
+        Map<String, String> replacements = new HashMap<>();
+        replacements.put("{价格主管部门或成本监审机构}", organizationName);
+        replacements.put("{材料件数}", String.valueOf(totalDocuments));
+        replacements.put("{材料页数}", String.valueOf(totalPages));
+        replacements.put("{登记表生成日期}", generateDate);
+        replacements.put("{序号}", "1");
+        replacements.put("{资料名称}", rowDataList.get(0).getDocumentName());
+        replacements.put("{页数}", String.valueOf(rowDataList.get(0).getPageCount()));
+        replacements.put("{备注}", rowDataList.get(0).getRemark());
+        SmartTemplateWriter.writeToTemplate(document,replacements);
+
+        // 3. 处理表格数据
+        processTableData(document, rowDataList);
+
+        System.out.println("模板处理完成!");
+    }
+
+    /**
+     * 计算总页数
+     */
+    private static int calculateTotalPages(List<TableRowData> rowDataList) {
+        return rowDataList.stream().mapToInt(TableRowData::getPageCount).sum();
+    }
+
+    /**
+     * 替换文档中的占位符
+     */
+    private static void replaceDocumentPlaceholders(XWPFDocument document,
+                                                    String organizationName,
+                                                    int totalDocuments,
+                                                    int totalPages,
+                                                    String generateDate) {
+
+        // 替换映射
+        Map<String, String> replacements = new HashMap<>();
+        replacements.put("{价格主管部门或成本监审机构}", organizationName);
+        replacements.put("{材料件数}", String.valueOf(totalDocuments));
+        replacements.put("{材料页数}", String.valueOf(totalPages));
+        replacements.put("{登记表生成日期}", generateDate);
+
+        // 在文档中查找并替换
+        for (Map.Entry<String, String> entry : replacements.entrySet()) {
+            boolean found = replaceTextInDocument(document, entry.getKey(), entry.getValue());
+            if (!found) {
+                System.out.println("警告: 未找到占位符 " + entry.getKey());
+            } else {
+                System.out.println("成功替换: " + entry.getKey() + " → " + entry.getValue());
+            }
+        }
+    }
+
+    /**
+     * 处理表格数据
+     */
+    private static void processTableData(XWPFDocument document, List<TableRowData> rowDataList) {
+        List<XWPFTable> tables = document.getTables();
+        if (tables.isEmpty()) {
+            System.err.println("错误: 未找到表格");
+            return;
+        }
+
+        XWPFTable table = tables.get(0);
+        System.out.println("找到表格,行数: " + table.getRows().size());
+
+        // 找到模板行(包含占位符的行)
+        //int templateRowIndex = findTemplateRow(table);
+       /* if (templateRowIndex == -1) {
+            System.err.println("错误: 未找到包含占位符的模板行");
+            return;
+        }*/
+
+        System.out.println("模板行索引: " + 1);
+
+        // 处理表格数据
+        processTableRows(table, 1, rowDataList);
+    }
+
+    /**
+     * 找到包含占位符的模板行
+     */
+    private static int findTemplateRow(XWPFTable table) {
+        for (int i = 0; i < table.getRows().size(); i++) {
+            XWPFTableRow row = table.getRows().get(i);
+            if (containsTablePlaceholders(row)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * 检查行是否包含表格占位符
+     */
+    private static boolean containsTablePlaceholders(XWPFTableRow row) {
+        String[] placeholders = {"{序号}", "{资料名称}", "{页数}", "{备注}"};
+        String rowText = getRowText(row);
+
+        if (rowText == null) return false;
+
+        for (String placeholder : placeholders) {
+            if (rowText.contains(placeholder)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 处理表格行数据
+     */
+    private static void processTableRows(XWPFTable table, int templateRowIndex, List<TableRowData> rowDataList) {
+        XWPFTableRow templateRow = table.getRows().get(templateRowIndex);
+
+        // 1. 首先替换模板行(第一行数据)
+       /* if (rowDataList.size() > 0) {
+            replaceTemplateRow(templateRow, rowDataList.get(0), 1);
+            System.out.println("替换模板行完成");
+        }*/
+
+        // 2. 添加额外的数据行
+        for (int i = 1; i < rowDataList.size(); i++) {
+            addDataRow(table, templateRow, rowDataList.get(i), i + 1, templateRowIndex + i);
+            System.out.println("添加数据行: " + (i + 1));
+        }
+
+        // 3. 清理多余的空行(保留汇总行)
+        cleanupEmptyRows(table, templateRowIndex + rowDataList.size());
+
+        System.out.println("表格处理完成,最终行数: " + table.getRows().size());
+    }
+
+    /**
+     * 替换模板行
+     */
+    private static void replaceTemplateRow(XWPFTableRow row, TableRowData data, int sequence) {
+        List<XWPFTableCell> cells = row.getTableCells();
+        if (cells.size() < 4) {
+            System.err.println("错误: 表格列数不足");
+            return;
+        }
+
+        // 替换占位符
+        //replaceInCell(cells.get(0), "[{序号}]", String.valueOf(sequence));
+       // replaceInCell(cells.get(1), "[{资料名称}]", data.getDocumentName());
+       // replaceInCell(cells.get(2), "[{页数}]", data.getPageCount() > 0 ? String.valueOf(data.getPageCount()) : "");
+       // replaceInCell(cells.get(3), "[{备注}]", data.getRemark() != null ? data.getRemark() : "");
+    }
+
+    /**
+     * 添加数据行
+     */
+    private static void addDataRow(XWPFTable table, XWPFTableRow templateRow, TableRowData data, int sequence, int insertIndex) {
+        // 创建新行
+        XWPFTableRow newRow = table.insertNewTableRow(insertIndex);
+
+        // 复制模板行的单元格结构
+        for (int i = 0; i < templateRow.getTableCells().size(); i++) {
+            XWPFTableCell newCell = newRow.addNewTableCell();
+            // 复制单元格样式(简化)
+            copyCellStyle(templateRow.getTableCells().get(i), newCell);
+        }
+
+        // 填充数据
+        List<XWPFTableCell> cells = newRow.getTableCells();
+        setCellText(cells.get(0), String.valueOf(sequence));
+        setCellText(cells.get(1), data.getDocumentName());
+        setCellText(cells.get(2), data.getPageCount() > 0 ? String.valueOf(data.getPageCount()) : "");
+        setCellText(cells.get(3), data.getRemark() != null ? data.getRemark() : "");
+    }
+
+    /**
+     * 清理多余的空行
+     */
+    private static void cleanupEmptyRows(XWPFTable table, int startIndex) {
+        // 找到汇总行
+        int summaryRowIndex = findSummaryRow(table);
+        if (summaryRowIndex == -1) return;
+
+        // 清理汇总行之前的空行
+        for (int i = summaryRowIndex - 1; i >= startIndex; i--) {
+            if (i < table.getRows().size() && isRowEmpty(table.getRows().get(i))) {
+                table.removeRow(i);
+                System.out.println("清理空行: " + i);
+            }
+        }
+    }
+
+    /**
+     * 找到汇总行
+     */
+    private static int findSummaryRow(XWPFTable table) {
+        for (int i = 0; i < table.getRows().size(); i++) {
+            XWPFTableRow row = table.getRows().get(i);
+            String rowText = getRowText(row);
+            if (rowText != null && rowText.contains("以上材料共")) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    // ========== 工具方法 ==========
+
+    /**
+     * 替换文档中的文本
+     */
+    private static boolean replaceTextInDocument(XWPFDocument document, String findText, String replaceText) {
+        boolean found = false;
+
+        // 在段落中查找
+        for (XWPFParagraph paragraph : document.getParagraphs()) {
+            if (replaceInParagraph(paragraph, findText, replaceText)) {
+                found = true;
+            }
+        }
+
+        // 在表格中查找
+        for (XWPFTable table : document.getTables()) {
+            for (XWPFTableRow row : table.getRows()) {
+                for (XWPFTableCell cell : row.getTableCells()) {
+                    for (XWPFParagraph paragraph : cell.getParagraphs()) {
+                        if (replaceInParagraph(paragraph, findText, replaceText)) {
+                            found = true;
+                        }
+                    }
+                }
+            }
+        }
+
+        return found;
+    }
+
+    private static boolean replaceInParagraph(XWPFParagraph paragraph, String findText, String replaceText) {
+        boolean found = false;
+        for (XWPFRun run : paragraph.getRuns()) {
+            String text = run.getText(0);
+            if (text != null && text.contains(findText)) {
+                run.setText(text.replace(findText, replaceText), 0);
+                found = true;
+            }
+        }
+        return found;
+    }
+
+    /**
+     * 替换单元格中的文本
+     */
+    private static void replaceInCell(XWPFTableCell cell, String findText, String replaceText) {
+        for (XWPFParagraph paragraph : cell.getParagraphs()) {
+            for (XWPFRun run : paragraph.getRuns()) {
+                String text = run.getText(0);
+                if (text != null && text.contains(findText)) {
+                    run.setText(text.replace(findText, replaceText), 0);
+                }
+            }
+        }
+    }
+
+    /**
+     * 设置单元格文本
+     */
+    private static void setCellText(XWPFTableCell cell, String text) {
+        // 清除现有内容
+        for (int i = cell.getParagraphs().size() - 1; i >= 0; i--) {
+            cell.removeParagraph(i);
+        }
+
+        // 添加新内容
+        XWPFParagraph paragraph = cell.addParagraph();
+        XWPFRun run = paragraph.createRun();
+        run.setText(text);
+        paragraph.setAlignment(ParagraphAlignment.CENTER);
+    }
+
+    /**
+     * 复制单元格样式
+     */
+    private static void copyCellStyle(XWPFTableCell source, XWPFTableCell target) {
+        try {
+            target.setColor(source.getColor());
+            if (StringUtil.isNotEmpty(String.valueOf(source.getWidth()) )) {
+                target.setWidth(String.valueOf(source.getWidth()));
+            }
+        } catch (Exception e) {
+            // 忽略样式复制错误
+        }
+    }
+
+    /**
+     * 获取行文本
+     */
+    private static String getRowText(XWPFTableRow row) {
+        StringBuilder sb = new StringBuilder();
+        for (XWPFTableCell cell : row.getTableCells()) {
+            String cellText = getCellText(cell);
+            if (cellText != null) {
+                sb.append(cellText);
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 获取单元格文本
+     */
+    private static String getCellText(XWPFTableCell cell) {
+        StringBuilder sb = new StringBuilder();
+        for (XWPFParagraph paragraph : cell.getParagraphs()) {
+            if (paragraph.getText() != null) {
+                sb.append(paragraph.getText());
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 检查行是否为空
+     */
+    private static boolean isRowEmpty(XWPFTableRow row) {
+        for (XWPFTableCell cell : row.getTableCells()) {
+            String text = getCellText(cell);
+            if (text != null && !text.trim().isEmpty()) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 表格行数据类
+     */
+    @Getter
+    @Data
+    public static class TableRowData {
+        private String documentName;
+        private int pageCount;
+        private String remark;
+
+        public TableRowData() {
+            this.documentName = documentName;
+            this.pageCount = pageCount;
+            this.remark = remark;
+        }
+
+    }
+}

+ 0 - 225
assistMg/src/main/java/com/hotent/util/wordexcelutils/SimpleTableFiller.java

@@ -1,225 +0,0 @@
-package com.hotent.util.wordexcelutils;/**
- * @program: cbjs-mvue-master
- * @description:
- * @author: zhao yue yue
- * @create: 2025-11-26 17:03
- */
-
-import org.apache.poi.xwpf.usermodel.*;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- *@author: zhao yue yue
- *@create: 2025-11-26 17:03
- */
-public class SimpleTableFiller {
-
-    /**
-     * 简化版表格填充
-     */
-    public static void fillTableSimple(XWPFDocument document,
-                                       String organizationName,
-                                       List<Map<String,Object>> rowDataList,
-                                       int totalDocuments,
-                                       int totalPages,
-                                       String generateDate) {
-
-        // 1. 替换基本占位符
-        replaceTextInDocument(document, "[{价格主管部门或成本监审机构}]", organizationName);
-        replaceTextInDocument(document, "[{材料件数}]", String.valueOf(totalDocuments));
-        replaceTextInDocument(document, "[材料页数]", String.valueOf(totalPages));
-        replaceTextInDocument(document, "[登记表生成日期]", generateDate);
-
-        // 2. 填充表格数据
-        fillTableRows(document, rowDataList);
-    }
-
-    /**
-     * 填充表格行数据
-     */
-    private static void fillTableRows(XWPFDocument document, List<Map<String,Object>> rowDataList) {
-        if (rowDataList == null || rowDataList.isEmpty()) return;
-
-        XWPFTable table = document.getTables().get(0);
-        if (table == null) return;
-
-        // 找到模板行(包含[{序号}]等占位符的行)
-        int templateRowIndex = findTemplateRowIndex(table);
-        if (templateRowIndex == -1) return;
-
-        XWPFTableRow templateRow = table.getRows().get(templateRowIndex);
-
-        // 填充数据行
-        for (int i = 0; i < rowDataList.size(); i++) {
-            Map<String,Object> data = rowDataList.get(i);
-
-            // 如果是第一行数据,直接替换模板行
-            if (i == 0) {
-                fillExistingRow(templateRow, data, i + 1);
-            } else {
-                // 后续行创建新行
-                addNewDataRow(table, templateRow, data, i + 1);
-            }
-        }
-
-        // 如果数据行数少于模板行,移除多余的模板行
-        if (rowDataList.size() == 1) {
-            // 只保留一个数据行,移除其他空行
-            cleanupEmptyRows(table, templateRowIndex + 1);
-        }
-    }
-
-    /**
-     * 找到模板行索引
-     */
-    private static int findTemplateRowIndex(XWPFTable table) {
-        for (int i = 0; i < table.getRows().size(); i++) {
-            XWPFTableRow row = table.getRows().get(i);
-            if (containsPlaceholder(row, "[{序号}]")) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    /**
-     * 检查行是否包含占位符
-     */
-    private static boolean containsPlaceholder(XWPFTableRow row, String placeholder) {
-        for (XWPFTableCell cell : row.getTableCells()) {
-            for (XWPFParagraph paragraph : cell.getParagraphs()) {
-                if (paragraph.getText() != null && paragraph.getText().contains(placeholder)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * 填充现有行
-     */
-    private static void fillExistingRow(XWPFTableRow row, Map<String,Object> data, int sequence) {
-        List<XWPFTableCell> cells = row.getTableCells();
-        if (cells.size() < 4) return;
-
-        // 替换占位符
-        replaceInCell(cells.get(0), "[{序号}]", String.valueOf(sequence));
-        replaceInCell(cells.get(1), "[{资料名称}]",String.valueOf(data.get("documentName")));
-        replaceInCell(cells.get(2), "[{页数}]", Integer.parseInt(data.get("pageCount").toString())  > 0 ? String.valueOf(Integer.parseInt(data.get("pageCount").toString())) : "");
-        replaceInCell(cells.get(3), "[{备注}]", String.valueOf(data.get("remark")) != null ? String.valueOf(data.get("remark")) : "");
-    }
-
-    /**
-     * 添加新数据行
-     */
-    private static void addNewDataRow(XWPFTable table, XWPFTableRow templateRow, Map<String,Object> data , int sequence) {
-        // 创建新行
-        XWPFTableRow newRow = table.createRow();
-
-        // 复制模板行的单元格结构
-        List<XWPFTableCell> templateCells = templateRow.getTableCells();
-        List<XWPFTableCell> newCells = newRow.getTableCells();
-
-        // 确保单元格数量一致
-        while (newCells.size() < templateCells.size()) {
-            newRow.addNewTableCell();
-            newCells = newRow.getTableCells();
-        }
-
-        // 填充数据
-        setCellText(newCells.get(0), String.valueOf(sequence));
-        setCellText(newCells.get(1), String.valueOf(data.get("documentName")));
-        setCellText(newCells.get(2), Integer.parseInt(data.get("pageCount").toString())  > 0 ? String.valueOf(Integer.parseInt(data.get("pageCount").toString())) : "");
-        setCellText(newCells.get(3),  String.valueOf(data.get("remark")) != null ? String.valueOf(data.get("remark")) : "");
-    }
-
-    /**
-     * 清理空行
-     */
-    private static void cleanupEmptyRows(XWPFTable table, int startIndex) {
-        // 从指定索引开始移除空行
-        for (int i = table.getRows().size() - 1; i >= startIndex; i--) {
-            XWPFTableRow row = table.getRows().get(i);
-            if (isRowEmpty(row)) {
-                table.removeRow(i);
-            }
-        }
-    }
-
-    /**
-     * 检查行是否为空
-     */
-    private static boolean isRowEmpty(XWPFTableRow row) {
-        for (XWPFTableCell cell : row.getTableCells()) {
-            for (XWPFParagraph paragraph : cell.getParagraphs()) {
-                if (paragraph.getText() != null && !paragraph.getText().trim().isEmpty()) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    /**
-     * 替换单元格中的文本
-     */
-    private static void replaceInCell(XWPFTableCell cell, String placeholder, String value) {
-        for (XWPFParagraph paragraph : cell.getParagraphs()) {
-            for (XWPFRun run : paragraph.getRuns()) {
-                String text = run.getText(0);
-                if (text != null && text.contains(placeholder)) {
-                    run.setText(text.replace(placeholder, value), 0);
-                }
-            }
-        }
-    }
-
-    /**
-     * 设置单元格文本
-     */
-    private static void setCellText(XWPFTableCell cell, String text) {
-        // 清除现有内容
-        for (int i = cell.getParagraphs().size() - 1; i >= 0; i--) {
-            cell.removeParagraph(i);
-        }
-
-        // 添加新内容
-        XWPFParagraph paragraph = cell.addParagraph();
-        XWPFRun run = paragraph.createRun();
-        run.setText(text);
-        paragraph.setAlignment(ParagraphAlignment.CENTER);
-    }
-
-    /**
-     * 替换文档中的文本
-     */
-    private static void replaceTextInDocument(XWPFDocument document, String findText, String replaceText) {
-        for (XWPFParagraph paragraph : document.getParagraphs()) {
-            replaceInParagraph(paragraph, findText, replaceText);
-        }
-
-        for (XWPFTable table : document.getTables()) {
-            for (XWPFTableRow row : table.getRows()) {
-                for (XWPFTableCell cell : row.getTableCells()) {
-                    for (XWPFParagraph paragraph : cell.getParagraphs()) {
-                        replaceInParagraph(paragraph, findText, replaceText);
-                    }
-                }
-            }
-        }
-    }
-
-    private static void replaceInParagraph(XWPFParagraph paragraph, String findText, String replaceText) {
-        for (XWPFRun run : paragraph.getRuns()) {
-            String text = run.getText(0);
-            if (text != null && text.contains(findText)) {
-                run.setText(text.replace(findText, replaceText), 0);
-            }
-        }
-    }
-
-
-}