Selaa lähdekoodia

Merge remote-tracking branch 'cs/master'

zzw 1 viikko sitten
vanhempi
commit
fbc3c6d048

+ 8 - 1
assistMg/src/main/java/com/hotent/util/wordexcelutils/HtmlToWordConverterV2.java

@@ -52,8 +52,15 @@ public class HtmlToWordConverterV2 {
     private static String removePlaceholders(XWPFDocument document,String html) {
         Map<String, String> replacements = new HashMap<>();
         replacements.put("{底稿内容}", html);
-        SmartTemplateWriter.writeToTemplate(document, replacements);
+        //SmartTemplateWriter.writeToTemplate(document, replacements);
+        // 方法1:最简单直接的方法 - 删除包含特定文本的整个段落
+        WordDocumentUtils.deleteParagraphsContainingText(document, "{底稿内容}");
 
+        // 方法2:删除占位符段落
+        WordDocumentUtils.deletePlaceholderParagraph(document, "{底稿内容}");
+
+        // 方法3:强力删除
+        WordDocumentUtils.forceDeleteText(document, "{底稿内容}");
         return html;
     }
 

+ 533 - 0
assistMg/src/main/java/com/hotent/util/wordexcelutils/WordDocumentUtils.java

@@ -0,0 +1,533 @@
+package com.hotent.util.wordexcelutils;/**
+ * @program: cbjs-mvue-master
+ * @description:
+ * @author: zhao yue yue
+ * @create: 2026-01-27 15:07
+ */
+import org.apache.poi.xwpf.usermodel.*;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Iterator;
+import java.util.regex.Pattern;
+/**
+ *@author: zhao yue yue
+ *@create: 2026-01-27 15:07
+ */
+public class WordDocumentUtils {
+    /**
+     * 删除文档中所有指定的文本
+     * @param document Word文档对象
+     * @param textToDelete 要删除的文本
+     * @return 是否删除了文本
+     */
+    public static boolean deleteAllText(XWPFDocument document, String textToDelete) {
+        if (document == null || textToDelete == null || textToDelete.trim().isEmpty()) {
+            return false;
+        }
+
+        boolean textDeleted = false;
+
+        try {
+            // 1. 处理段落中的文本
+            textDeleted = deleteTextFromParagraphs(document, textToDelete) || textDeleted;
+
+            // 2. 处理表格中的文本
+            textDeleted = deleteTextFromTables(document, textToDelete) || textDeleted;
+
+            // 3. 处理页眉中的文本
+            textDeleted = deleteTextFromHeaders(document, textToDelete) || textDeleted;
+
+            // 4. 处理页脚中的文本
+            textDeleted = deleteTextFromFooters(document, textToDelete) || textDeleted;
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return textDeleted;
+    }
+
+    /**
+     * 从段落中删除文本
+     */
+    private static boolean deleteTextFromParagraphs(XWPFDocument document, String textToDelete) {
+        boolean textDeleted = false;
+
+        for (XWPFParagraph paragraph : document.getParagraphs()) {
+            if (deleteTextFromParagraph(paragraph, textToDelete)) {
+                textDeleted = true;
+            }
+        }
+
+        return textDeleted;
+    }
+
+    /**
+     * 从单个段落中删除文本
+     */
+    private static boolean deleteTextFromParagraph(XWPFParagraph paragraph, String textToDelete) {
+        if (paragraph == null) {
+            return false;
+        }
+
+        boolean textDeleted = false;
+
+        try {
+            // 获取段落的所有Run
+            List<XWPFRun> runs = paragraph.getRuns();
+            if (runs.isEmpty()) {
+                return false;
+            }
+
+            // 方法1:直接使用XML处理(最可靠)
+            String paragraphXml = paragraph.getCTP().xmlText();
+            if (paragraphXml.contains(textToDelete)) {
+                // 替换文本
+                String newXml = paragraphXml.replace(textToDelete, "");
+                // 使用正确的方式重建段落
+                try {
+                    CTP newCtp = CTP.Factory.parse(newXml);
+                    paragraph.getCTP().set(newCtp);
+                    textDeleted = true;
+                } catch (Exception e) {
+                    // 如果XML解析失败,使用其他方法
+                    e.printStackTrace();
+                }
+            }
+
+            // 方法2:遍历Run逐个处理
+            if (!textDeleted) {
+                textDeleted = processRunsForDeletion(runs, textToDelete);
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return textDeleted;
+    }
+
+    /**
+     * 处理Run以删除文本
+     */
+    private static boolean processRunsForDeletion(List<XWPFRun> runs, String textToDelete) {
+        boolean textDeleted = false;
+
+        try {
+            // 先收集所有Run的文本
+            List<String> runTexts = new ArrayList<>();
+            List<XWPFRun> runList = new ArrayList<>(runs);
+
+            for (XWPFRun run : runList) {
+                String text = run.getText(0);
+                runTexts.add(text != null ? text : "");
+            }
+
+            // 合并所有Run的文本
+            String combinedText = String.join("", runTexts);
+
+            if (combinedText.contains(textToDelete)) {
+                // 找到要删除的文本位置
+                int start = combinedText.indexOf(textToDelete);
+                int end = start + textToDelete.length();
+
+                // 计算文本在哪些Run中
+                int currentPos = 0;
+                for (int i = 0; i < runList.size(); i++) {
+                    String runText = runTexts.get(i);
+                    if (runText == null) {
+                        continue;
+                    }
+
+                    int runStart = currentPos;
+                    int runEnd = currentPos + runText.length();
+
+                    // 检查这个Run是否包含要删除的文本
+                    if (runEnd > start && runStart < end) {
+                        // 计算在这个Run中要删除的字符范围
+                        int deleteStart = Math.max(0, start - runStart);
+                        int deleteEnd = Math.min(runText.length(), end - runStart);
+
+                        // 删除文本
+                        String newText = runText.substring(0, deleteStart) +
+                                runText.substring(deleteEnd);
+
+                        // 更新Run的文本
+                        runList.get(i).setText(newText, 0);
+                        textDeleted = true;
+                    }
+
+                    currentPos += runText.length();
+                }
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return textDeleted;
+    }
+
+    /**
+     * 从表格中删除文本
+     */
+    private static boolean deleteTextFromTables(XWPFDocument document, String textToDelete) {
+        boolean textDeleted = false;
+
+        for (XWPFTable table : document.getTables()) {
+            for (XWPFTableRow row : table.getRows()) {
+                for (XWPFTableCell cell : row.getTableCells()) {
+                    for (XWPFParagraph paragraph : cell.getParagraphs()) {
+                        if (deleteTextFromParagraph(paragraph, textToDelete)) {
+                            textDeleted = true;
+                        }
+                    }
+                }
+            }
+        }
+
+        return textDeleted;
+    }
+
+    /**
+     * 从页眉中删除文本
+     */
+    private static boolean deleteTextFromHeaders(XWPFDocument document, String textToDelete) {
+        boolean textDeleted = false;
+
+        try {
+            List<XWPFHeader> headers = document.getHeaderList();
+            for (XWPFHeader header : headers) {
+                for (XWPFParagraph paragraph : header.getParagraphs()) {
+                    if (deleteTextFromParagraph(paragraph, textToDelete)) {
+                        textDeleted = true;
+                    }
+                }
+
+                // 处理页眉中的表格
+                for (XWPFTable table : header.getTables()) {
+                    for (XWPFTableRow row : table.getRows()) {
+                        for (XWPFTableCell cell : row.getTableCells()) {
+                            for (XWPFParagraph paragraph : cell.getParagraphs()) {
+                                if (deleteTextFromParagraph(paragraph, textToDelete)) {
+                                    textDeleted = true;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return textDeleted;
+    }
+
+    /**
+     * 从页脚中删除文本
+     */
+    private static boolean deleteTextFromFooters(XWPFDocument document, String textToDelete) {
+        boolean textDeleted = false;
+
+        try {
+            List<XWPFFooter> footers = document.getFooterList();
+            for (XWPFFooter footer : footers) {
+                for (XWPFParagraph paragraph : footer.getParagraphs()) {
+                    if (deleteTextFromParagraph(paragraph, textToDelete)) {
+                        textDeleted = true;
+                    }
+                }
+
+                // 处理页脚中的表格
+                for (XWPFTable table : footer.getTables()) {
+                    for (XWPFTableRow row : table.getRows()) {
+                        for (XWPFTableCell cell : row.getTableCells()) {
+                            for (XWPFParagraph paragraph : cell.getParagraphs()) {
+                                if (deleteTextFromParagraph(paragraph, textToDelete)) {
+                                    textDeleted = true;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return textDeleted;
+    }
+
+    /**
+     * 强力删除方法:完全重建段落
+     */
+    public static void forceDeleteText(XWPFDocument document, String textToDelete) {
+        if (document == null || textToDelete == null) {
+            return;
+        }
+
+        try {
+            // 处理所有段落
+            for (XWPFParagraph paragraph : document.getParagraphs()) {
+                forceDeleteFromParagraph(paragraph, textToDelete);
+            }
+
+            // 处理所有表格
+            for (XWPFTable table : document.getTables()) {
+                for (XWPFTableRow row : table.getRows()) {
+                    for (XWPFTableCell cell : row.getTableCells()) {
+                        for (XWPFParagraph paragraph : cell.getParagraphs()) {
+                            forceDeleteFromParagraph(paragraph, textToDelete);
+                        }
+                    }
+                }
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 强力删除段落中的文本
+     */
+    private static void forceDeleteFromParagraph(XWPFParagraph paragraph, String textToDelete) {
+        try {
+            String paragraphText = paragraph.getText();
+            if (paragraphText == null || !paragraphText.contains(textToDelete)) {
+                return;
+            }
+
+            // 完全重建段落
+            String newText = paragraphText.replace(textToDelete, "");
+
+            // 清空段落
+            List<XWPFRun> runs = paragraph.getRuns();
+            for (int i = runs.size() - 1; i >= 0; i--) {
+                try {
+                    paragraph.removeRun(i);
+                } catch (Exception e) {
+                    // 忽略异常
+                }
+            }
+
+            // 重新添加文本
+            if (!newText.trim().isEmpty()) {
+                XWPFRun run = paragraph.createRun();
+                run.setText(newText);
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 专门删除占位符的方法 - 这是最简单最可靠的方法
+     */
+    public static void deletePlaceholder(XWPFDocument document, String placeholder) {
+        if (document == null || placeholder == null) {
+            return;
+        }
+
+        // 处理所有段落
+        for (XWPFParagraph paragraph : document.getParagraphs()) {
+            String text = paragraph.getText();
+            if (text != null && text.contains(placeholder)) {
+                // 清空段落所有内容
+                List<XWPFRun> runs = paragraph.getRuns();
+                for (int i = runs.size() - 1; i >= 0; i--) {
+                    try {
+                        paragraph.removeRun(i);
+                    } catch (Exception e) {
+                        // 忽略异常
+                    }
+                }
+                // 可选:也可以删除整个段落
+                // document.removeBodyElement(document.getPosOfParagraph(paragraph));
+            }
+        }
+
+        // 处理表格
+        for (XWPFTable table : document.getTables()) {
+            for (XWPFTableRow row : table.getRows()) {
+                for (XWPFTableCell cell : row.getTableCells()) {
+                    for (XWPFParagraph paragraph : cell.getParagraphs()) {
+                        String text = paragraph.getText();
+                        if (text != null && text.contains(placeholder)) {
+                            // 清空段落所有内容
+                            List<XWPFRun> runs = paragraph.getRuns();
+                            for (int i = runs.size() - 1; i >= 0; i--) {
+                                try {
+                                    paragraph.removeRun(i);
+                                } catch (Exception e) {
+                                    // 忽略异常
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 查找并删除占位符段落 - 这个方法更彻底
+     */
+    public static void deletePlaceholderParagraph(XWPFDocument document, String placeholderText) {
+        if (document == null || placeholderText == null) {
+            return;
+        }
+
+        // 查找包含占位符的段落
+        List<XWPFParagraph> paragraphsToDelete = new ArrayList<>();
+
+        // 检查普通段落
+        for (XWPFParagraph paragraph : document.getParagraphs()) {
+            String text = paragraph.getText();
+            if (text != null && text.contains(placeholderText)) {
+                paragraphsToDelete.add(paragraph);
+            }
+        }
+
+        // 检查表格中的段落
+        for (XWPFTable table : document.getTables()) {
+            for (XWPFTableRow row : table.getRows()) {
+                for (XWPFTableCell cell : row.getTableCells()) {
+                    for (XWPFParagraph paragraph : cell.getParagraphs()) {
+                        String text = paragraph.getText();
+                        if (text != null && text.contains(placeholderText)) {
+                            paragraphsToDelete.add(paragraph);
+                        }
+                    }
+                }
+            }
+        }
+
+        // 删除找到的段落(从文档中移除)
+        for (XWPFParagraph paragraph : paragraphsToDelete) {
+            try {
+                // 获取段落位置并移除
+                int pos = document.getPosOfParagraph(paragraph);
+                if (pos >= 0) {
+                    document.removeBodyElement(pos);
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * 替换文本而不是删除
+     */
+    public static void replaceText(XWPFDocument document, String oldText, String newText) {
+        if (document == null || oldText == null) {
+            return;
+        }
+
+        try {
+            // 处理段落
+            for (XWPFParagraph paragraph : document.getParagraphs()) {
+                replaceTextInParagraph(paragraph, oldText, newText);
+            }
+
+            // 处理表格
+            for (XWPFTable table : document.getTables()) {
+                for (XWPFTableRow row : table.getRows()) {
+                    for (XWPFTableCell cell : row.getTableCells()) {
+                        for (XWPFParagraph paragraph : cell.getParagraphs()) {
+                            replaceTextInParagraph(paragraph, oldText, newText);
+                        }
+                    }
+                }
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 替换段落中的文本
+     */
+    private static void replaceTextInParagraph(XWPFParagraph paragraph, String oldText, String newText) {
+        try {
+            String paragraphText = paragraph.getText();
+            if (paragraphText == null || !paragraphText.contains(oldText)) {
+                return;
+            }
+
+            // 替换文本
+            String updatedText = paragraphText.replace(oldText, newText != null ? newText : "");
+
+            // 重建段落
+            List<XWPFRun> runs = paragraph.getRuns();
+            for (int i = runs.size() - 1; i >= 0; i--) {
+                try {
+                    paragraph.removeRun(i);
+                } catch (Exception e) {
+                    // 忽略异常
+                }
+            }
+
+            // 重新添加文本
+            if (!updatedText.trim().isEmpty()) {
+                XWPFRun run = paragraph.createRun();
+                run.setText(updatedText);
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 最简单直接的方法:删除包含特定文本的整个段落
+     */
+    public static void deleteParagraphsContainingText(XWPFDocument document, String textToFind) {
+        if (document == null || textToFind == null || textToFind.trim().isEmpty()) {
+            return;
+        }
+
+        try {
+            // 收集要删除的段落
+            List<XWPFParagraph> paragraphsToRemove = new ArrayList<>();
+
+            // 查找普通段落
+            for (XWPFParagraph paragraph : document.getParagraphs()) {
+                String text = paragraph.getText();
+                if (text != null && text.contains(textToFind)) {
+                    paragraphsToRemove.add(paragraph);
+                }
+            }
+
+            // 从后往前删除,避免索引问题
+            for (int i = paragraphsToRemove.size() - 1; i >= 0; i--) {
+                XWPFParagraph paragraph = paragraphsToRemove.get(i);
+                try {
+                    int pos = document.getPosOfParagraph(paragraph);
+                    if (pos >= 0) {
+                        document.removeBodyElement(pos);
+                    }
+                } catch (Exception e) {
+                    // 如果无法通过位置删除,尝试清空内容
+                    List<XWPFRun> runs = paragraph.getRuns();
+                    for (int j = runs.size() - 1; j >= 0; j--) {
+                        try {
+                            paragraph.removeRun(j);
+                        } catch (Exception ex) {
+                            // 忽略异常
+                        }
+                    }
+                }
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}