【新增】 docx4j获取docx考点

This commit is contained in:
MSI\letre
2025-07-08 14:47:29 +08:00
parent 0fa5df7a46
commit bf2863f425
11 changed files with 878 additions and 200 deletions

View File

@@ -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<List<JudgementWordsVO>> docxMaster(@RequestBody List<WpsDocxInfoVo> wpsDocxInfoVos) throws Exception {
return CommonResult.success(judgementWpsWordService.docxMaster(wpsDocxInfoVos));
}
/**
* wps word
* @return 获取大类
*/
@GetMapping("/runWpsWord")
public CommonResult<List<WordInfoReqVo>> runWpsWord(String path) throws Exception {
return CommonResult.success(judgementWpsWordService.programmingWpsWord(path));
}
}

View File

@@ -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;
}

View File

@@ -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<String> docxMaster() throws Exception {
judgementWpsWordService.docxMaster("D:\\Project\\Exam\\Software\\Temp\\1.docx");
return CommonResult.success("");
@PostMapping("/docxMaster")
public CommonResult<List<JudgementWordsVO>> docxMaster(@RequestBody List<WpsDocxInfoVo> wpsDocxInfoVos) throws Exception {
return CommonResult.success(judgementWpsWordService.docxMaster(wpsDocxInfoVos));
}
/**
* wps word

View File

@@ -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<JudgementWordsVO> docxMaster(List<WpsDocxInfoVo> wpsDocxInfoVos) throws Exception;
/**
* 获取word文件内得考点及描述
* @param path minio文件路径

View File

@@ -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<JudgementWordsVO> docxMaster(List<WpsDocxInfoVo> 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

View File

@@ -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<JudgementWordsVO> docxMaster(List<WpsDocxInfoVo> wpsDocxInfoVos) throws Docx4JException, InvalidFormatException, IOException, JAXBException, XmlException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
// 一共分为 段落, 页面,图形
String firstDuanLuoId = Convert.getStringRandom();
String firstYeMianId = Convert.getStringRandom();
String firstTuXingId = Convert.getStringRandom();
// 一共分为 段落
// 创建考点数组
List<JudgementWordsVO> judgementWordsVOS = new ArrayList<>();
// 1、获取想要判断的文件地址
String path = wpsDocxInfoVos.get(0).getFilePath();
// 2、Docx转换对象
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new File(path));
List<Object> paragraphs = wordMLPackage.getMainDocumentPart().getContent();
// 2-1、样式对象
StyleDefinitionsPart stylePart = wordMLPackage.getMainDocumentPart().getStyleDefinitionsPart();
// 2-2、编号对象
NumberingDefinitionsPart ndp = wordMLPackage.getMainDocumentPart().getNumberingDefinitionsPart();
// 2-3、节对象
List<SectionWrapper> 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<Object> 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<Object> 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<Object> 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<Object> 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<JudgementWordsVO> setJudgementWord(List<JudgementWordsVO> 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();

View File

@@ -10,11 +10,8 @@ import java.util.List;
public class DocxSetInfo {
public static List<JudgementWordsVO> setInfo(List<JudgementWordsVO> 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;
}

View File

@@ -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<JudgementWordsVO> getLayout(List<JudgementWordsVO> 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<JudgementWordsVO> getStyles(List<JudgementWordsVO> 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<JudgementWordsVO> getShapeProfile(List<JudgementWordsVO> 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<JudgementWordsVO> getShapeYinYing(List<JudgementWordsVO> 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 "";
}
}
}

View File

@@ -18,108 +18,51 @@ public class Paragraphs {
* 段落-对齐方式
* @param paragraph
* @param stylePart
* @param judgementWordsVOS
* @param betoLong
* @param firstId
* @return
*/
public static List<JudgementWordsVO> getParagraphAlignment(P paragraph, StyleDefinitionsPart stylePart, List<JudgementWordsVO> 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<JudgementWordsVO> getParagraphOutlineLvl(P paragraph, StyleDefinitionsPart stylePart, List<JudgementWordsVO> 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<JudgementWordsVO> getParagraphIndent(P paragraph, StyleDefinitionsPart stylePart, List<JudgementWordsVO> 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<JudgementWordsVO> getParagraphSpacing(P paragraph, StyleDefinitionsPart stylePart, List<JudgementWordsVO> 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<JudgementWordsVO> getParagraphList(P paragraph, NumberingDefinitionsPart ndp, List<JudgementWordsVO> judgementWordsVOS, int betoLong, String firstId) {
if (paragraph == null) {

View File

@@ -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<JudgementWordsVO> getTextInfo(List<JudgementWordsVO> 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<JudgementWordsVO> getTextFillFromRun(List<JudgementWordsVO> 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 "水平(默认)";
}
}
}

View File

@@ -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;
}