diff --git a/com.actionsoft.apps.coe.pal/lib/com.actionsoft.apps.coe.pal.jar b/com.actionsoft.apps.coe.pal/lib/com.actionsoft.apps.coe.pal.jar
index c07dcb29..00bb17a4 100644
Binary files a/com.actionsoft.apps.coe.pal/lib/com.actionsoft.apps.coe.pal.jar and b/com.actionsoft.apps.coe.pal/lib/com.actionsoft.apps.coe.pal.jar differ
diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/output/util/OutputWordUtil.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/output/util/OutputWordUtil.java
index c2b6a19c..38c92287 100644
--- a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/output/util/OutputWordUtil.java
+++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/output/util/OutputWordUtil.java
@@ -423,145 +423,183 @@ public class OutputWordUtil {
FormFile formFile = processfile.get(0);
DCContext fileDCContext = SDK.getBOAPI().getFileDCContext(formFile);
+
// 加载目标文件和待合并文档2
Document docs1 = new Document();
docs1.loadFromFile(outFile.getPath());
Document docs2 = new Document();
docs2.loadFromFile(fileDCContext.getFilePath());
+ try {
+ // 删除docs1的最后一个节(保留原有逻辑)
+ Section lastSection1 = docs1.getLastSection();
+ docs1.getSections().remove(lastSection1);
- Section lastSection1 = docs1.getLastSection();
+ // 在docs2中查找"三、流程图"的位置
+ TextSelection[] selectionsInDocs2 = docs2.findAllString("三、流程图", true, true);
- // 删除最后一个节
- docs1.getSections().remove(lastSection1);
+ if (selectionsInDocs2.length > 0) {
+ // 获取第一个匹配的位置
+ TextSelection selectionInDocs2 = selectionsInDocs2[0];
- // 提取所有表格
- List
allTables = extractAllTables(docs2);
+ // 获取包含文本的段落 - 通过遍历节和段落来查找
+ Paragraph targetParagraphInDocs2 = findParagraphContainingSelection(docs2, selectionInDocs2);
- if (allTables.size() >= 4) {
- // 拆分表格:前2个表格,后2个表格
- List firstTwoTables = allTables.subList(0, 1);
+ if (targetParagraphInDocs2 != null) {
+ // 提取docs2中"三、流程图"前面和后面的内容
+ List contentBeforeFlowChart = extractContentBeforeParagraph(docs2, targetParagraphInDocs2);
+ List contentAfterFlowChart = extractContentAfterParagraph(docs2, targetParagraphInDocs2);
- TextPosition position = findTextPosition(docs1, "流程图");
+ // 在docs1中查找"流程图"文本位置
+ Paragraph targetParagraphInDocs1= findAutoNumberedFlowchartParagraph(docs1);
- if (position != null) {
- // 在前面插入前2个表格
- insertTablesBeforeText(docs1, firstTwoTables, position);
-
- // 获取docs2中剩余的内容(除了前两个表格)
- List remainingContent = extractRemainingContent(docs2, firstTwoTables.size());
-
- // 将剩余内容插入到docs1的最后一节
- insertContentToLastSection(docs1, remainingContent);
+ if (targetParagraphInDocs1 != null) {
+ System.out.println("成功找到自动编号的流程图段落: '" + targetParagraphInDocs1.getText().trim() + "'");
- // 保存合并后的文档
- docs1.saveToFile(outFile.getPath(), FileFormat.Docx);
+ if (targetParagraphInDocs1 != null) {
+ // 在docs1的"流程图"前面插入docs2中"三、流程图"前面的内容
+ insertContentBeforeParagraph(docs1, contentBeforeFlowChart, targetParagraphInDocs1);
- docs1.dispose();
- docs2.dispose();
+ // 在docs1的"流程图"后面插入docs2中"三、流程图"后面的内容
+ insertContentAfterParagraph(docs1, contentAfterFlowChart, targetParagraphInDocs1);
- System.out.println("文档合并成功!");
+
+ // 保存合并后的文档
+ docs1.saveToFile(outFile.getPath(), FileFormat.Docx);
+ System.out.println("文档合并成功!");
+ } else {
+ System.out.println("在目标文档中未找到包含'流程图'的段落");
+ }
+ } else {
+ System.out.println("在目标文档中未找到文本'流程图'");
+ }
+ } else {
+ System.out.println("在源文档中未找到包含'三、流程图'的段落");
+ }
} else {
- System.out.println("未找到文本'流程图'");
+ System.out.println("在源文档中未找到文本'三、流程图'");
}
- } else {
- System.out.println("源文档中的表格数量不足4个,当前只有: " + allTables.size());
+ } finally {
+ docs1.dispose();
+ docs2.dispose();
}
-
-
}
-
/**
- * 提取剩余内容(除了前n个表格)
+ * 查找自动编号的"1.流程图"段落
*/
- private static List extractRemainingContent(Document document, int tablesToSkip) {
- List remainingContent = new ArrayList<>();
- int skippedTables = 0;
+ private static Paragraph findAutoNumberedFlowchartParagraph(Document document) {
+ System.out.println("开始查找自动编号的流程图段落...");
- for (int i = 0; i < document.getSections().getCount(); i++) {
- Section section = document.getSections().get(i);
- for (int j = 0; j < section.getBody().getChildObjects().getCount(); j++) {
- DocumentObject obj = section.getBody().getChildObjects().get(j);
+ for (Section section : (Iterable) document.getSections()) {
+ for (Paragraph paragraph : (Iterable) section.getParagraphs()) {
+ String paragraphText = paragraph.getText().trim();
- if (obj instanceof Table) {
- if (skippedTables < tablesToSkip) {
- skippedTables++;
- continue; // 跳过前n个表格
+ // 检查段落是否包含"流程图"
+ if (paragraphText.contains("流程图")) {
+ System.out.println("找到包含'流程图'的段落: '" + paragraphText + "'");
+
+ // 检查是否是自动编号段落
+ if (isAutoNumberedParagraph(paragraph)) {
+ System.out.println("这是一个自动编号段落");
+
+ // 进一步验证是否符合"1.流程图"的格式
+ if (isNumberedFlowchartFormat(paragraph, paragraphText)) {
+ System.out.println("符合编号流程图格式");
+ return paragraph;
+ }
+ } else {
+ System.out.println("这不是自动编号段落");
}
}
-
- // 克隆对象以避免重复引用问题
- remainingContent.add(obj.deepClone());
- }
- }
- return remainingContent;
- }
-
-
-
-
- /**
- * 将内容插入到最后一节
- */
- private static void insertContentToLastSection(Document docs1, List content) {
- int lastSectionIndex = docs1.getSections().getCount() - 1;
- Section lastSection = docs1.getSections().get(lastSectionIndex);
-
- // 在插入前添加分页符(可选)
- Paragraph pageBreak = new Paragraph(docs1);
- pageBreak.appendBreak(BreakType.Page_Break);
- lastSection.getBody().getChildObjects().add(pageBreak);
-
- // 插入剩余内容
- for (DocumentObject obj : content) {
- lastSection.getBody().getChildObjects().add(obj);
- }
- }
-
-
-
-
- /**
- * 提取文档中的所有表格
- */
- private static List extractAllTables(Document doc) {
- List tables = new ArrayList<>();
-
- for (Object sectionObj : doc.getSections()) {
- Section section = (Section) sectionObj;
-
- for (Object obj : section.getBody().getChildObjects()) {
- if (obj instanceof Table) {
- tables.add((Table) obj);
- }
}
}
- return tables;
+ System.out.println("未找到符合条件的自动编号流程图段落");
+ return null;
}
+
+
/**
- * 查找文本位置
+ * 验证是否符合编号流程图的格式
*/
- private static TextPosition findTextPosition(Document doc, String targetText) {
- for (int s = 0; s < doc.getSections().getCount(); s++) {
- Section section = doc.getSections().get(s);
+ private static boolean isNumberedFlowchartFormat(Paragraph paragraph, String paragraphText) {
+ // 检查文本是否包含"流程图"
+ if (!paragraphText.contains("流程图")) {
+ return false;
+ }
- for (int p = 0; p < section.getParagraphs().getCount(); p++) {
- Paragraph paragraph = section.getParagraphs().get(p);
- String paragraphText = paragraph.getText();
+ // 检查格式:数字 + 点 + 文本
+ // 匹配 "1.流程图", "1. 流程图", "1.流程图说明" 等格式
+ if (paragraphText.matches("^\\d+\\..*流程图.*") ||
+ paragraphText.matches("^\\d+\\.\\s*流程图.*")) {
+ return true;
+ }
- if (paragraphText.contains(targetText)) {
- return new TextPosition(s, p, paragraphText.indexOf(targetText));
+ // 对于复杂的自动编号,可能数字和文本是分开的
+ // 这种情况下主要依靠 isAutoNumberedParagraph 的判断
+ return true;
+ }
+
+
+
+
+ /**
+ * 判断段落是否是自动编号段落
+ */
+ private static boolean isAutoNumberedParagraph(Paragraph paragraph) {
+ // 方法1:检查列表格式
+ if (paragraph.getListFormat() != null) {
+ // 检查是否有列表级别
+ if (paragraph.getListFormat().getListLevelNumber() >= 0) {
+ System.out.println(" 通过列表级别判断为自动编号");
+ return true;
+ }
+
+
+ }
+
+ // 方法2:检查格式特征
+ if (paragraph.getFormat() != null) {
+ // 自动编号通常有特定的缩进
+ if (paragraph.getFormat().getLeftIndent() > 0 ||
+ paragraph.getFormat().getFirstLineIndent() != 0) {
+ System.out.println(" 通过缩进格式判断为自动编号");
+ return true;
+ }
+ }
+
+ // 方法3:检查文本模式(数字. 开头)
+ String text = paragraph.getText().trim();
+ if (text.matches("^\\d+\\..*")) {
+ System.out.println(" 通过文本模式判断为自动编号");
+ return true;
+ }
+
+ return false;
+ }
+
+
+ /**
+ * 查找包含文本选择的段落
+ */
+ private static Paragraph findParagraphContainingSelection(Document doc, TextSelection selection) {
+ for (int i = 0; i < doc.getSections().getCount(); i++) {
+ Section section = doc.getSections().get(i);
+ for (int j = 0; j < section.getParagraphs().getCount(); j++) {
+ Paragraph paragraph = section.getParagraphs().get(j);
+ // 检查这个段落是否包含选中的文本
+ if (paragraph.getText().contains(selection.getSelectedText())) {
+ return paragraph;
}
}
}
@@ -569,65 +607,154 @@ public class OutputWordUtil {
}
/**
- * 在指定文本前插入表格
+ * 提取文档中指定段落之前的所有内容
*/
- private static void insertTablesBeforeText(Document mainDoc, List tables, TextPosition position) {
- Section mainSection = mainDoc.getSections().get(position.getSectionIndex());
- Paragraph targetParagraph = mainSection.getParagraphs().get(position.getParagraphIndex());
- int insertIndex = mainSection.getBody().getChildObjects().indexOf(targetParagraph);
+ private static List extractContentBeforeParagraph(Document doc, Paragraph targetParagraph) {
+ List content = new ArrayList<>();
- // 在前方插入表格(反向插入以保持顺序)
- for (int i = tables.size() - 1; i >= 0; i--) {
- Table clonedTable = tables.get(i).deepClone();
- mainSection.getBody().getChildObjects().insert(insertIndex, clonedTable);
+ boolean foundTarget = false;
- // 在每个表格前添加一个空段落作为间隔
- Paragraph spacingPara = new Paragraph(mainDoc);
- mainSection.getBody().getChildObjects().insert(insertIndex, spacingPara);
+ // 遍历所有节
+ for (int i = 0; i < doc.getSections().getCount(); i++) {
+ Section section = doc.getSections().get(i);
+
+ // 遍历节中的所有子对象
+ for (int j = 0; j < section.getBody().getChildObjects().getCount(); j++) {
+ DocumentObject obj = section.getBody().getChildObjects().get(j);
+
+ if (obj == targetParagraph) {
+ foundTarget = true;
+ break;
+ }
+
+ // 克隆并添加对象
+ DocumentObject clonedObj = cloneDocumentObject(obj);
+ if (clonedObj != null) {
+ content.add(clonedObj);
+ }
+ }
+
+ if (foundTarget) {
+ break;
+ }
}
+
+ return content;
}
/**
- * 在指定文本后插入表格
+ * 提取文档中指定段落之后的所有内容
*/
- private static void insertTablesAfterText(Document mainDoc, List tables, TextPosition position) {
- Section mainSection = mainDoc.getSections().get(position.getSectionIndex());
- Paragraph targetParagraph = mainSection.getParagraphs().get(position.getParagraphIndex());
- int insertIndex = mainSection.getBody().getChildObjects().indexOf(targetParagraph) + 1;
+ private static List extractContentAfterParagraph(Document doc, Paragraph targetParagraph) {
+ List content = new ArrayList<>();
- // 在后方插入表格
- for (Table table : tables) {
- Table clonedTable = table.deepClone();
- mainSection.getBody().getChildObjects().insert(insertIndex, clonedTable);
- insertIndex++;
+ boolean foundTarget = false;
- // 在每个表格后添加一个空段落作为间隔
- Paragraph spacingPara = new Paragraph(mainDoc);
- mainSection.getBody().getChildObjects().insert(insertIndex, spacingPara);
- insertIndex++;
+ // 遍历所有节
+ for (int i = 0; i < doc.getSections().getCount(); i++) {
+ Section section = doc.getSections().get(i);
+
+ // 遍历节中的所有子对象
+ for (int j = 0; j < section.getBody().getChildObjects().getCount(); j++) {
+ DocumentObject obj = section.getBody().getChildObjects().get(j);
+
+ if (foundTarget) {
+ // 克隆并添加目标之后的对象
+ DocumentObject clonedObj = cloneDocumentObject(obj);
+ if (clonedObj != null) {
+ content.add(clonedObj);
+ }
+ }
+
+ if (obj == targetParagraph) {
+ foundTarget = true;
+ }
+ }
}
+
+ return content;
}
/**
- * 文本位置信息类
+ * 在指定段落前插入内容
*/
- static class TextPosition {
- private int sectionIndex;
- private int paragraphIndex;
- private int textOffset;
+ private static void insertContentBeforeParagraph(Document doc, List content, Paragraph targetParagraph) {
+ // 找到目标段落所在的节和索引
+ int targetIndex = -1;
+ Section targetSection = null;
- public TextPosition(int sectionIndex, int paragraphIndex, int textOffset) {
- this.sectionIndex = sectionIndex;
- this.paragraphIndex = paragraphIndex;
- this.textOffset = textOffset;
+ for (int i = 0; i < doc.getSections().getCount(); i++) {
+ Section section = doc.getSections().get(i);
+ for (int j = 0; j < section.getBody().getChildObjects().getCount(); j++) {
+ if (section.getBody().getChildObjects().get(j) == targetParagraph) {
+ targetSection = section;
+ targetIndex = j;
+ break;
+ }
+ }
+ if (targetSection != null) break;
}
- public int getSectionIndex() { return sectionIndex; }
- public int getParagraphIndex() { return paragraphIndex; }
- public int getTextOffset() { return textOffset; }
+ if (targetSection != null && targetIndex != -1) {
+ // 在目标位置之前插入内容(逆序插入以保证顺序正确)
+ for (int i = content.size() - 1; i >= 0; i--) {
+ DocumentObject obj = content.get(i);
+ targetSection.getBody().getChildObjects().insert(targetIndex, obj);
+ }
+ }
}
+
+
+
+
+
+ /**
+ * 在指定段落之后插入内容
+ */
+ private static void insertContentAfterParagraph(Document document, List content, Paragraph targetParagraph) {
+
+
+
+ int lastSectionIndex = document.getSections().getCount() - 1;
+ Section lastSection = document.getSections().get(lastSectionIndex);
+
+ // 在插入前添加分页符(可选)
+ Paragraph pageBreak = new Paragraph(document);
+ pageBreak.appendBreak(BreakType.Page_Break);
+ lastSection.getBody().getChildObjects().add(pageBreak);
+
+ // 插入剩余内容
+ for (DocumentObject obj : content) {
+ lastSection.getBody().getChildObjects().add(obj);
+ }
+
+
+ }
+
+
+
+
+ /**
+ * 克隆文档对象
+ */
+ private static DocumentObject cloneDocumentObject(DocumentObject obj) {
+ try {
+ if (obj instanceof Paragraph) {
+ return ((Paragraph) obj).deepClone();
+ } else if (obj instanceof Table) {
+ return ((Table) obj).deepClone();
+ }
+ // 可以添加其他类型的处理
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+
+
/**
* 生成word文件
*
@@ -1073,13 +1200,17 @@ public class OutputWordUtil {
for (int i = 2; i < doc2.getSections().getCount(); i++) {
Section targetSection = doc2.getSections().get(i);
- PageSetup pageSetup = targetSection.getPageSetup();
- PageOrientation orientation = pageSetup.getOrientation();
- // 根据合并文档节的页面方向选择模板
- PageOrientation mergeOrientation = pageSetup.getOrientation();
- Document templateDoc = (mergeOrientation == PageOrientation.Landscape) ? doc3 : doc1;
+ double width = targetSection.getPageSetup().getPageSize().getWidth();
+ double height = targetSection.getPageSetup().getPageSize().getHeight();
+
+ // 实际方向(根据尺寸)
+ boolean actualLandscape = isLandscapeBySize(width, height);
+
+ Document templateDoc = actualLandscape ? doc3 : doc1;
+
+
// 复制模板文档的页眉和页脚到新文档
HeaderFooter sourceHeader = templateDoc.getSections().get(0).getHeadersFooters().getHeader();
@@ -1114,10 +1245,16 @@ public class OutputWordUtil {
Section targetSection = doc2.getSections().get(i);
HeaderFooter targetFooter = targetSection.getHeadersFooters().getFooter();
- PageSetup pageSetup = targetSection.getPageSetup();
+ double width = targetSection.getPageSetup().getPageSize().getWidth();
+ double height = targetSection.getPageSetup().getPageSize().getHeight();
+
+ // 实际方向(根据尺寸)
+ boolean actualLandscape = isLandscapeBySize(width, height);
+
+ Document templateDoc = actualLandscape ? doc3 : doc1;
+
+
- PageOrientation mergeOrientation = pageSetup.getOrientation();
- Document templateDoc = (mergeOrientation == PageOrientation.Landscape) ? doc3 : doc1;
HeaderFooter sourceFooter = templateDoc.getSections().get(0).getHeadersFooters().getFooter();
targetFooter.getChildObjects().clear();
@@ -1859,6 +1996,18 @@ public class OutputWordUtil {
}
+ /**
+ * 判断是否为横向
+ * @param width
+ * @param height
+ * @return
+ */
+ public static boolean isLandscapeBySize(double width, double height) {
+ return width > height;
+ }
+
+
+
/**
* 生成word文件
*