【新增】 docx4j获取docx考点
This commit is contained in:
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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
|
||||
|
@@ -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文件路径
|
||||
|
@@ -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
|
||||
|
@@ -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();
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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 "无";
|
||||
}
|
||||
}
|
||||
}
|
@@ -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) {
|
||||
|
@@ -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 "水平(默认)";
|
||||
}
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user