From eb7691b982d56bfceeeaf8fe3af0e3d4ff42b1ac Mon Sep 17 00:00:00 2001 From: huababa1 <2037205722@qq.com> Date: Tue, 2 Sep 2025 17:29:00 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E4=BF=AE=E6=94=B9=E3=80=91=E6=96=B0?= =?UTF-8?q?=E5=A2=9Ewps=E8=A1=A8=E6=A0=BC=E8=80=83=E7=82=B9=EF=BC=8C?= =?UTF-8?q?=E6=B1=89=E5=8C=96=E8=BE=B9=E6=A1=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wps_word/docx4j/paragraph/Paragraphs.java | 68 ++++++++++---- .../wps_word/docx4j/paragraph/RunText.java | 33 ++++++- .../utils/wps_word/docx4j/table/TableIng.java | 92 ++++++++++++++++++- 3 files changed, 171 insertions(+), 22 deletions(-) diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/paragraph/Paragraphs.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/paragraph/Paragraphs.java index 77e411f2..2c56cc7d 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/paragraph/Paragraphs.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/paragraph/Paragraphs.java @@ -505,30 +505,32 @@ public class Paragraphs { return "无"; } - // 段落边框 样式 - public static String getParagraphBorderStyle(P paragraph, StyleDefinitionsPart stylePart, WordprocessingMLPackage wordMLPackage, NumberingDefinitionsPart ndp) { - // 先查询自身段落数据 + // 段落边框 样式(带汉化) + public static String getParagraphBorderStyle(P paragraph, StyleDefinitionsPart stylePart, + WordprocessingMLPackage wordMLPackage, NumberingDefinitionsPart ndp) { PPr pPr = paragraph.getPPr(); if (pPr != null && pPr.getPBdr() != null) { PPrBase.PBdr border = pPr.getPBdr(); - // 上边框 + CTBorder top = border.getTop(); - // 下边框 CTBorder bottom = border.getBottom(); - // 左边框 CTBorder left = border.getLeft(); - // 右边框 CTBorder right = border.getRight(); - // 判断上下左右边框是否一致 - if (top.getVal().value().equals(bottom.getVal().value()) && top.getVal().value().equals(left.getVal().value()) && top.getVal().value().equals(right.getVal().value())) { - // 说明样式一样 - return top.getVal().value(); - } else { - // 说明样式不一样 - return top.getVal().value() + "-" + bottom.getVal().value() + "-" + left.getVal().value() + "-" + right.getVal().value(); + + if (top != null && bottom != null && left != null && right != null) { + String topVal = translateBorderVal(top.getVal().value()); + String bottomVal = translateBorderVal(bottom.getVal().value()); + String leftVal = translateBorderVal(left.getVal().value()); + String rightVal = translateBorderVal(right.getVal().value()); + + if (topVal.equals(bottomVal) && topVal.equals(leftVal) && topVal.equals(rightVal)) { + return topVal; // 四边一致 + } else { + return "上:" + topVal + " 下:" + bottomVal + " 左:" + leftVal + " 右:" + rightVal; + } } } - return "无"; + return "无边框"; } // 段落边框 - 颜色 @@ -913,5 +915,39 @@ public class Paragraphs { } // - + // 边框样式汉化 + private static String translateBorderVal(String val) { + if (val == null) return "无"; + switch (val.toLowerCase()) { + case "nil": return "无边框"; + case "none": return "无边框"; + case "single": return "单实线"; + case "thick": return "粗实线"; + case "double": return "双实线"; + case "dotted": return "点线"; + case "dashed": return "虚线"; + case "dotdash": return "点划线"; + case "dotdotdash": return "点点划线"; + case "wave": return "波浪线"; + case "triple": return "三重线"; + case "thin-thick-small-gap": return "细-粗-小间隔线"; + case "thick-thin-small-gap": return "粗-细-小间隔线"; + case "thin-thick-thin-small-gap": return "细-粗-细-小间隔线"; + case "thin-thick-medium-gap": return "细-粗-中间隔线"; + case "thick-thin-medium-gap": return "粗-细-中间隔线"; + case "thin-thick-thin-medium-gap": return "细-粗-细-中间隔线"; + case "thin-thick-large-gap": return "细-粗-大间隔线"; + case "thick-thin-large-gap": return "粗-细-大间隔线"; + case "thin-thick-thin-large-gap": return "细-粗-细-大间隔线"; + case "wave-double": return "双波浪线"; + case "wave-thick": return "粗波浪线"; + case "dash-small-gap": return "短虚线"; + case "dash-dot-stroked": return "点划虚线"; + case "three-d-emboss": return "三维浮雕"; + case "three-d-engrave": return "三维雕刻"; + case "outset": return "外凸"; + case "inset": return "内凹"; + default: return val; // 没映射到的直接返回原值 + } + } } diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/paragraph/RunText.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/paragraph/RunText.java index 69e5528b..75e8c0ab 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/paragraph/RunText.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/paragraph/RunText.java @@ -270,27 +270,31 @@ public class RunText { return "默认"; } - // 下划线类型 + // 下划线类型 (带汉化) public static String getParagraphFontUnderlineVal(List runs, String text, P paragraph, StyleDefinitionsPart stylePart) { if (runs == null || runs.isEmpty()) return null; + String underlineVal = null; + + // 直接取 run 的格式 for (R run : runs) { if (run == null) continue; RPr rPr = run.getRPr(); if (rPr != null && rPr.getU() != null && rPr.getU().getVal() != null) { - return rPr.getU().getVal().value(); // single, double, none 等 + underlineVal = rPr.getU().getVal().value(); + break; } } // 样式继承 - if (paragraph != null && stylePart != null) { + if (underlineVal == null && paragraph != null && stylePart != null) { PPr pPr = paragraph.getPPr(); if (pPr != null && pPr.getPStyle() != null) { String styleId = pPr.getPStyle().getVal(); try { Style style = stylePart.getStyleById(styleId); if (style != null && style.getRPr() != null && style.getRPr().getU() != null) { - return style.getRPr().getU().getVal().value(); + underlineVal = style.getRPr().getU().getVal().value(); } } catch (Exception e) { e.printStackTrace(); @@ -298,9 +302,28 @@ public class RunText { } } - return null; + if (underlineVal == null) return null; + + // 汉化映射 + switch (underlineVal.toLowerCase()) { + case "single": return "单下划线"; + case "double": return "双下划线"; + case "thick": return "粗下划线"; + case "dotted": return "点下划线"; + case "dottedheavy": return "粗点下划线"; + case "dash": return "虚线下划线"; + case "dashlong": return "长虚线下划线"; + case "dotdash": return "点划线下划线"; + case "dotdotdash": return "点点划线下划线"; + case "wavy": return "波浪线下划线"; + case "wavydouble": return "双波浪线下划线"; + case "wavyheavy": return "粗波浪线下划线"; + case "none": return "无下划线"; + default: return underlineVal; // 兜底,返回原值 + } } + // 下划线颜色 public static String getParagraphFontUnderlineColor(List runs, String text, P paragraph, StyleDefinitionsPart stylePart) { if (runs == null || runs.isEmpty()) return null; diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/table/TableIng.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/table/TableIng.java index 23012734..9d17416e 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/table/TableIng.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/table/TableIng.java @@ -178,6 +178,75 @@ public class TableIng { tblCursor.pop(); } } + /** + * 表格边框 - 左框线 → 是否绘制 + */ + public static String getTableBorderLeft(XmlCursor tblCursor, CTEndnotes endnotes) { + return getBorderDrawFlag(tblCursor, "left"); + } + + /** + * 表格边框 - 上框线 → 是否绘制 + */ + public static String getTableBorderTop(XmlCursor tblCursor, CTEndnotes endnotes) { + return getBorderDrawFlag(tblCursor, "top"); + } + + /** + * 表格边框 - 右框线 → 是否绘制 + */ + public static String getTableBorderRight(XmlCursor tblCursor, CTEndnotes endnotes) { + return getBorderDrawFlag(tblCursor, "right"); + } + + /** + * 表格边框 - 下框线 → 是否绘制 + */ + public static String getTableBorderBottom(XmlCursor tblCursor, CTEndnotes endnotes) { + return getBorderDrawFlag(tblCursor, "bottom"); + } + + /** + * 表格属性 → 列数 + */ + public static String getTableColumnCount(XmlCursor tblCursor, CTEndnotes endnotes) { + tblCursor.push(); + try { + // 选择第一行的所有单元格 + String path = "declare namespace w='" + W_NAMESPACE + "' .//w:tr[1]/w:tc"; + tblCursor.selectPath(path); + + int colCount = 0; + while (tblCursor.toNextSelection()) { + colCount++; + } + return colCount > 0 ? colCount + " 列" : null; + } finally { + tblCursor.pop(); + } + } + + /** + * 表格属性 → 行数 + */ + public static String getTableRowCount(XmlCursor tblCursor, CTEndnotes endnotes) { + tblCursor.push(); + try { + // 选择所有行 + String path = "declare namespace w='" + W_NAMESPACE + "' .//w:tr"; + tblCursor.selectPath(path); + + int rowCount = 0; + while (tblCursor.toNextSelection()) { + rowCount++; + } + return rowCount > 0 ? rowCount + " 行" : null; + } finally { + tblCursor.pop(); + } + } + + // 英文对齐转换为中文 public static String convertAlignToChinese(String align) { if (align == null) return null; @@ -189,6 +258,27 @@ public class TableIng { default: return align; } } - + /** + * 公共方法:判断某一边框是否绘制 + */ + private static String getBorderDrawFlag(XmlCursor tblCursor, String borderName) { + tblCursor.push(); + try { + String path = "declare namespace w='" + W_NAMESPACE + "' .//w:tblPr/w:tblBorders/w:" + borderName; + tblCursor.selectPath(path); + if (tblCursor.toNextSelection()) { + String val = tblCursor.getAttributeText(new QName(W_NAMESPACE, "val")); + // val 为 nil/none 表示不绘制,否则就是绘制 + if (val == null || "nil".equals(val) || "none".equals(val)) { + return "否"; + } else { + return "是"; + } + } + return "否"; // 没有找到节点默认不绘制 + } finally { + tblCursor.pop(); + } + } }