Pārlūkot izejas kodu

1.机构添加字段
2.worde处理工具类

赵越越 3 nedēļas atpakaļ
vecāks
revīzija
c5f573f35d

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

@@ -397,7 +397,7 @@ public class CostProjectDocumentManagerImpl extends BaseManagerImpl<CostProjectD
 
         //保存解析出的文件内容
         costProjectDocumentFileManager.saveBatch(req.getCostProjectDocumentFiles());
-        return req.getId();
+        return costProjectDocument.getId();
     }
 
     public synchronized String getWH(CostDocumentWh costDocumentWh){

+ 447 - 0
assistMg/src/main/java/com/hotent/util/wordexcelutils/RobustComplexDocumentProcessor.java

@@ -0,0 +1,447 @@
+package com.hotent.util.wordexcelutils;/**
+ * @program: cbjs-mvue-master
+ * @description:
+ * @author: zhao yue yue
+ * @create: 2025-12-03 11:13
+ */
+
+import org.apache.poi.xwpf.usermodel.*;
+
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *@author: zhao yue yue
+ *@create: 2025-12-03 11:13
+ */
+public class RobustComplexDocumentProcessor {
+
+    /**
+     * 处理复杂文档:使用Map和List作为数据结构
+     */
+    public static void processDocumentWithMaps(XWPFDocument document,
+                                               Map<String, String> textReplacements,
+                                               List<String> years,
+                                               List<Map<String, Object>> costItems) {
+
+        System.out.println("开始处理文档(Map版)...");
+
+        try {
+            // 1. 替换所有文本占位符
+            replaceAllTextPlaceholders(document, textReplacements);
+
+            // 2. 处理定价成本核定表
+            processCostTableWithMaps(document, years, costItems);
+
+            System.out.println("文档处理完成!");
+
+        } catch (Exception e) {
+            System.err.println("处理过程中出现错误: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 替换所有文本占位符
+     */
+    private static void replaceAllTextPlaceholders(XWPFDocument document,
+                                                   Map<String, String> replacements) {
+        System.out.println("开始替换文本占位符...");
+
+        // 存储替换统计
+        Map<String, Boolean> replacementStats = new HashMap<>();
+
+        // 尝试多种替换策略
+        for (Map.Entry<String, String> entry : replacements.entrySet()) {
+            String placeholder = entry.getKey();
+            String value = entry.getValue();
+
+            boolean success = false;
+
+            // 策略1:在段落中直接替换
+            success = replaceInParagraphs(document, placeholder, value);
+
+            // 策略2:在表格中替换
+            if (!success) {
+                success = replaceInTables(document, placeholder, value);
+            }
+
+            // 策略3:使用智能替换
+            if (!success) {
+                success = smartReplaceInDocument(document, placeholder, value);
+            }
+
+            replacementStats.put(placeholder, success);
+
+            String status = success ? "✅" : "❌";
+            System.out.println(status + " " + placeholder + " → " + value +
+                    (success ? "" : " (未找到)"));
+        }
+
+        // 打印替换统计
+        long successCount = replacementStats.values().stream().filter(v -> v).count();
+        long totalCount = replacementStats.size();
+        System.out.println("替换完成: " + successCount + "/" + totalCount + " 个占位符");
+    }
+
+    /**
+     * 在段落中替换
+     */
+    private static boolean replaceInParagraphs(XWPFDocument doc, String placeholder, String value) {
+        boolean found = false;
+        for (XWPFParagraph paragraph : doc.getParagraphs()) {
+            if (replaceInParagraph(paragraph, placeholder, value)) {
+                found = true;
+            }
+        }
+        return found;
+    }
+
+    /**
+     * 在表格中替换
+     */
+    private static boolean replaceInTables(XWPFDocument doc, String placeholder, String value) {
+        boolean found = false;
+        for (XWPFTable table : doc.getTables()) {
+            for (XWPFTableRow row : table.getRows()) {
+                for (XWPFTableCell cell : row.getTableCells()) {
+                    for (XWPFParagraph paragraph : cell.getParagraphs()) {
+                        if (replaceInParagraph(paragraph, placeholder, value)) {
+                            found = true;
+                        }
+                    }
+                }
+            }
+        }
+        return found;
+    }
+
+    /**
+     * 智能替换
+     */
+    private static boolean smartReplaceInDocument(XWPFDocument doc, String placeholder, String value) {
+        // 尝试处理带格式的占位符
+        String cleanPlaceholder = placeholder
+                .replaceAll("[\\[\\]{}]", "")
+                .replaceAll("\\s+", "");
+
+        if (cleanPlaceholder.length() > 3) {
+            // 在文档中搜索类似的文本
+            return searchAndReplaceFuzzy(doc, cleanPlaceholder, value);
+        }
+
+        return false;
+    }
+
+    /**
+     * 在段落中执行替换
+     */
+    private static boolean replaceInParagraph(XWPFParagraph paragraph, String findText, String replaceText) {
+        boolean replaced = false;
+        for (XWPFRun run : paragraph.getRuns()) {
+            String text = run.getText(0);
+            if (text != null && text.contains(findText)) {
+                run.setText(text.replace(findText, replaceText), 0);
+                replaced = true;
+            }
+        }
+        return replaced;
+    }
+
+    /**
+     * 模糊搜索和替换
+     */
+    private static boolean searchAndReplaceFuzzy(XWPFDocument doc, String search, String replace) {
+        boolean found = false;
+
+        // 搜索段落
+        for (XWPFParagraph paragraph : doc.getParagraphs()) {
+            String text = paragraph.getText();
+            if (text != null && text.toLowerCase().contains(search.toLowerCase())) {
+                // 在runs中查找具体位置
+                for (XWPFRun run : paragraph.getRuns()) {
+                    String runText = run.getText(0);
+                    if (runText != null && runText.toLowerCase().contains(search.toLowerCase())) {
+                        run.setText(runText.replaceAll("(?i)" + search, replace), 0);
+                        found = true;
+                    }
+                }
+            }
+        }
+
+        return found;
+    }
+
+    /**
+     * 使用Map处理定价成本核定表
+     */
+    private static void processCostTableWithMaps(XWPFDocument document,
+                                                 List<String> years,
+                                                 List<Map<String, Object>> costItems) {
+        System.out.println("开始处理定价成本核定表...");
+
+        // 找到所有表格
+        List<XWPFTable> tables = document.getTables();
+        if (tables.isEmpty()) {
+            System.out.println("未找到表格,创建新表格");
+            createNewCostTable(document, years, costItems);
+            return;
+        }
+
+        // 假设最后一个表格是定价成本核定表
+        XWPFTable costTable = tables.get(tables.size() - 1);
+        System.out.println("找到表格,当前行数: " + costTable.getRows().size());
+
+        // 重建表格
+        rebuildCostTableWithMaps(costTable, years, costItems);
+    }
+
+    /**
+     * 使用Map重建成本核定表
+     */
+    private static void rebuildCostTableWithMaps(XWPFTable table,
+                                                 List<String> years,
+                                                 List<Map<String, Object>> costItems) {
+        try {
+            // 1. 找到表头行
+            int headerRowIndex = findCostTableHeaderRow(table);
+            System.out.println("表头行索引: " + headerRowIndex);
+
+            // 2. 清空数据区域
+            clearCostTableData(table, headerRowIndex);
+
+            // 3. 重建表头(如果需要)
+            rebuildTableHeader(table, years, headerRowIndex);
+
+            // 4. 添加数据行
+            addCostTableDataRows(table, years, costItems, headerRowIndex);
+
+            // 5. 添加说明行
+            addCostTableFooter(table);
+
+            System.out.println("表格处理完成,最终行数: " + table.getRows().size());
+
+        } catch (Exception e) {
+            System.err.println("表格处理失败: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 找到成本表表头行
+     */
+    private static int findCostTableHeaderRow(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("成本项目") || rowText.contains("定价成本"))) {
+                return i;
+            }
+        }
+        return 0; // 默认第一行
+    }
+
+    /**
+     * 清空表格数据区域
+     */
+    private static void clearCostTableData(XWPFTable table, int headerRowIndex) {
+        // 保留表头行,移除后面的行
+        for (int i = table.getRows().size() - 1; i > headerRowIndex; i--) {
+            table.removeRow(i);
+        }
+        System.out.println("清理数据区域完成");
+    }
+
+    /**
+     * 重建表头
+     */
+    private static void rebuildTableHeader(XWPFTable table,
+                                           List<String> years,
+                                           int headerRowIndex) {
+        XWPFTableRow headerRow;
+
+        if (headerRowIndex < table.getRows().size()) {
+            headerRow = table.getRows().get(headerRowIndex);
+        } else {
+            headerRow = table.createRow();
+        }
+
+        // 清空现有单元格
+        for (XWPFTableCell cell : headerRow.getTableCells()) {
+            clearCellContent(cell);
+        }
+
+        // 确保有足够的单元格
+        int neededCells = 2 + years.size(); // 成本项目 + 行次 + 各年份
+        while (headerRow.getTableCells().size() < neededCells) {
+            headerRow.addNewTableCell();
+        }
+
+        // 设置表头内容
+        List<XWPFTableCell> cells = headerRow.getTableCells();
+
+        // 成本项目列
+        setCellText(cells.get(0), "成本项目");
+
+        // 行次列
+        setCellText(cells.get(1), "行次");
+
+        // 各年份列
+        for (int i = 0; i < years.size(); i++) {
+            setCellText(cells.get(2 + i), years.get(i) + "年度");
+        }
+
+        System.out.println("表头重建完成,列数: " + cells.size());
+    }
+
+    /**
+     * 添加数据行
+     */
+    private static void addCostTableDataRows(XWPFTable table,
+                                             List<String> years,
+                                             List<Map<String, Object>> costItems,
+                                             int startRowIndex) {
+        System.out.println("添加 " + costItems.size() + " 行数据");
+
+        for (int i = 0; i < costItems.size(); i++) {
+            Map<String, Object> item = costItems.get(i);
+
+            // 创建新行
+            XWPFTableRow dataRow = table.createRow();
+
+            // 确保有足够的单元格
+            int neededCells = 2 + years.size();
+            while (dataRow.getTableCells().size() < neededCells) {
+                dataRow.addNewTableCell();
+            }
+
+            List<XWPFTableCell> cells = dataRow.getTableCells();
+
+            // 设置成本项目
+            String costItemName = (String) item.get("costItemName");
+            setCellText(cells.get(0), costItemName != null ? costItemName : "");
+
+            // 设置行次
+            setCellText(cells.get(1), String.valueOf(i + 1));
+
+            // 设置各年份数据
+            for (int j = 0; j < years.size(); j++) {
+                String year = years.get(j);
+                Map<String, String> yearValues = (Map<String, String>) item.get("yearValues");
+                String value = yearValues != null ? yearValues.get(year) : "";
+                setCellText(cells.get(2 + j), value != null ? value : "0");
+            }
+        }
+    }
+
+    /**
+     * 添加表格说明
+     */
+    private static void addCostTableFooter(XWPFTable table) {
+        XWPFTableRow footerRow = table.createRow();
+
+        // 合并单元格显示说明
+        XWPFTableCell footerCell = footerRow.addNewTableCell();
+
+        try {
+            // 获取第一行的列数
+            int colCount = table.getRow(0).getTableCells().size();
+            footerCell.getCTTc().addNewTcPr().addNewGridSpan()
+                    .setVal(BigInteger.valueOf(colCount));
+        } catch (Exception e) {
+            System.err.println("合并单元格失败,但不影响使用: " + e.getMessage());
+        }
+
+        // 设置说明文本
+        XWPFParagraph paragraph = footerCell.addParagraph();
+        XWPFRun run = paragraph.createRun();
+        run.setText("说明:本表应根据行业会计制度及监审项目不同制表,对成本科目及计算方法做相应调整。");
+    }
+
+    /**
+     * 创建新的成本表(如果没有找到表格)
+     */
+    private static void createNewCostTable(XWPFDocument document,
+                                           List<String> years,
+                                           List<Map<String, Object>> costItems) {
+        XWPFTable newTable = document.createTable();
+
+        // 创建表头行
+        XWPFTableRow headerRow = newTable.getRow(0);
+
+        // 添加表头列
+        XWPFTableCell cell1 = headerRow.getCell(0);
+        setCellText(cell1, "成本项目");
+
+        XWPFTableCell cell2 = headerRow.addNewTableCell();
+        setCellText(cell2, "行次");
+
+        for (String year : years) {
+            XWPFTableCell yearCell = headerRow.addNewTableCell();
+            setCellText(yearCell, year + "年度");
+        }
+
+        // 添加数据行
+        addCostTableDataRows(newTable, years, costItems, 1);
+
+        // 添加说明行
+        addCostTableFooter(newTable);
+
+        System.out.println("新表格创建完成");
+    }
+
+    // ========== 工具方法 ==========
+
+    /**
+     * 设置单元格文本
+     */
+    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();
+        paragraph.setAlignment(ParagraphAlignment.CENTER);
+        XWPFRun run = paragraph.createRun();
+        run.setText(text != null ? text : "");
+    }
+
+    /**
+     * 清空单元格内容
+     */
+    private static void clearCellContent(XWPFTableCell cell) {
+        for (int i = cell.getParagraphs().size() - 1; i >= 0; i--) {
+            cell.removeParagraph(i);
+        }
+    }
+
+    /**
+     * 获取行文本
+     */
+    private static String getRowText(XWPFTableRow row) {
+        StringBuilder sb = new StringBuilder();
+        for (XWPFTableCell cell : row.getTableCells()) {
+            sb.append(getCellText(cell));
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 获取单元格文本
+     */
+    private static String getCellText(XWPFTableCell cell) {
+        StringBuilder sb = new StringBuilder();
+        for (XWPFParagraph paragraph : cell.getParagraphs()) {
+            String text = paragraph.getText();
+            if (text != null) {
+                sb.append(text);
+            }
+        }
+        return sb.toString();
+    }
+}

+ 1 - 0
uc/src/main/java/com/hotent/uc/manager/impl/OrgManagerImpl.java

@@ -461,6 +461,7 @@ public class OrgManagerImpl extends BaseManagerImpl<OrgDao, Org> implements OrgM
 			}
 		}
 		o.setDataScope(orgVo.getDataScope());
+		o.setCorporateRepresentative(orgVo.getCorporateRepresentative());
 		o.setProvinceCode(orgVo.getProvinceCode());
 		o.setCityCode(orgVo.getCityCode());
 		o.setCountyCode(orgVo.getCountyCode());

+ 15 - 0
uc/src/main/java/com/hotent/uc/model/Org.java

@@ -100,6 +100,12 @@ public class Org extends UcBaseModel<Org>  implements IGroup{
 	@TableField(exist=false)
 	@ApiModelProperty(name="parentOrgName",notes="上级组织名称")
 	protected  String parentOrgName;
+	/**
+	 * 法人代表
+	 */
+	@TableField("CORPORATE_REPRESENTATIVE")
+	@ApiModelProperty(name="corporateRepresentative",notes="法人代表")
+	protected  String corporateRepresentative;
 
 	@TableField("SUPERIOR_ORG_ID_")
 	@ApiModelProperty(name="superiorOrgId",notes="所属组织id")
@@ -264,6 +270,15 @@ public class Org extends UcBaseModel<Org>  implements IGroup{
 		this.joinExtSystemSyndir = joinExtSystemSyndir;
 	}
 
+
+	public String getCorporateRepresentative() {
+		return corporateRepresentative;
+	}
+
+	public void setCorporateRepresentative(String corporateRepresentative) {
+		this.corporateRepresentative = corporateRepresentative;
+	}
+
 	public Integer getIsInherit() {
 		return isInherit;
 	}

+ 11 - 0
uc/src/main/java/com/hotent/uc/params/org/OrgVo.java

@@ -72,6 +72,17 @@ public class OrgVo implements UpdateCompare {
 	@ApiModelProperty(value = "所属区、县")
 	private String countyCode;
 
+	@ApiModelProperty(value = "法人代表")
+	private String corporateRepresentative;
+
+	public String getCorporateRepresentative() {
+		return corporateRepresentative;
+	}
+
+	public void setCorporateRepresentative(String corporateRepresentative) {
+		this.corporateRepresentative = corporateRepresentative;
+	}
+
 	public String getJoinExtSystemType() {
 		return joinExtSystemType;
 	}