diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/AutoWps/AutoWpsController.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/AutoWps/AutoWpsController.java new file mode 100644 index 00000000..28ec342e --- /dev/null +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/AutoWps/AutoWpsController.java @@ -0,0 +1,63 @@ +package pc.exam.pp.module.judgement.controller.admin.AutoWps; + +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import pc.exam.pp.framework.common.pojo.CommonResult; +import pc.exam.pp.module.judgement.controller.admin.AutoWps.vo.WpsDocxInfoVo; +import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsPptxJudgementDto; +import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsWordJudgementDto; +import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsWordReqDto; +import pc.exam.pp.module.judgement.service.wps_excel.JudgementWpsExcelService; +import pc.exam.pp.module.judgement.service.wps_pptx.JudgementWpsPptxService; +import pc.exam.pp.module.judgement.service.wps_word.JudgementWpsWordService; +import pc.exam.pp.module.judgement.utils.wps_pptx.judgementVO.JudgementReqVo; +import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxInfoReqVo; +import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.JudgementWordsVO; +import pc.exam.pp.module.judgement.utils.wps_word.vo.WordInfoReqVo; + +import java.util.List; + +/** + * wps word + * rwb + * @author REN + */ + +@RestController +@RequestMapping("/auto/wps") +@Tag( name = "测试判分2 - wps相关操作") +@Validated +public class AutoWpsController { + + @Resource + JudgementWpsWordService judgementWpsWordService; + @Resource + JudgementWpsPptxService judgementWpsPptxService; + @Resource + JudgementWpsExcelService judgementWpsExcelService; + + + /** + * 获取指定考点的数据 + * @param wpsDocxInfoVos + * @return + * @throws Exception + */ + @PostMapping("/docxMaster") + public CommonResult> docxMaster(@RequestBody List wpsDocxInfoVos) throws Exception { + return CommonResult.success(judgementWpsWordService.docxMaster(wpsDocxInfoVos)); + } + + /** + * wps word + * @return 获取大类 + */ + @GetMapping("/runWpsWord") + public CommonResult> runWpsWord(String path) throws Exception { + return CommonResult.success(judgementWpsWordService.programmingWpsWord(path)); + } + + +} diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/AutoWps/vo/WpsDocxInfoVo.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/AutoWps/vo/WpsDocxInfoVo.java new file mode 100644 index 00000000..5967e596 --- /dev/null +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/AutoWps/vo/WpsDocxInfoVo.java @@ -0,0 +1,25 @@ +package pc.exam.pp.module.judgement.controller.admin.AutoWps.vo; + +import lombok.Data; + +@Data +public class WpsDocxInfoVo { + + // 大类名称 + private String firstName; + + // 序号 + private String index; + + // 方法名称 + private String function; + + // 考点名称 + private String examName; + + // 考点代码 + private String examCode; + + // 文件路径 理论上都是一样的 + private String filePath; +} 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 42a2fa5c..3468cebf 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 @@ -6,6 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import pc.exam.pp.framework.common.pojo.CommonResult; +import pc.exam.pp.module.judgement.controller.admin.AutoWps.vo.WpsDocxInfoVo; import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsPptxJudgementDto; import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsWordJudgementDto; import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsWordReqDto; @@ -22,6 +23,7 @@ import pc.exam.pp.module.judgement.utils.wps_pptx.judgementVO.JudgementReqVo; import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxInfoPointsVo; import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxInfoReqVo; import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxVO; +import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.JudgementWordsVO; import pc.exam.pp.module.judgement.utils.wps_word.vo.WordInfoReqVo; import pc.exam.pp.module.judgement.utils.wps_word.vo.WordVO; @@ -45,10 +47,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(""); + + + @PostMapping("/docxMaster") + public CommonResult> docxMaster(@RequestBody List wpsDocxInfoVos) throws Exception { + return CommonResult.success(judgementWpsWordService.docxMaster(wpsDocxInfoVos)); } /** * wps word 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 ed630418..ae8a1cd3 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 @@ -3,9 +3,11 @@ package pc.exam.pp.module.judgement.service.wps_word; import pc.exam.pp.module.exam.dal.dataobject.ExamQuestion; +import pc.exam.pp.module.judgement.controller.admin.AutoWps.vo.WpsDocxInfoVo; import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsWordJudgementDto; import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsWordReqDto; import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText; +import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.JudgementWordsVO; import pc.exam.pp.module.judgement.utils.wps_word.vo.WordInfoReqVo; import pc.exam.pp.module.judgement.utils.wps_word.vo.WordVO; @@ -19,7 +21,7 @@ import java.util.List; */ public interface JudgementWpsWordService { - void docxMaster(String path) throws Exception; + List docxMaster(List wpsDocxInfoVos) 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 b3a63de8..8778abd2 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 @@ -9,6 +9,7 @@ import pc.exam.pp.module.exam.dal.dataobject.ExamQuestionAnswer; import pc.exam.pp.module.exam.utils.file.LogFileUtils; import pc.exam.pp.module.infra.dal.dataobject.config.ConfigDO; import pc.exam.pp.module.infra.service.config.ConfigService; +import pc.exam.pp.module.judgement.controller.admin.AutoWps.vo.WpsDocxInfoVo; import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsWordChineseFunctionDto; import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsWordJudgementDto; import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsWordReqDto; @@ -20,6 +21,7 @@ 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.docx4j.vo.JudgementWordsVO; 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; @@ -49,8 +51,13 @@ public class JudgementWpsWordServiceImpl implements JudgementWpsWordService { private AdminUserService userService; @Override - public void docxMaster(String path) throws Exception { - DocxMaster.docxMaster(path); + public List docxMaster(List wpsDocxInfoVos) throws Exception { +// String pathName = ""; +// ConfigDO config = configService.getConfigByKey("file_down_wps_word_path"); +// AdminUserDO user = userService.getUser(getLoginUserId()); +// // 2、下载文件并返回文件完整路径 +// pathName = autoToolsService.downloadStudentFile(path, config.getValue() + "\\" + user.getId()); + return DocxMaster.docxMaster(wpsDocxInfoVos); } @Override 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 index 2f31a0d3..e8054b16 100644 --- 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 @@ -1,22 +1,39 @@ package pc.exam.pp.module.judgement.utils.wps_word.docx4j; import jakarta.xml.bind.JAXBElement; +import jakarta.xml.bind.JAXBException; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.openxml4j.opc.ZipPackage; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlException; import org.docx4j.XmlUtils; -import org.docx4j.model.structure.HeaderFooterPolicy; +import org.docx4j.com.microsoft.schemas.office.word.x2010.wordprocessingShape.CTWordprocessingShape; +import org.docx4j.dml.CTBlipFillProperties; +import org.docx4j.dml.CTStretchInfoProperties; +import org.docx4j.mce.AlternateContent; import org.docx4j.model.structure.SectionWrapper; +import org.docx4j.dml.wordprocessingDrawing.Anchor; 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.w14.CTWordContentPart; import org.docx4j.wml.*; +import org.w3c.dom.Node; +import pc.exam.pp.module.judgement.controller.admin.AutoWps.vo.WpsDocxInfoVo; 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.text.TextInfo; import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.JudgementWordsVO; import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; @@ -26,63 +43,202 @@ import java.util.List; */ public class DocxMaster { - public static void docxMaster(String path) throws Docx4JException { + public static List docxMaster(List wpsDocxInfoVos) throws Docx4JException, InvalidFormatException, IOException, JAXBException, XmlException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { + + // 一共分为 段落, 页面,图形 + String firstDuanLuoId = Convert.getStringRandom(); + String firstYeMianId = Convert.getStringRandom(); + String firstTuXingId = Convert.getStringRandom(); - // 一共分为 段落 - // 创建考点数组 List judgementWordsVOS = new ArrayList<>(); + // 1、获取想要判断的文件地址 + String path = wpsDocxInfoVos.get(0).getFilePath(); + // 2、Docx转换对象 WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new File(path)); List paragraphs = wordMLPackage.getMainDocumentPart().getContent(); + // 2-1、样式对象 StyleDefinitionsPart stylePart = wordMLPackage.getMainDocumentPart().getStyleDefinitionsPart(); + // 2-2、编号对象 NumberingDefinitionsPart ndp = wordMLPackage.getMainDocumentPart().getNumberingDefinitionsPart(); + // 2-3、节对象 List sections = wordMLPackage.getDocumentModel().getSections(); + for (WpsDocxInfoVo wpsDocxInfoVo : wpsDocxInfoVos) { + // 参数实例化 + // 大类名称 + String firstName = wpsDocxInfoVo.getFirstName(); + // 序号 + String indexParm = wpsDocxInfoVo.getIndex(); + // 方法名称 + String function = wpsDocxInfoVo.getFunction(); + // 考点名称 + String examName = wpsDocxInfoVo.getExamName(); + // 考点代码 + String examCode = wpsDocxInfoVo.getExamCode(); - 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; + // 创建一个索引ID,跟参数中index进行匹配 + int index = 0; + for (Object obj : paragraphs) { + index ++; + Object realObj = XmlUtils.unwrap(obj); + if (realObj instanceof P) { + P paragraph = (P) realObj; + PPr pPr = paragraph.getPPr(); + if (pPr == null || pPr.getSectPr() == null) { + // 开始查询段落的属性,非句子的属性 + if (index == Integer.parseInt(indexParm)) { + // 查询出具体想要查询哪个段落的数据 + // 目标对象 + Paragraphs paragraphsFunction = new Paragraphs(); + // 参数类型列表(按方法声明顺序) + Class[] paramTypes = {P.class, StyleDefinitionsPart.class}; + // 带参数的方法调用示例 + Method methodWithArgs = paragraphsFunction.getClass().getMethod(function, paramTypes); + // 实际参数值 + Object[] arguments = {paragraph, stylePart}; + String value = (String) methodWithArgs.invoke(obj, arguments); + judgementWordsVOS = setJudgementWord(judgementWordsVOS, examCode + "@" + value, firstName + examName + value); } - // 句子-字体 - RunText.getParagraphAlignment(run, text); } } } } - SectionPage.getSectionPageHeader(sections, wordMLPackage); - SectionPage.getSectionPageFooter(sections, wordMLPackage); + + + +// // 创建考点数组 +// +// +// +// +// +// +// +// judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, firstDuanLuoId, "0", "段落", "段落", "段落"); +// +// 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(firstDuanLuoId); +// 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); +// } +// } +// } +// } +// for (Object para : paragraphs) { +// if (para instanceof P) { +// P p = (P) para; +// for (Object content : p.getContent()) { +// if (content instanceof R) { +// R run = (R) content; +// for (Object runContent : run.getContent()) { +// // 直接是Drawing对象的情况 +// if (runContent instanceof AlternateContent) { +// AlternateContent alternateContent = (AlternateContent) runContent; +// Object alternateContents = alternateContent.getChoice().get(0).getAny().get(0); +// if (alternateContents instanceof Drawing) { +// Drawing drawing = (Drawing) alternateContents; +// List anchorsOrInlines = drawing.getAnchorOrInline(); +// if (anchorsOrInlines == null || anchorsOrInlines.isEmpty()) continue; +// Object anchorOrInline = anchorsOrInlines.get(0); +// // 使用docx4j的CTAnchor +// if (anchorOrInline instanceof Anchor) { +// Anchor anchor = (Anchor) anchorOrInline; +// // 现在可以安全访问CTAnchor的方法 +// // 区分是图片还是文本框 +// if (anchor.getDocPr().getName().contains("图片")) { +// +// } +// if (anchor.getDocPr().getName().contains("文本框")) { +// // 获取文本框内的文本填充样式 +//// TextInfo.getTextFillFromRun(judgementWordsVOS,run, 1, "1"); +// +// // 文本框属性 +// TextInfo.getTextInfo(judgementWordsVOS,anchor, 1, "1"); +// } +// } +//// System.out.println(anchor.getDocPr().getName()); +// } +// } else if (runContent instanceof JAXBElement) { +// JAXBElement jaxbElement = (JAXBElement) runContent; +// // 检查是否是drawing元素 +// if ("drawing".equals(jaxbElement.getName().getLocalPart())) { +// Object value = jaxbElement.getValue(); +// if (value instanceof Drawing) { +// Drawing drawing = (Drawing) value; +// List anchorsOrInlines = drawing.getAnchorOrInline(); +// if (anchorsOrInlines == null || anchorsOrInlines.isEmpty()) continue; +// Object anchorOrInline = anchorsOrInlines.get(0); +// // 使用docx4j的CTAnchor +// if (anchorOrInline instanceof Anchor) { +// Anchor anchor = (Anchor) anchorOrInline; +// // 现在可以安全访问CTAnchor的方法 +// // 区分是图片还是文本框 +// if (anchor.getDocPr().getName().contains("图片")) { +// +// } +// if (anchor.getDocPr().getName().contains("文本框")) { +// +// } +// } +// +// } +// } +// } +// } +// } +// } +// } +// } +// SectionPage.getSectionPageHeader(sections, wordMLPackage); +// SectionPage.getSectionPageFooter(sections, wordMLPackage); + + + + return judgementWordsVOS; } + private static List setJudgementWord(List judgementWordsVOList, String content, String contentIn) { + JudgementWordsVO judgementWordsVO = new JudgementWordsVO(); + judgementWordsVO.setContent(content); + judgementWordsVO.setContentIn(contentIn); + judgementWordsVOList.add(judgementWordsVO); + return judgementWordsVOList; + } + + // 提取 run 中的文本内容 private static String getRunText(R run) { StringBuilder sb = new StringBuilder(); 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 index 10cf41e5..aeae8c23 100644 --- 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 @@ -10,11 +10,8 @@ import java.util.List; 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/drawing/Drawing.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/drawing/Drawing.java new file mode 100644 index 00000000..0c931d71 --- /dev/null +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/drawing/Drawing.java @@ -0,0 +1,225 @@ +package pc.exam.pp.module.judgement.utils.wps_word.docx4j.drawing; + +import org.docx4j.dml.CTLineProperties; +import org.docx4j.dml.CTOuterShadowEffect; +import org.docx4j.dml.CTShapeProperties; +import org.docx4j.dml.STShapeType; +import org.docx4j.dml.chartDrawing.CTPicture; +import org.docx4j.dml.wordprocessingDrawing.Anchor; +import pc.exam.pp.module.judgement.utils.wps_word.docx4j.DocxSetInfo; +import pc.exam.pp.module.judgement.utils.wps_word.docx4j.paragraph.Convert; +import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.JudgementWordsVO; + +import java.lang.reflect.Method; +import java.util.List; + +public class Drawing { + + // 布局 + public static List getLayout(List judgementWordsVOS, Anchor anchor, int betoLong, String firstId){ + String name = "【第" + betoLong + "个图形】【图片】"; + String parentId = Convert.getStringRandom(); + String parName = "【布局】【锁定横纵比】"; + String layoutHuanRaoName = "【布局】【环绕方式】"; + // 环绕方式 + String layoutHuanRaoValue = anchor.getWrapSquare().getWrapText().value(); + layoutHuanRaoValue = getLayoutHuanRaoName(layoutHuanRaoValue); + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + layoutHuanRaoName + layoutHuanRaoValue, name + layoutHuanRaoName + layoutHuanRaoValue, name); + + // 锁定横纵比 + boolean lock = anchor.getCNvGraphicFramePr().getGraphicFrameLocks().isNoChangeAspect(); + + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + parName + lock, name + parName + lock, name); + + // 高度 + String heightName = "【布局】【高度】"; + String height = anchor.getExtent().getCy() / 360000 + "cm"; + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + heightName + height, name + heightName + height, name); + + // 宽度 + String weightName = "【布局】【宽度】"; + String weight = anchor.getExtent().getCx() / 360000 + "cm"; + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + weightName + weight, name + weightName + weight, name); + + return judgementWordsVOS; + } + + // 形状和样式 + public static List getStyles(List judgementWordsVOS, Anchor anchor, int betoLong, String firstId){ + String name = "【第" + betoLong + "个图形】【图片】"; + String parName = "【形状和样式】【自选图形->形状】"; + CTPicture picture = (CTPicture) anchor.getGraphic().getGraphicData().getAny().get(0); + // 获取形状属性 + CTShapeProperties shapeProps = picture.getSpPr(); + String parentId = Convert.getStringRandom(); + if (shapeProps != null) { + // 获取形状几何属性 + if (shapeProps.getPrstGeom() != null) { + String prst = shapeProps.getPrstGeom().getPrst().value(); + prst = getShapeName(prst); + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + parName + prst, name + parName + prst, name); + } + } + return judgementWordsVOS; + } + + // 形状轮廓 + public static List getShapeProfile(List judgementWordsVOS, Anchor anchor, int betoLong, String firstId){ + String name = "【第" + betoLong + "个图形】【图片】"; + String firstName = "【形状轮廓】"; + String huiZhiName = firstName + "【绘制】"; + String yanSeName = firstName + "【颜色】"; + String kuanDuName = firstName + "【宽度(粗细)】"; + String xianXingName = firstName + "【线型(复合类型)】"; + String xuXianName = firstName + "【虚线(短划线类型)】"; + String touMingName = firstName + "【透明度】"; + String parentId = Convert.getStringRandom(); + CTPicture picture = (CTPicture) anchor.getGraphic().getGraphicData().getAny().get(0); + + // 绘制 + if (picture.getSpPr() == null || picture.getSpPr().getLn() == null) { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + huiZhiName + "是", name + huiZhiName + "是", name); + + // 宽度 + CTLineProperties outline = picture.getSpPr().getLn(); + // 轮廓宽度(以EMU为单位,1厘米=360000 EMU) + long widthEMU = outline.getW(); + String widthValue =widthEMU / 360000.0 +" 厘米"; + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + kuanDuName + widthValue, name + kuanDuName + widthValue, name); + // 颜色 + if (outline.getSolidFill() != null) { + if (outline.getSolidFill().getSrgbClr() != null) { + // RGB颜色 + String colorValue = outline.getSolidFill().getSrgbClr().getVal(); + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + yanSeName + colorValue, name + yanSeName + colorValue, name); + } else if (outline.getSolidFill().getSchemeClr() != null) { + // 主题颜色 + String colorValue = outline.getSolidFill().getSchemeClr().getVal().value(); + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + yanSeName + colorValue, name + yanSeName + colorValue, name); + } + } + // 轮廓样式 + if (outline.getPrstDash() != null) { + String val = outline.getPrstDash().getVal().value(); + val = getDashStyleName(val); + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + xianXingName + val, name + xianXingName + val, name); + } + } else { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + huiZhiName + "否", name + huiZhiName + "否", name); + } + return judgementWordsVOS; + } + + // 形状效果(阴影) + public static List getShapeYinYing(List judgementWordsVOS, Anchor anchor, int betoLong, String firstId){ + String name = "【第" + betoLong + "个图形】【图片】"; + String firstName = "【形状效果(阴影)】"; + String huiZhiName = firstName + "【绘制】"; + String yanSeName = firstName + "【颜色】"; + String touMingDuName = firstName + "【透明度】"; + String daXiaoName = firstName + "【大小】"; + String moHuName = firstName + "【模糊】"; + String parentId = Convert.getStringRandom(); + CTPicture picture = (CTPicture) anchor.getGraphic().getGraphicData().getAny().get(0); + if (picture.getSpPr() == null || picture.getSpPr().getEffectLst() == null) { + // 没有设置效果 + CTOuterShadowEffect shadow = picture.getSpPr().getEffectLst().getOuterShdw(); + if (shadow == null) { + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + huiZhiName + "否", name + huiZhiName + "否", name); + } + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + huiZhiName + "是", name + huiZhiName + "是", name); + if (shadow.getPrstClr() != null) { + String colorVal = shadow.getPrstClr().getVal().value(); + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + yanSeName + colorVal, name + yanSeName + colorVal, name); + + // 尝试通过颜色变换获取透明度 + try { + Object egColorTransform = shadow.getPrstClr().getEGColorTransform(); + if (egColorTransform != null) { + // 使用反射检查是否存在alpha属性 + Method getAlphaMethod = egColorTransform.getClass().getMethod("getAlpha"); + if (getAlphaMethod != null) { + Object alpha = getAlphaMethod.invoke(egColorTransform); + if (alpha != null) { + String value = alpha.toString(); + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + touMingDuName + value, name + touMingDuName + value, name); + } + } + } + } catch (Exception e) { + System.out.println("无法获取透明度信息"); + } + } else if (shadow.getSrgbClr() != null) { + String colorVal = shadow.getSrgbClr().getVal(); + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + yanSeName + colorVal, name + yanSeName + colorVal, name); + // 尝试通过颜色变换获取透明度 + try { + Object egColorTransform = shadow.getPrstClr().getEGColorTransform(); + if (egColorTransform != null) { + // 使用反射检查是否存在alpha属性 + Method getAlphaMethod = egColorTransform.getClass().getMethod("getAlpha"); + if (getAlphaMethod != null) { + Object alpha = getAlphaMethod.invoke(egColorTransform); + if (alpha != null) { + String value = alpha.toString(); + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + touMingDuName + value, name + touMingDuName + value, name); + } + } + } + } catch (Exception e) { + System.out.println("无法获取透明度信息"); + } + } + System.out.printf("模糊半径: %.2f cm\n", shadow.getBlurRad()/360000.0); + System.out.printf("阴影距离: %.2f cm\n", shadow.getDist()/360000.0); + System.out.printf("阴影方向: %.1f°\n", shadow.getDir()/60000.0); + System.out.printf("水平缩放: %.1f%%\n", shadow.getSx()/1000.0); + System.out.printf("垂直缩放: %.1f%%\n", shadow.getSy()/1000.0); + System.out.printf("水平倾斜: %.1f°\n", shadow.getKx()/60000.0); + System.out.printf("垂直倾斜: %.1f°\n", shadow.getKy()/60000.0); + } + return judgementWordsVOS; + } + + + private static String getShapeName(String shapeType) { + switch (shapeType) { + case "rect": return "矩形"; + case "roundRect": return "圆角矩形"; + case "ellipse": return "椭圆/圆形"; + case "triangle": return "三角形"; + case "diamond": return "菱形"; + case "hexagon": return "六边形"; + case "cloud": return "云形"; + case "star": return "星形"; + default: return shapeType; + } + } + + private static String getDashStyleName(String val) { + switch(val) { + case "solid": return "实线"; + case "dot": return "点线"; + case "dash": return "虚线"; + case "lgDash": return "长虚线"; + case "dashDot": return "点划线"; + case "lgDashDot": return "长点划线"; + case "sysDash": return "系统虚线"; + case "sysDot": return "系统点线"; + case "sysDashDot": return "系统点划线"; + default: return val; + } + } + + private static String getLayoutHuanRaoName(String wrapText) { + if (wrapText == null) return "两侧"; + + switch (wrapText) { + case "bothSides": return "两侧"; + case "left": return "只在左侧"; + case "right": return "只在右侧"; + case "largest": return "最大边"; + default: return "无"; + } + } +} 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 27e324dc..693886d3 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 @@ -18,108 +18,51 @@ 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; - } + public static String getParagraphAlignment(P paragraph, StyleDefinitionsPart stylePart) { // 先查段落自身 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); - } + return Convert.convertJc(pPr.getJc().getVal().value()); } // 若段落未定义对齐方式,则尝试从样式中继承 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 Convert.convertJc(style.getPPr().getJc().getVal().value()); } } // 都没有设置,返回默认 - return judgementWordsVOS; + return ""; } // 段落-大纲级别 - 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(); + public static String getParagraphOutlineLvl(P paragraph, StyleDefinitionsPart stylePart) { // 先查询自身段落数据 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); - } + return Convert.convertOutlineLvl(pPr.getOutlineLvl().getVal().toString()); } // 没有设置,从公共方法中获取参数 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 Convert.convertJc(style.getPPr().getOutlineLvl().getVal().toString()); } } - return judgementWordsVOS; + return ""; } - // 段落-缩进 - 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(); - // 先查询自身段落数据 + /// 段落格式(缩进) 左缩进 磅 + public static String getParagraphIndLeft(P paragraph, StyleDefinitionsPart stylePart) { 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); - } + return ind.getLeft().intValue() + " 磅"; } } if (pPr != null && pPr.getPStyle() != null && stylePart != null) { @@ -128,95 +71,225 @@ public class Paragraphs { 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 indStyle.getLeft().intValue() + " 磅"; } } } - return judgementWordsVOS; + return ""; } - // 段落-间距 - public static List getParagraphSpacing(P paragraph, StyleDefinitionsPart stylePart, List judgementWordsVOS, int betoLong, String firstId) { - if (paragraph == null) { - return judgementWordsVOS; + /// 段落格式(缩进) 右缩进 磅 + public static String getParagraphIndRight(P paragraph, StyleDefinitionsPart stylePart) { + PPr pPr = paragraph.getPPr(); + PPrBase.Ind ind = pPr.getInd(); + if (ind != null) { + if (ind.getRight() != null) { + return ind.getRight().intValue() + " 磅"; + } } - String name = "【第" + betoLong + "段】"; - String parentId = Convert.getStringRandom(); - // 先查询自身段落数据 + 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.getRight() != null) { + return indStyle.getRight().intValue() + " 磅"; + } + } + } + return ""; + } + /// 段落格式(缩进) 首行缩进 磅 + public static String getParagraphIndFirstLine(P paragraph, StyleDefinitionsPart stylePart) { + PPr pPr = paragraph.getPPr(); + PPrBase.Ind ind = pPr.getInd(); + if (ind != null) { + if (ind.getFirstLine() != null) { + return ind.getFirstLine().intValue() + " 磅"; + } + } + 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.getFirstLine() != null) { + return indStyle.getFirstLine().intValue() + " 磅"; + } + } + } + return ""; + } + /// 段落格式(缩进) 悬挂缩进 磅 + public static String getParagraphIndHanging(P paragraph, StyleDefinitionsPart stylePart) { + PPr pPr = paragraph.getPPr(); + PPrBase.Ind ind = pPr.getInd(); + if (ind != null) { + if (ind.getHanging() != null) { + return ind.getHanging().intValue() + " 磅"; + } + } + 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.getHanging() != null) { + return indStyle.getHanging().intValue() + " 磅"; + } + } + } + return ""; + } + + /// 段落格式(间距) 段前 + public static String getParagraphSpacingBefore(P paragraph, StyleDefinitionsPart stylePart) { 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); - } + return pPr.getSpacing().getBefore().toString(); } 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 spacing.getBefore().toString(); + } + } + return ""; + } + /// 段落格式(间距) 段后 + public static String getParagraphSpacingAfter(P paragraph, StyleDefinitionsPart stylePart) { + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getSpacing() != null) { + return pPr.getSpacing().getAfter().toString(); + } + 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(); + return spacing.getAfter().toString(); + } + } + return ""; + } + /// 段落格式(间距) 间距 + public static String getParagraphSpacingLine(P paragraph, StyleDefinitionsPart stylePart) { + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getSpacing() != null) { + return pPr.getSpacing().getLine().toString(); + } + 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(); + return spacing.getLine().toString(); + } + } + return ""; + } + + /// 段落格式(间距) 间距值 + public static String getParagraphSpacingLines(P paragraph, StyleDefinitionsPart stylePart) { + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getSpacing() != null) { + return pPr.getSpacing().getLine().toString(); + } + 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(); + return spacing.getLine().toString(); + } + } + return ""; + } + + /// 段落 编号列表 存在 + public static String getParagraphListIsTrue(P paragraph, NumberingDefinitionsPart ndp) { + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getNumPr() != null && pPr.getNumPr().getNumId() != null) { + return "存在"; + } else { + return "不存在"; + } + } + /// 段落 编号列表 列表级别 + public static String getParagraphListIlvl(P paragraph, NumberingDefinitionsPart ndp) { + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getNumPr() != null && pPr.getNumPr().getNumId() != null) { + PPrBase.NumPr numPr = pPr.getNumPr(); + BigInteger ilvl = numPr.getIlvl() != null ? numPr.getIlvl().getVal() : null; + return (ilvl != null ? String.valueOf(ilvl.intValue()) : "未知"); + } else { + return "未知"; + } + } + /// 段落 编号列表 编号样式 + public static String getParagraphListAbstractNumId(P paragraph, NumberingDefinitionsPart ndp) { + 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; + 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); + BigInteger ilvl = numPr.getIlvl() != null ? numPr.getIlvl().getVal() : null; + if (absNum != null && ilvl != null) { + Lvl lvl = absNum.getLvl().stream() + .filter(l -> l.getIlvl().equals(ilvl)) + .findFirst().orElse(null); + + if (lvl != null) { + return lvl.getNumFmt().getVal().toString(); + + } + } } } } - return judgementWordsVOS; + return "未知"; } + /// 段落 编号列表 编号格式 + public static String getParagraphListLvlText(P paragraph, NumberingDefinitionsPart ndp) { + 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; + 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) { + // 获取对应的编号格式 + return lvl.getLvlText().getVal(); + } + } + } + } + } + return "未知"; + } + /// 段落 编号列表 项目符号 + /// 段落 编号列表 列表类型 + // 段落-编号列表 public static List getParagraphList(P paragraph, NumberingDefinitionsPart ndp, List judgementWordsVOS, int betoLong, String firstId) { if (paragraph == null) { diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/text/TextInfo.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/text/TextInfo.java new file mode 100644 index 00000000..7a4eb5f9 --- /dev/null +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/text/TextInfo.java @@ -0,0 +1,135 @@ +package pc.exam.pp.module.judgement.utils.wps_word.docx4j.text; + +import jakarta.xml.bind.JAXBElement; +import jakarta.xml.bind.JAXBException; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlObject; +import org.docx4j.XmlUtils; +import org.docx4j.com.microsoft.schemas.office.word.x2010.wordprocessingShape.CTWordprocessingShape; +import org.docx4j.dml.wordprocessingDrawing.Anchor; +import org.docx4j.jaxb.Context; +import org.docx4j.wml.CTTextEffect; +import org.docx4j.wml.R; +import org.w3c.dom.Document; +import pc.exam.pp.module.judgement.utils.wps_word.docx4j.DocxSetInfo; +import pc.exam.pp.module.judgement.utils.wps_word.docx4j.paragraph.Convert; +import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.JudgementWordsVO; + +import java.util.List; + +public class TextInfo { + + // 文本内容 + public static List getTextInfo(List judgementWordsVOS, Anchor anchor, int betoLong, String firstId){ + String name = "【第" + betoLong + "个图形】【文本框】"; + String parName = "【文本】"; + String neiRongName = parName + "【文本内容】"; + String fangXiangName = parName + "【文字方向】"; + String parentId = Convert.getStringRandom(); + Object graphicData = anchor.getGraphic().getGraphicData().getAny().get(0); + // 正确处理 JAXBElement + if (graphicData instanceof JAXBElement) { + JAXBElement jaxbElement = (JAXBElement) graphicData; + Object value = jaxbElement.getValue(); + + // 现在可以尝试转换为实际类型 + if (value.getClass().getName().contains("CTWordprocessingShape")) { + if (value instanceof CTWordprocessingShape) { + // 文本内容 + CTWordprocessingShape textInfo = (CTWordprocessingShape) value; + String textValue = textInfo.getTxbx().getTxbxContent().getContent().toString(); + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + neiRongName + textValue, name + neiRongName + textValue, name); + // 文字方向 + String vertValue = textInfo.getBodyPr().getVert().value(); + vertValue = getTextDirection(vertValue); + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + fangXiangName + vertValue, name + fangXiangName + vertValue, name); + String tianChongName = parName + "【填充方式】"; + // 文本填充-填充方式 TODO 存在标签对不上的问题 + if (textInfo.getSpPr().getSolidFill() != null) { + // 纯色填充 + String typeValue = "纯色填充"; + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + tianChongName + typeValue, name + tianChongName + typeValue, name); + + if (textInfo.getSpPr().getSolidFill().getSrgbClr() != null) { + // 纯色填充-颜色 + String color = textInfo.getSpPr().getSolidFill().getSrgbClr().getVal(); + tianChongName = tianChongName + "【颜色】"; + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + tianChongName + color, name + tianChongName + color, name); + } else if (textInfo.getSpPr().getSolidFill().getSchemeClr() != null) { + // 纯色填充-颜色 + String color = textInfo.getSpPr().getSolidFill().getSrgbClr().getVal(); + tianChongName = tianChongName + "【颜色】"; + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + tianChongName + color, name + tianChongName + color, name); + } + } + if (textInfo.getSpPr().getBlipFill() != null) { + // 图片填充 + tianChongName = tianChongName + "图片填充"; + } + if (textInfo.getSpPr().getGradFill() != null) { + // 渐变填充 + tianChongName = tianChongName + "渐变填充"; + } + } + } + if (value.getClass().getName().contains("shadow")) { + System.out.println(11); + System.out.println(11); + } + } + // 属性直接在wp:anchor 下面的 + String layoutHuanRaoName = "【布局】【环绕方式】"; + String layoutHuanRaoValue = anchor.getWrapSquare().getWrapText().value(); + layoutHuanRaoValue = getTextDirection(layoutHuanRaoValue); + judgementWordsVOS = DocxSetInfo.setInfo(judgementWordsVOS, parentId, firstId, name + layoutHuanRaoName + layoutHuanRaoValue, name + layoutHuanRaoName + layoutHuanRaoValue, name); + + + + return judgementWordsVOS; + } + + public static List getTextFillFromRun(List judgementWordsVOS, R run, int betoLong, String firstId) throws JAXBException, XmlException { + String xml = XmlUtils.marshaltoString(run, true); + org.w3c.dom.Node node = Context.jc.createMarshaller().getNode(run); + XmlCursor xmlCursor = XmlObject.Factory.parse(node).newCursor(); + + System.out.println(xmlCursor.xmlText()); + return judgementWordsVOS; + } + + + private static String getWrapTextDescription(String wrapText) { + if (wrapText == null) return "两侧"; + + switch (wrapText) { + case "bothSides": return "两侧"; + case "left": return "只在左侧"; + case "right": return "只在右侧"; + case "largest": return "最大边"; + default: return "无"; + } + } + public static String getTextDirection(String vert) { + if (vert == null) return "水平(默认)"; + + switch (vert) { + case "horz": + return "水平"; + case "vert": + return "垂直"; + case "vert270": + return "垂直(270度)"; + case "eaVert": + return "东亚垂直"; + case "mongolianVert": + return "蒙古文垂直"; + case "wordArtVert": + return "艺术字垂直"; + case "wordArtVertRtl": + return "艺术字垂直(从右到左)"; + default: + return "水平(默认)"; + } + } +} 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 index b65478f3..d26d6794 100644 --- 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 @@ -8,18 +8,10 @@ import lombok.Data; @Data public class JudgementWordsVO { - // 名称(相当于类型) - private String name; - // 考点 private String content; // 考点名称 private String contentIn; - // 父节点 - private String parentId; - - // 节点id - private String id; }