diff --git a/exam-module-judgement/exam-module-judgement-biz/pom.xml b/exam-module-judgement/exam-module-judgement-biz/pom.xml index fa618c20..db916edc 100644 --- a/exam-module-judgement/exam-module-judgement-biz/pom.xml +++ b/exam-module-judgement/exam-module-judgement-biz/pom.xml @@ -153,6 +153,37 @@ 2.4.2-SNAPSHOT compile + + org.docx4j + docx4j-core + 11.5.3 + + + org.docx4j + docx4j-JAXB-MOXy + 11.5.3 + + + + org.docx4j + docx4j-JAXB-Internal + 8.3.9 + + + + + org.eclipse.persistence + org.eclipse.persistence.moxy + 3.0.2 + + + + + jakarta.xml.bind + jakarta.xml.bind-api + 3.0.1 + + diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Wps/WpsController.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Wps/WpsController.java index 75bb7434..42a2fa5c 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Wps/WpsController.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Wps/WpsController.java @@ -45,6 +45,11 @@ public class WpsController { JudgementWpsPptxService judgementWpsPptxService; @Resource JudgementWpsExcelService judgementWpsExcelService; + @GetMapping("/docxMaster") + public CommonResult docxMaster() throws Exception { + judgementWpsWordService.docxMaster("D:\\Project\\Exam\\Software\\Temp\\1.docx"); + return CommonResult.success(""); + } /** * wps word * @return 判分 diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_word/JudgementWpsWordService.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_word/JudgementWpsWordService.java index 42bb5d14..ed630418 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_word/JudgementWpsWordService.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_word/JudgementWpsWordService.java @@ -19,6 +19,7 @@ import java.util.List; */ public interface JudgementWpsWordService { + void docxMaster(String path) throws Exception; /** * 获取word文件内得考点及描述 * @param path minio文件路径 diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_word/JudgementWpsWordServiceImpl.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_word/JudgementWpsWordServiceImpl.java index 980567ae..b3a63de8 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_word/JudgementWpsWordServiceImpl.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_word/JudgementWpsWordServiceImpl.java @@ -19,6 +19,7 @@ import pc.exam.pp.module.judgement.service.auto_tools.AutoToolsService; import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText; import pc.exam.pp.module.judgement.utils.HtmlAppender; import pc.exam.pp.module.judgement.utils.wps_word.WpsWordUtils; +import pc.exam.pp.module.judgement.utils.wps_word.docx4j.DocxMaster; import pc.exam.pp.module.judgement.utils.wps_word.vo.WordInfoReqVo; import pc.exam.pp.module.judgement.utils.wps_word.vo.WordVO; import pc.exam.pp.module.system.dal.dataobject.user.AdminUserDO; @@ -47,6 +48,11 @@ public class JudgementWpsWordServiceImpl implements JudgementWpsWordService { @Resource private AdminUserService userService; + @Override + public void docxMaster(String path) throws Exception { + DocxMaster.docxMaster(path); + } + @Override public List programmingWpsWord(String path) throws Exception { String pathName = ""; diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/DocxMaster.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/DocxMaster.java new file mode 100644 index 00000000..2f31a0d3 --- /dev/null +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/DocxMaster.java @@ -0,0 +1,101 @@ +package pc.exam.pp.module.judgement.utils.wps_word.docx4j; + +import jakarta.xml.bind.JAXBElement; +import org.docx4j.XmlUtils; +import org.docx4j.model.structure.HeaderFooterPolicy; +import org.docx4j.model.structure.SectionWrapper; +import org.docx4j.openpackaging.exceptions.Docx4JException; +import org.docx4j.openpackaging.packages.WordprocessingMLPackage; +import org.docx4j.openpackaging.parts.WordprocessingML.HeaderPart; +import org.docx4j.openpackaging.parts.WordprocessingML.NumberingDefinitionsPart; +import org.docx4j.openpackaging.parts.WordprocessingML.StyleDefinitionsPart; +import org.docx4j.wml.*; +import pc.exam.pp.module.judgement.utils.wps_word.docx4j.paragraph.Convert; +import pc.exam.pp.module.judgement.utils.wps_word.docx4j.paragraph.Paragraphs; +import pc.exam.pp.module.judgement.utils.wps_word.docx4j.paragraph.RunText; +import pc.exam.pp.module.judgement.utils.wps_word.docx4j.section.SectionPage; +import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.JudgementWordsVO; + +import java.io.File; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +/** + * @author REN + */ +public class DocxMaster { + + public static void docxMaster(String path) throws Docx4JException { + + // 一共分为 段落 + // 创建考点数组 + List judgementWordsVOS = new ArrayList<>(); + WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new File(path)); + List paragraphs = wordMLPackage.getMainDocumentPart().getContent(); + StyleDefinitionsPart stylePart = wordMLPackage.getMainDocumentPart().getStyleDefinitionsPart(); + NumberingDefinitionsPart ndp = wordMLPackage.getMainDocumentPart().getNumberingDefinitionsPart(); + List sections = wordMLPackage.getDocumentModel().getSections(); + + int index = 0; + for (Object obj : paragraphs) { + Object realObj = XmlUtils.unwrap(obj); + if (realObj instanceof P) { + index++; + P paragraph = (P) realObj; + PPr pPr = paragraph.getPPr(); + // 安全判断:pPr 为空或 pPr 中没有 sectPr,才认为是普通段落 + if (pPr == null || pPr.getSectPr() == null) { + String firstId = Convert.getStringRandom(); + // 首先先创建段落 + JudgementWordsVO judgementWordsVO = new JudgementWordsVO(); + judgementWordsVO.setName("第" + index + "段"); + judgementWordsVO.setParentId("0"); + judgementWordsVO.setId(firstId); + judgementWordsVOS.add(judgementWordsVO); + judgementWordsVOS = Paragraphs.getParagraphAlignment(paragraph, stylePart, judgementWordsVOS, index, firstId); + judgementWordsVOS = Paragraphs.getParagraphOutlineLvl(paragraph, stylePart, judgementWordsVOS, index, firstId); + judgementWordsVOS = Paragraphs.getParagraphIndent(paragraph, stylePart, judgementWordsVOS, index, firstId); + judgementWordsVOS = Paragraphs.getParagraphSpacing(paragraph, stylePart, judgementWordsVOS, index, firstId); + judgementWordsVOS = Paragraphs.getParagraphList(paragraph, ndp, judgementWordsVOS, index, firstId); + + System.out.println(judgementWordsVOS); + } else { + Paragraphs.getParagraphCols(paragraph, stylePart); + } + // 句子 + List contents = paragraph.getContent(); + for (Object content : contents) { + if (content instanceof R) { + R run = (R) content; + String text = getRunText(run); + if (text == null || text.trim().isEmpty()) { + continue; + } + // 句子-字体 + RunText.getParagraphAlignment(run, text); + } + } + } + } + SectionPage.getSectionPageHeader(sections, wordMLPackage); + SectionPage.getSectionPageFooter(sections, wordMLPackage); + + } + + // 提取 run 中的文本内容 + private static String getRunText(R run) { + StringBuilder sb = new StringBuilder(); + for (Object content : run.getContent()) { + if (content instanceof Text) { + sb.append(((Text) content).getValue()); + } else if (content instanceof JAXBElement) { + Object val = ((JAXBElement) content).getValue(); + if (val instanceof Text) { + sb.append(((Text) val).getValue()); + } + } + } + return sb.toString(); + } +} diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/DocxSetInfo.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/DocxSetInfo.java new file mode 100644 index 00000000..10cf41e5 --- /dev/null +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/DocxSetInfo.java @@ -0,0 +1,22 @@ +package pc.exam.pp.module.judgement.utils.wps_word.docx4j; + +import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.JudgementWordsVO; + +import java.util.List; + +/** + * @author REN + */ +public class DocxSetInfo { + public static List setInfo(List judgementWordsVOS, String id, String parentId, String contentIn, String content, String name) { + JudgementWordsVO judgementWordsVO = new JudgementWordsVO(); + judgementWordsVO.setId(id); + judgementWordsVO.setParentId(parentId); + judgementWordsVO.setContentIn(contentIn); + judgementWordsVO.setContent(content); + judgementWordsVO.setName(name); + judgementWordsVOS.add(judgementWordsVO); + return judgementWordsVOS; + } + +} diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/paragraph/Convert.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/paragraph/Convert.java new file mode 100644 index 00000000..53d99cd3 --- /dev/null +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/paragraph/Convert.java @@ -0,0 +1,84 @@ +package pc.exam.pp.module.judgement.utils.wps_word.docx4j.paragraph; + +import org.docx4j.openpackaging.parts.WordprocessingML.NumberingDefinitionsPart; +import org.docx4j.wml.*; + +import java.math.BigInteger; +import java.util.List; +import java.util.Random; + +public class Convert { + public static String getStringRandom() { + String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + Random random = new Random(); + StringBuilder sb = new StringBuilder(); + + // 生成指定长度的随机字符字符串 + for (int i = 0; i < 10; i++) { + int randomIndex = random.nextInt(characters.length()); + // 随机字符 + sb.append(characters.charAt(randomIndex)); + } + return sb.toString(); + } + public static String convertJc(String val) { + switch (val) { + case "left": return "左对齐"; + case "center": return "居中对齐"; + case "right": return "右对齐"; + case "both": return "两端对齐"; + case "distribute": return "分散对齐"; + default: return "未知对齐方式(" + val + ")"; + } + } + + public static String convertOutlineLvl(String val) { + switch (val) { + case "0": + return "标题1"; + case "1": + return "标题2"; + default: + return null; + } + } + + public static Numbering.AbstractNum getAbstractNumById(NumberingDefinitionsPart ndp, BigInteger abstractNumId) { + List abstractNums = ndp.getJaxbElement().getAbstractNum(); + for (Numbering.AbstractNum abs : abstractNums) { + if (abs.getAbstractNumId().equals(abstractNumId)) { + return abs; + } + } + return null; + } + + public static void printBorder(String name, CTBorder ctBorder) { + if (ctBorder != null) { + System.out.println(name + " 样式: " + ctBorder.getVal()); // eg: single, double, dashed + System.out.println(name + " 颜色: #" + ctBorder.getColor()); // hex color + System.out.println(name + " 宽度: " + ctBorder.getSz() + " 八分之一磅"); // 单位是1/8 pt + System.out.println(name + " 间距: " + ctBorder.getSpace()); // twips之间距(可选) + } + } + + public static String getFirstRunFont(P paragraph) { + List runs = paragraph.getContent(); + for (Object runObj : runs) { + if (runObj instanceof R) { + R run = (R) runObj; + RPr rPr = run.getRPr(); + if (rPr != null && rPr.getRFonts() != null) { + RFonts fonts = rPr.getRFonts(); + if (fonts.getAscii() != null) { + return fonts.getAscii(); + } else if (fonts.getHAnsi() != null) { + return fonts.getHAnsi(); + } + } + break; // 只取第一个文字 Run + } + } + return null; + } +} 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 new file mode 100644 index 00000000..27e324dc --- /dev/null +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/paragraph/Paragraphs.java @@ -0,0 +1,381 @@ +package pc.exam.pp.module.judgement.utils.wps_word.docx4j.paragraph; + +import jakarta.xml.bind.JAXBElement; +import org.docx4j.openpackaging.parts.WordprocessingML.NumberingDefinitionsPart; +import org.docx4j.openpackaging.parts.WordprocessingML.StyleDefinitionsPart; +import org.docx4j.wml.*; +import pc.exam.pp.module.judgement.utils.wps_word.docx4j.DocxSetInfo; +import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.JudgementWordsVO; + +import java.math.BigInteger; +import java.util.List; + +/** + * @author REN + */ +public class Paragraphs { + /** + * 段落-对齐方式 + * @param paragraph + * @param stylePart + * @param judgementWordsVOS + * @param betoLong + * @param firstId + * @return + */ + public static List getParagraphAlignment(P paragraph, StyleDefinitionsPart stylePart, List judgementWordsVOS, int betoLong, String firstId) { + String name = "【第" + betoLong + "段】"; + String parName = "【段落格式(常规)】【对齐方式】"; + if (paragraph == null) { + return judgementWordsVOS; + } + // 先查段落自身 + PPr pPr = paragraph.getPPr(); + String parentId = Convert.getStringRandom(); + if (pPr != null && pPr.getJc() != null && pPr.getJc().getVal() != null) { + String value = Convert.convertJc(pPr.getJc().getVal().value()); + if (value != null) { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + parName + value, name + parName + value, name); + } + } + // 若段落未定义对齐方式,则尝试从样式中继承 + if (pPr != null && pPr.getPStyle() != null && stylePart != null) { + String styleId = pPr.getPStyle().getVal(); + Style style = stylePart.getStyleById(styleId); + if (style != null && style.getPPr() != null && style.getPPr().getJc() != null) { + String value = Convert.convertJc(style.getPPr().getJc().getVal().value()); + if (value != null) { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + parName + value, name + parName + value, name); + } + } + } + // 都没有设置,返回默认 + return judgementWordsVOS; + } + + // 段落-大纲级别 + public static List getParagraphOutlineLvl(P paragraph, StyleDefinitionsPart stylePart, List judgementWordsVOS, int betoLong, String firstId) { + if (paragraph == null) { + return judgementWordsVOS; + } + String name = "【第" + betoLong + "段】"; + String parName = "【段落格式(常规)】【大纲级别】"; + String parentId = Convert.getStringRandom(); + // 先查询自身段落数据 + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getOutlineLvl() != null && pPr.getOutlineLvl().getVal() != null) { + String value = Convert.convertOutlineLvl(pPr.getOutlineLvl().getVal().toString()); + if (value != null) { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + parName + value, name + parName + value, name); + } + } + // 没有设置,从公共方法中获取参数 + if (pPr != null && pPr.getPStyle() != null && stylePart != null) { + String styleId = pPr.getPStyle().getVal(); + Style style = stylePart.getStyleById(styleId); + if (style != null && style.getPPr() != null && style.getPPr().getJc() != null) { + String value = Convert.convertJc(style.getPPr().getOutlineLvl().getVal().toString()); + if (value != null) { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + parName + value, name + parName + value, name); + } + } + } + return judgementWordsVOS; + } + // 段落-缩进 + public static List getParagraphIndent(P paragraph, StyleDefinitionsPart stylePart, List judgementWordsVOS, int betoLong, String firstId) { + if (paragraph == null) { + return judgementWordsVOS; + } + String name = "【第" + betoLong + "段】"; + String parentId = Convert.getStringRandom(); + // 先查询自身段落数据 + PPr pPr = paragraph.getPPr(); + PPrBase.Ind ind = pPr.getInd(); + if (ind != null) { + if (ind.getLeft() != null) { + String value = ind.getLeft().intValue() + " 磅"; + String parName = "【段落格式(缩进)】【左缩进】"; + if (value != null) { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + parName + value, name + parName + value, name); + } + } + if (ind.getRight() != null) { + String value = ind.getRight().intValue() + " 磅"; + String parName = "【段落格式(缩进)】【右缩进】"; + if (value != null) { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + parName + value, name + parName + value, name); + } + } + if (ind.getFirstLine() != null) { + String value = ind.getFirstLine().intValue() + " 磅"; + String parName = "【段落格式(缩进)】【首行缩进】"; + if (value != null) { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + parName + value, name + parName + value, name); + } + } + if (ind.getHanging() != null) { + String value = ind.getHanging().intValue() + " 磅"; + String parName = "【段落格式(缩进)】【悬挂缩进】"; + if (value != null) { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + parName + value, name + parName + value, name); + } + } + } + if (pPr != null && pPr.getPStyle() != null && stylePart != null) { + String styleId = pPr.getPStyle().getVal(); + Style style = stylePart.getStyleById(styleId); + if (style != null && style.getPPr() != null && style.getPPr().getInd() != null) { + PPrBase.Ind indStyle = style.getPPr().getInd(); + if (indStyle.getLeft() != null) { + String value = indStyle.getLeft().intValue() + " 磅"; + String parName = "【段落格式(缩进)】【左缩进】"; + if (value != null) { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + parName + value, name + parName + value, name); + } + } + if (indStyle.getRight() != null) { + String value = indStyle.getRight().intValue() + " 磅"; + String parName = "【段落格式(缩进)】【右缩进】"; + if (value != null) { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + parName + value, name + parName + value, name); + } + } + if (indStyle.getFirstLine() != null) { + String value = indStyle.getFirstLine().intValue() + " 磅"; + String parName = "【段落格式(缩进)】【首行缩进】"; + if (value != null) { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + parName + value, name + parName + value, name); + } + } + if (indStyle.getHanging() != null) { + String value = indStyle.getHanging().intValue() + " 磅"; + String parName = "【段落格式(缩进)】【悬挂缩进】"; + if (value != null) { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + parName + value, name + parName + value, name); + } + } + } + } + return judgementWordsVOS; + } + // 段落-间距 + public static List getParagraphSpacing(P paragraph, StyleDefinitionsPart stylePart, List judgementWordsVOS, int betoLong, String firstId) { + if (paragraph == null) { + return judgementWordsVOS; + } + String name = "【第" + betoLong + "段】"; + String parentId = Convert.getStringRandom(); + // 先查询自身段落数据 + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getSpacing() != null) { + BigInteger before = pPr.getSpacing().getBefore(); + BigInteger after = pPr.getSpacing().getAfter(); + BigInteger line = pPr.getSpacing().getLine(); + String beforeName = "【段落格式(间距)】【段前】"; + if (before != null) { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + beforeName + before, name + beforeName + before, name); + } + String afterName = "【段落格式(间距)】【段后】"; + if (after != null) { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + afterName + after, name + afterName + after, name); + } + String lineName = "【段落格式(间距)】【行距】"; + if (line != null) { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + lineName + line, name + lineName + line, name); + } + String linesName = "【段落格式(间距)】【行距值】"; + if (line != null) { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + linesName + line, name + linesName + line, name); + } + } + if (pPr != null && pPr.getPStyle() != null && stylePart != null) { + String styleId = pPr.getPStyle().getVal(); + Style style = stylePart.getStyleById(styleId); + if (style != null && style.getPPr() != null && style.getPPr().getSpacing() != null) { + PPrBase.Spacing spacing = style.getPPr().getSpacing(); + BigInteger before = spacing.getBefore(); + BigInteger after = spacing.getAfter(); + BigInteger line = spacing.getLine(); + String beforeName = "【段落格式(间距)】【段前】"; + if (before != null) { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + beforeName + before, name + beforeName + before, name); + } + String afterName = "【段落格式(间距)】【段后】"; + if (after != null) { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + afterName + after, name + afterName + after, name); + } + String lineName = "【段落格式(间距)】【行距】"; + if (line != null) { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + lineName + line, name + lineName + line, name); + } + String linesName = "【段落格式(间距)】【行距值】"; + if (line != null) { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + linesName + line, name + linesName + line, name); + } + } + } + return judgementWordsVOS; + } + // 段落-编号列表 + public static List getParagraphList(P paragraph, NumberingDefinitionsPart ndp, List judgementWordsVOS, int betoLong, String firstId) { + if (paragraph == null) { + return judgementWordsVOS; + } + String name = "【第" + betoLong + "段】"; + String parentId = Convert.getStringRandom(); + // 先查询自身段落数据 + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getNumPr() != null && pPr.getNumPr().getNumId() != null) { + PPrBase.NumPr numPr = pPr.getNumPr(); + BigInteger numId = numPr.getNumId() != null ? numPr.getNumId().getVal() : null; + BigInteger ilvl = numPr.getIlvl() != null ? numPr.getIlvl().getVal() : null; + String trueName = "【编号列表】【应用编号列表】存在"; + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + trueName, name + trueName, name); + String jiBieName = "【编号列表】【列表级别】" + (ilvl != null ? ilvl.intValue() : "未知"); + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + jiBieName, name + jiBieName, name); + if (numId != null && ndp != null) { + Numbering.Num num = ndp.getJaxbElement().getNum().stream() + .filter(n -> n.getNumId().equals(numId)) + .findFirst().orElse(null); + + if (num != null) { + BigInteger abstractNumId = num.getAbstractNumId().getVal(); + Numbering.AbstractNum absNum = Convert.getAbstractNumById(ndp, abstractNumId); + + if (absNum != null && ilvl != null) { + Lvl lvl = absNum.getLvl().stream() + .filter(l -> l.getIlvl().equals(ilvl)) + .findFirst().orElse(null); + + if (lvl != null) { + String bianHaoYangShiName = "【编号列表】【编号样式】" + lvl.getNumFmt().getVal(); + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + bianHaoYangShiName, name + bianHaoYangShiName, name); + String bianHaoGeShiName = "【编号列表】【编号格式】" + lvl.getLvlText().getVal(); + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + bianHaoGeShiName, name + bianHaoGeShiName, name); + if ("bullet".equals(lvl.getNumFmt().getVal().value())) { + String xiangMuFuHaoName = "【编号列表】【项目符号】" + lvl.getLvlText().getVal(); + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + xiangMuFuHaoName, name + xiangMuFuHaoName, name); + String lieBiaoName = "【编号列表】【列表类型】无序列表"; + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + lieBiaoName, name + lieBiaoName, name); + + } else { + String lieBiaoName = "【编号列表】【列表类型】有序列表"; + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + lieBiaoName, name + lieBiaoName, name); + + } + } + } + } + } + } + return judgementWordsVOS; + } + // 段落-边框 +// public static List getParagraphBorder(P paragraph, StyleDefinitionsPart stylePart, List judgementWordsVOS, int betoLong, String firstId) { +// if (paragraph == null) { +// return judgementWordsVOS; +// } +// String name = "【第" + betoLong + "段】"; +// String parentId = Convert.getStringRandom(); +// // 先查询自身段落数据 +// PPr pPr = paragraph.getPPr(); +// if (pPr != null && pPr.getPBdr() != null) { +// PPrBase.PBdr border = pPr.getPBdr(); +// String topName = "【】【】"; +// Convert.printBorder("上边框", border.getTop()); +// Convert.printBorder("下边框", border.getBottom()); +// Convert.printBorder("左边框", border.getLeft()); +// Convert.printBorder("右边框", border.getRight()); +// Convert.printBorder("内横线", border.getBetween()); +// Convert.printBorder("内竖线", border.getBar()); +// } +// } + + // 段落-底纹 + public static void getParagraphShd(P paragraph, StyleDefinitionsPart stylePart) { + if (paragraph == null) { + return ; + } + // 先查询自身段落数据 + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getShd() != null) { + CTShd shd = pPr.getShd(); + System.out.println("图案样式 (val): " + shd.getVal()); // 如 clear, solid, nil + System.out.println("图案颜色 (color): " + shd.getColor()); // 图案颜色(文字上的线) + System.out.println("填充颜色 (fill): " + shd.getFill()); // 背景色(段落底色) + } + } + // 段落-首字下沉 + public static void getParagraphDropCap(P paragraph, StyleDefinitionsPart stylePart) { + if (paragraph == null) { + return ; + } + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getFramePr() != null) { + CTFramePr framePr = pPr.getFramePr(); + System.out.println("---- 首字下沉 ----"); + System.out.println("存在首字下沉: 是"); + + if (framePr.getDropCap() != null) { + System.out.println("首字位置 (dropCap): " + framePr.getDropCap().value()); // drop | none | margin + } + + if (framePr.getLines() != null) { + System.out.println("下沉行数 (lines): " + framePr.getLines().intValue()); + } + + if (framePr.getHSpace() != null) { + System.out.println("距正文 (hSpace): " + framePr.getHSpace().intValue()); // twips + } + + // 获取首字字体 + String fontName = Convert.getFirstRunFont(paragraph); + if (fontName != null) { + System.out.println("字体: " + fontName); + } + } else { + System.out.println("不存在首字下沉"); + } + } + // 段落-分栏 + public static void getParagraphCols(P paragraph, StyleDefinitionsPart stylePart) { + if (paragraph == null) { + return ; + } + PPr pPr = paragraph.getPPr(); + SectPr sectPr = null; + sectPr = pPr.getSectPr(); + // 优先取段落自身的节属性 + if (pPr != null && pPr.getSectPr() != null) { + sectPr = pPr.getSectPr(); + } + + // 或最后一个段落中会有一个节结束的SectPr + if (sectPr == null && paragraph.getContent().size() > 0) { + Object lastObj = paragraph.getContent().get(paragraph.getContent().size() - 1); + if (lastObj instanceof JAXBElement && ((JAXBElement) lastObj).getValue() instanceof SectPr) { + sectPr = (SectPr) ((JAXBElement) lastObj).getValue(); + } + } + + if (sectPr != null && sectPr.getCols() != null) { + CTColumns cols = sectPr.getCols(); + + System.out.println("---- 分栏信息 ----"); + System.out.println("栏数: " + (cols.getNum() != null ? cols.getNum().intValue() : "未设置")); + System.out.println("是否栏宽相等 (equalWidth): " + (cols.isEqualWidth() ? "是" : "否")); + System.out.println("是否有分隔线 (sep): " + (cols.isSep() ? "是" : "否")); + + if (cols.getCol() != null && !cols.getCol().isEmpty()) { + int index = 1; + for (CTColumn col : cols.getCol()) { + System.out.println("第 " + index + " 栏宽度 (twips): " + col.getW()); + System.out.println("第 " + index + " 栏间距 (twips): " + col.getSpace()); + index++; + } + } + } + } + +} 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 new file mode 100644 index 00000000..90207a55 --- /dev/null +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/paragraph/RunText.java @@ -0,0 +1,170 @@ +package pc.exam.pp.module.judgement.utils.wps_word.docx4j.paragraph; + +import org.docx4j.XmlUtils; +import org.docx4j.openpackaging.parts.WordprocessingML.StyleDefinitionsPart; +import org.docx4j.wml.*; + +import java.math.BigInteger; + +public class RunText { + + // 句子-字体 + public static void getParagraphAlignment(R run, String text) { + if (run == null) { + return ; + } + RPr rPr = run.getRPr(); + String eastAsiaFont = null, asciiFont = null, hAnsiFont = null; + String fontSize = null; + + if (rPr != null) { + // 字体 + if (rPr.getRFonts() != null) { + RFonts fonts = rPr.getRFonts(); + eastAsiaFont = fonts.getEastAsia(); + asciiFont = fonts.getAscii(); + hAnsiFont = fonts.getHAnsi(); + } + // 字号(单位是半磅;20 = 10.0pt) + if (rPr.getSz() != null) { + BigInteger sz = rPr.getSz().getVal(); + fontSize = sz != null ? (sz.intValue() / 2.0) + " pt" : null; + } + } + + System.out.println("文本内容: " + text); + System.out.println("中文字体: " + (eastAsiaFont != null ? eastAsiaFont : "未设置")); + System.out.println("西文字体(ASCII): " + (asciiFont != null ? asciiFont : "未设置")); + System.out.println("西文字体(HAnsi): " + (hAnsiFont != null ? hAnsiFont : "未设置")); + System.out.println("字号: " + (fontSize != null ? fontSize : "未设置")); + System.out.println("--------"); + } + + // 字体-字形 + public static void getParagraphFontStyle(R run, String text) { + RPr rPr = run.getRPr(); + boolean isBold = false; + boolean isItalic = false; + + if (rPr != null) { + isBold = rPr.getB() != null && rPr.getB().isVal(); + isItalic = rPr.getI() != null && rPr.getI().isVal(); + } + + System.out.println("文本: " + text); + if (isBold && isItalic) { + System.out.println("样式: 加粗 + 倾斜"); + } else if (isBold) { + System.out.println("样式: 加粗"); + } else if (isItalic) { + System.out.println("样式: 倾斜"); + } else { + System.out.println("样式: 常规"); + } + System.out.println("--------"); + } + // 字体-所有文字 + public static void getParagraphFontColor(R run, StyleDefinitionsPart stylePart, String text) { + RPr rPr = run.getRPr(); + + String color = "默认"; + String underlineVal = "无"; + String underlineColor = "默认"; + + if (rPr != null) { + if (rPr.getColor() != null && rPr.getColor().getVal() != null) { + color = rPr.getColor().getVal(); // 如 "FF0000" + } + + if (rPr.getU() != null) { + if (rPr.getU().getVal() != null) { + underlineVal = rPr.getU().getVal().value(); // single, double, none 等 + } + if (rPr.getU().getColor() != null) { + underlineColor = rPr.getU().getColor(); // 例如 "0000FF" + } + } + } + + System.out.println("文本: " + text); + System.out.println("字体颜色: " + color); + System.out.println("下划线样式: " + underlineVal); + System.out.println("下划线颜色: " + underlineColor); + System.out.println("--------"); + } + // 字体-效果-删除线 + public static void getParagraphStrike(R run, String text) { + RPr rPr = run.getRPr(); + + boolean isStrike = false; + boolean isDoubleStrike = false; + String verticalAlign = "正常"; + + if (rPr != null) { + isStrike = rPr.getStrike() != null && rPr.getStrike().isVal(); + isDoubleStrike = rPr.getDstrike() != null && rPr.getDstrike().isVal(); + + if (rPr.getVertAlign() != null && rPr.getVertAlign().getVal() != null) { + verticalAlign = rPr.getVertAlign().getVal().value(); // superscript or subscript + } + } + + System.out.println("文本: " + text); + System.out.println("删除线: " + (isStrike ? "有" : "无")); + System.out.println("双删除线: " + (isDoubleStrike ? "有" : "无")); + System.out.println("上下标: " + verticalAlign); // superscript/subscript/normal + System.out.println("--------"); + } + + // 字体-字符间距 + public static void getParagraphFontSpacing(R run, String text) { + RPr rPr = run.getRPr(); + + String scale = "100%"; + String spacing = "0"; + String position = "0"; + String kern = "无"; + String snapToGrid = "否"; + + if (rPr != null) { + if (rPr.getW() != null && rPr.getW().getVal() != null) { + scale = rPr.getW().getVal().toString() + "%"; + } + if (rPr.getSpacing() != null && rPr.getSpacing().getVal() != null) { + spacing = rPr.getSpacing().getVal().toString() + " twips"; + } + if (rPr.getPosition() != null && rPr.getPosition().getVal() != null) { + position = rPr.getPosition().getVal().toString() + " pt(1/2)"; + } + if (rPr.getKern() != null && rPr.getKern().getVal() != null) { + kern = rPr.getKern().getVal().toString() + " (1/100 pt)"; + } + if (rPr.getSnapToGrid() != null) { + snapToGrid = rPr.getSnapToGrid().isVal() ? "是" : "否"; + } + } + + System.out.println("文本: " + text); + System.out.println("缩放比例: " + scale); + System.out.println("字符间距: " + spacing); + System.out.println("字符位置: " + position); + System.out.println("最小间距 (Kern): " + kern); + System.out.println("对齐到网格: " + snapToGrid); + System.out.println("--------"); + } + // 字体-文本效果 + public static void getParagraphTextEffect(R run, String text) { + + // 转换为 XML 文本 + String runXml = XmlUtils.marshaltoString(run, true); + System.out.println("文本: " + text); + + // 检测特效 + System.out.println("文本填充 (textFill): " + (runXml.contains("w14:textFill") ? "是" : "否")); + System.out.println("文本轮廓 (textOutline): " + (runXml.contains("w14:textOutline") ? "是" : "否")); + System.out.println("阴影 (shadow): " + (runXml.contains("w14:shadow") ? "是" : "否")); + System.out.println("倒影 (reflection): " + (runXml.contains("w14:reflection") ? "是" : "否")); + System.out.println("发光 (glow): " + (runXml.contains("w14:glow") ? "是" : "否")); + System.out.println("--------"); + } +} diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/section/SectionPage.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/section/SectionPage.java new file mode 100644 index 00000000..424f996a --- /dev/null +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/section/SectionPage.java @@ -0,0 +1,309 @@ +package pc.exam.pp.module.judgement.utils.wps_word.docx4j.section; + +import jakarta.xml.bind.JAXBElement; +import org.docx4j.XmlUtils; +import org.docx4j.model.structure.HeaderFooterPolicy; +import org.docx4j.model.structure.SectionWrapper; +import org.docx4j.openpackaging.packages.WordprocessingMLPackage; +import org.docx4j.openpackaging.parts.WordprocessingML.FooterPart; +import org.docx4j.openpackaging.parts.WordprocessingML.HeaderPart; +import org.docx4j.wml.*; + + +import java.util.List; + +/** + * @author REN + */ +public class SectionPage { + + // 节-上下左右设置页边距 + public static void getSectionPageSettings(P paragraph) { + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getSectPr() != null) { + SectPr sectPr = pPr.getSectPr(); + SectPr.PgMar pgMar = sectPr.getPgMar(); + + if (pgMar != null) { + System.out.println("---- 节页面设置 ----"); + System.out.println("上边距 (twips): " + pgMar.getTop()); + System.out.println("下边距 (twips): " + pgMar.getBottom()); + System.out.println("左边距 (twips): " + pgMar.getLeft()); + System.out.println("右边距 (twips): " + pgMar.getRight()); + System.out.println("装订线宽度 (twips): " + pgMar.getGutter()); + System.out.println("-------------------"); + } + } + } + // 纸张方向 大小 + public static void getSectionPageSize(P paragraph) { + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getSectPr() != null) { + SectPr sectPr = pPr.getSectPr(); + SectPr.PgSz pgSz = sectPr.getPgSz(); + + if (pgSz != null) { + System.out.println("---- 节页面大小设置 ----"); + + // 页面宽度 & 高度(单位是 twips:1/20 pt) + System.out.println("页面宽度 (twips): " + pgSz.getW()); + System.out.println("页面高度 (twips): " + pgSz.getH()); + double widthMM = twipToMM(Integer.parseInt(pgSz.getW().toString())); + double heightMM = twipToMM(Integer.parseInt(pgSz.getH().toString())); + + // 保留一位小数误差范围 + double w = Math.min(widthMM, heightMM); + double h = Math.max(widthMM, heightMM); + String pageSize = ""; + if (Math.abs(w - 210) < 5 && Math.abs(h - 297) < 5) { + pageSize = "A4"; + } + if (Math.abs(w - 297) < 5 && Math.abs(h - 420) < 5) { + pageSize = "A3"; + } + if (Math.abs(w - 216) < 5 && Math.abs(h - 279) < 5) { + pageSize = "Letter"; + } + if (Math.abs(w - 216) < 5 && Math.abs(h - 356) < 5) { + pageSize = "Legal"; + } + if (Math.abs(w - 176) < 5 && Math.abs(h - 250) < 5) { + pageSize = "B5"; + } + if (Math.abs(w - 184) < 5 && Math.abs(h - 267) < 5) { + pageSize = "Executive"; + } + System.out.println("纸型: " + pageSize); + // 页面方向 + STPageOrientation orientation = pgSz.getOrient(); + if (orientation != null) { + System.out.println("纸张方向: " + ("landscape".equals(orientation.value()) ? "横向" : "纵向")); + } else { + System.out.println("纸张方向: 默认纵向"); + } + + System.out.println("----------------------"); + } + } + } + public static double twipToMM(int twips) { + return twips * 0.0176389; + } + // 水印 + public static void getSectionPageWatermark(R run) { + // 检查是否包含 Drawing(图片水印) + if (XmlUtils.marshaltoString(run, true).contains(" sections, WordprocessingMLPackage wordMLPackage) { + for (int i = 0; i < sections.size(); i++) { + org.docx4j.model.structure.SectionWrapper section = sections.get(i); + HeaderFooterPolicy hfp = section.getHeaderFooterPolicy(); + System.out.println("📄 节 " + (i + 1)); + + if (hfp.getDefaultHeader() != null) { + System.out.println("【默认/奇数页 页眉】"); + extractTextFromHeader(hfp.getDefaultHeader(), wordMLPackage); + } + + if (hfp.getEvenHeader() != null) { + System.out.println("【偶数页 页眉】"); + extractTextFromHeader(hfp.getEvenHeader(), wordMLPackage); + } + + if (hfp.getFirstHeader() != null) { + System.out.println("【首页 页眉】"); + extractTextFromHeader(hfp.getFirstHeader(), wordMLPackage); + } + + System.out.println("----------------------------"); + } + } + + // 页脚 + public static void getSectionPageFooter(List sections, WordprocessingMLPackage wordMLPackage) { + for (int i = 0; i < sections.size(); i++) { + SectionWrapper section = sections.get(i); + HeaderFooterPolicy hfp = section.getHeaderFooterPolicy(); + System.out.println("📄 节 " + (i + 1)); + + if (hfp.getDefaultFooter() != null) { + System.out.println("【默认/奇数页 页脚】"); + extractTextFromFooter(hfp.getDefaultFooter(), wordMLPackage); + } + + if (hfp.getEvenFooter() != null) { + System.out.println("【偶数页 页脚】"); + extractTextFromFooter(hfp.getEvenFooter(), wordMLPackage); + } + + if (hfp.getFirstFooter() != null) { + System.out.println("【首页 页脚】"); + extractTextFromFooter(hfp.getFirstFooter(), wordMLPackage); + } + + System.out.println("----------------------------"); + } + } + + public static void extractTextFromHeader(HeaderPart headerPart, WordprocessingMLPackage wordMLPackage) { + List contents = headerPart.getContent(); + for (Object obj : contents) { + if (obj instanceof P) { + P paragraph = (P) obj; + StringBuilder text = new StringBuilder(); + String font = null; + Double fontSizePt = null; + String colorHex = null; + String alignment = null; + + // 获取对齐方式 + if (paragraph.getPPr() != null && paragraph.getPPr().getJc() != null) { + alignment = paragraph.getPPr().getJc().getVal().value(); + } + + // 获取文本与样式 + for (Object o : paragraph.getContent()) { + if (o instanceof R) { + R run = (R) o; + + // 样式信息 + RPr rPr = run.getRPr(); + if (rPr != null) { + if (rPr.getRFonts() != null) { + font = rPr.getRFonts().getAscii(); + } + if (rPr.getSz() != null) { + fontSizePt = rPr.getSz().getVal().intValue() / 2.0; + } + if (rPr.getColor() != null) { + colorHex = rPr.getColor().getVal(); + } + } + + // 文本信息 + for (Object rContent : run.getContent()) { + Object val = (rContent instanceof JAXBElement) + ? ((JAXBElement) rContent).getValue() + : rContent; + + if (val instanceof Text) { + text.append(((Text) val).getValue()); + } + } + } + } + + // 输出页眉段落信息 + if (text.length() > 0) { + System.out.println("页眉文本: " + text); + System.out.println("字体: " + font); + System.out.println("字号: " + fontSizePt + " pt"); + System.out.println("颜色: " + colorHex); + System.out.println("对齐方式: " + alignment); + } + } + } + + // 提取页边距(节属性中的 header/left/right) + SectPr sectPr = wordMLPackage.getMainDocumentPart().getJaxbElement().getBody().getSectPr(); + if (sectPr != null && sectPr.getPgMar() != null) { + SectPr.PgMar pgMar = sectPr.getPgMar(); + if (pgMar.getHeader() != null) { + System.out.println("页眉距顶端: " + (pgMar.getHeader().intValue() / 20.0) + " pt"); + } + if (pgMar.getLeft() != null) { + System.out.println("左边距: " + (pgMar.getLeft().intValue() / 20.0) + " pt"); + } + if (pgMar.getRight() != null) { + System.out.println("右边距: " + (pgMar.getRight().intValue() / 20.0) + " pt"); + } + } + } + + public static void extractTextFromFooter(FooterPart footerPart, WordprocessingMLPackage wordMLPackage) { + List contents = footerPart.getContent(); + for (Object obj : contents) { + if (obj instanceof P) { + P paragraph = (P) obj; + StringBuilder text = new StringBuilder(); + String font = null; + Double fontSizePt = null; + String colorHex = null; + String alignment = null; + + // 获取对齐方式 + if (paragraph.getPPr() != null && paragraph.getPPr().getJc() != null) { + alignment = paragraph.getPPr().getJc().getVal().value(); + } + + // 遍历 run 内容 + for (Object o : paragraph.getContent()) { + if (o instanceof R) { + R run = (R) o; + + // 获取样式 + RPr rPr = run.getRPr(); + if (rPr != null) { + if (rPr.getRFonts() != null) { + font = rPr.getRFonts().getAscii(); + } + if (rPr.getSz() != null) { + fontSizePt = rPr.getSz().getVal().intValue() / 2.0; + } + if (rPr.getColor() != null) { + colorHex = rPr.getColor().getVal(); + } + } + + // 提取文本 + for (Object rContent : run.getContent()) { + Object val = rContent instanceof JAXBElement ? ((JAXBElement) rContent).getValue() : rContent; + if (val instanceof Text) { + text.append(((Text) val).getValue()); + } + } + } + } + + // 打印段落信息 + if (text.length() > 0) { + System.out.println("页脚文本: " + text); + System.out.println("字体: " + font); + System.out.println("字号: " + fontSizePt + " pt"); + System.out.println("颜色: " + colorHex); + System.out.println("对齐方式: " + alignment); + } + } + } + + // 获取 section 页边距信息 + SectPr sectPr = wordMLPackage.getMainDocumentPart().getJaxbElement().getBody().getSectPr(); + if (sectPr != null && sectPr.getPgMar() != null) { + SectPr.PgMar pgMar = sectPr.getPgMar(); + if (pgMar.getFooter() != null) { + System.out.println("页脚距底端: " + (pgMar.getFooter().intValue() / 20.0) + " pt"); + } + if (pgMar.getLeft() != null) { + System.out.println("左边距: " + (pgMar.getLeft().intValue() / 20.0) + " pt"); + } + if (pgMar.getRight() != null) { + System.out.println("右边距: " + (pgMar.getRight().intValue() / 20.0) + " pt"); + } + } + } + + +} diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/vo/JudgementWordsVO.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/vo/JudgementWordsVO.java new file mode 100644 index 00000000..b65478f3 --- /dev/null +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/vo/JudgementWordsVO.java @@ -0,0 +1,25 @@ +package pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo; + +import lombok.Data; + +/** + * @author REN + */ +@Data +public class JudgementWordsVO { + + // 名称(相当于类型) + private String name; + + // 考点 + private String content; + + // 考点名称 + private String contentIn; + + // 父节点 + private String parentId; + + // 节点id + private String id; +} diff --git a/pom.xml b/pom.xml index 5d0f016b..ac98fdb0 100644 --- a/pom.xml +++ b/pom.xml @@ -141,32 +141,32 @@ - - huaweicloud - huawei - https://mirrors.huaweicloud.com/repository/maven/ - - - aliyunmaven - aliyun - https://maven.aliyun.com/repository/public - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - false - - + + + + + + + + + + + + + + + + + + + + + + + + + + maven-central Maven Central Repository