【新增】 pptx验证考点修正

This commit is contained in:
DESKTOP-932OMT8\REN
2025-05-16 13:16:40 +08:00
parent 1bf1367bd6
commit 247f6e4b19
6 changed files with 50 additions and 104 deletions

View File

@@ -17,7 +17,6 @@ public class PptxSaveReqVO {
@Schema(description = "节点名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道") @Schema(description = "节点名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
@NotBlank(message = "节点名称不能为空") @NotBlank(message = "节点名称不能为空")
@Size(max = 30, message = "节点名称长度不能超过 30 个字符")
private String name; private String name;
/** /**
* 类型 * 类型

View File

@@ -17,7 +17,6 @@ public class WordSaveReqVO {
@Schema(description = "节点名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道") @Schema(description = "节点名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
@NotBlank(message = "节点名称不能为空") @NotBlank(message = "节点名称不能为空")
@Size(max = 30, message = "节点名称长度不能超过 30 个字符")
private String name; private String name;
/** /**
* 类型 * 类型

View File

@@ -17,7 +17,6 @@ public class XlsxSaveReqVO {
@Schema(description = "节点名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道") @Schema(description = "节点名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
@NotBlank(message = "节点名称不能为空") @NotBlank(message = "节点名称不能为空")
@Size(max = 30, message = "节点名称长度不能超过 30 个字符")
private String name; private String name;
/** /**
* 类型 * 类型

View File

@@ -38,6 +38,7 @@ public class JudgementWpsPptxServiceImpl implements JudgementWpsPptxService {
String pathName = autoToolsService.downloadStudentFile(path, config.getValue()); String pathName = autoToolsService.downloadStudentFile(path, config.getValue());
// 3、创建pptx考点tree // 3、创建pptx考点tree
PptxListReqVO pptxListReqVO = new PptxListReqVO(); PptxListReqVO pptxListReqVO = new PptxListReqVO();
// 查询形状狭的所有数据
pptxListReqVO.setBelongTo(0); pptxListReqVO.setBelongTo(0);
// 3-1、查询段落的标签 // 3-1、查询段落的标签
List<WpsPptxLinkDO> paragraphList = wpsPptxLinkMapper.selectList(pptxListReqVO); List<WpsPptxLinkDO> paragraphList = wpsPptxLinkMapper.selectList(pptxListReqVO);

View File

@@ -5,18 +5,14 @@ import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlObject;
import pc.exam.pp.module.judgement.dal.dataobject.wpspptx.WpsPptxLinkDO; import pc.exam.pp.module.judgement.dal.dataobject.wpspptx.WpsPptxLinkDO;
import pc.exam.pp.module.judgement.dal.dataobject.wpsword.WpsWordLinkDO;
import pc.exam.pp.module.judgement.utils.tree.TreeUtils; import pc.exam.pp.module.judgement.utils.tree.TreeUtils;
import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxVO; import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxVO;
import pc.exam.pp.module.judgement.utils.wps_word.vo.WordVO;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.IntStream;
/** /**
* @author REN * @author REN
@@ -33,6 +29,7 @@ public class WpsPptxUtils {
int index = 0; int index = 0;
// 获取了所有的幻灯片 // 获取了所有的幻灯片
for (XSLFSlide slides : pptxXml.getSlides()){ for (XSLFSlide slides : pptxXml.getSlides()){
index += 1;
String xmlText = slides.getXmlObject().xmlText(); String xmlText = slides.getXmlObject().xmlText();
// 1-1、创建最全的命名空间 // 1-1、创建最全的命名空间
Pattern pattern = Pattern.compile("xmlns:(\\w+)=\"([^\"]+)\""); Pattern pattern = Pattern.compile("xmlns:(\\w+)=\"([^\"]+)\"");
@@ -55,13 +52,39 @@ public class WpsPptxUtils {
String allPathx = xpathBuilder.toString(); String allPathx = xpathBuilder.toString();
// 3、获取CTDocument对象 // 3、获取CTDocument对象
XmlObject docXml = slides.getXmlObject(); XmlObject docXml = slides.getXmlObject();
// 命名
String typeName = "【第" + index + "页】";
String englishName = "@" + index;
for (WpsPptxLinkDO node : cSldTree) { for (WpsPptxLinkDO node : cSldTree) {
traverseTreeAndQueryXml("111", pptxVOS, node.getName(), "123", allPathx, node, docXml, new ArrayList<>(), new ArrayList<>(), index, 1); // 4、查询形状下的所有数据 先查询有多少个形状
XmlCursor xmlCursor = docXml.newCursor();
xmlCursor.selectPath(allPathx + "//" + node.getName());
System.out.println(xmlCursor.xmlText());
// 获取p:sp形状下的数据
int pIndex = 0;
while (xmlCursor.toNextSelection()) {
pIndex += 1;
for (WpsPptxLinkDO anchor :node.getChildren()) {
String spName = "【第" + pIndex + "个形状】";
String englishSpName = "@" + pIndex;
XmlCursor pXmlCursor = xmlCursor.getObject().newCursor();
String nextString = allPathx + anchor.getName();
pXmlCursor.selectPath(nextString);
while (pXmlCursor.toNextSelection()) {
XmlCursor pXmlCursors = pXmlCursor.getObject().newCursor();
String textValue = pXmlCursors.getTextValue();
PptxVO pptxVO = new PptxVO();
pptxVO.setExamKeynote(englishName + englishSpName + anchor.getName()+ " " + textValue);
pptxVO.setKeynoteChinese(typeName + spName + "" + anchor.getToChinese() + "" + textValue);
pptxVOS.add(pptxVO);
// System.out.println(typeName + spName + "【" + anchor.getToChinese() + "】" + textValue);
}
pXmlCursor.dispose();
}
// traverseTreeAndQueryXml(pptxVOS, typeName + "-第" + pIndex + "个形状", allPathx, node, pXmlObject, new ArrayList<>(), new ArrayList<>(), index, 1);
}
xmlCursor.dispose();
} }
index += 1;
// 2、解析文件内容
XmlObject xml = slides.getXmlObject();
System.out.println(index + "解析pptx文件内容: " + xml.xmlText());
} }
} catch (IOException e) { } catch (IOException e) {
@@ -71,10 +94,8 @@ public class WpsPptxUtils {
} }
/** /**
* @param type String 用来存放类型
* @param pptxVOS List<PptxVO> 用来存放结果 * @param pptxVOS List<PptxVO> 用来存放结果
* @param firstTitle String 用来存放一级标题 * @param firstTitle String 用来存放一级标题
* @param text String 用来存放文本
* @param xpath String 用来存放xpath * @param xpath String 用来存放xpath
* @param node WpsWordLinkDO 用来存放节点 * @param node WpsWordLinkDO 用来存放节点
* @param currentXml XmlObject 用来存放当前xml * @param currentXml XmlObject 用来存放当前xml
@@ -83,100 +104,37 @@ public class WpsPptxUtils {
* @param index int 用来存放索引 * @param index int 用来存放索引
* @param beginIndex int 用来存放开始索引 * @param beginIndex int 用来存放开始索引
*/ */
public static void traverseTreeAndQueryXml(String type, List<PptxVO> pptxVOS, String firstTitle, String text, String xpath, WpsPptxLinkDO node, XmlObject currentXml, List<String> pathSoFar, List<String> pathChinese, int index, int beginIndex) { public static void traverseTreeAndQueryXml(List<PptxVO> pptxVOS, String firstTitle, String xpath, WpsPptxLinkDO node, XmlObject currentXml, List<String> pathSoFar, List<String> pathChinese, int index, int beginIndex) {
// 到达参数节点,构造 XPath 路径查询它的值 // 到达参数节点,构造 XPath 路径查询它的值
if (beginIndex == 1) { if (beginIndex == 1) {
xpath += "./"; xpath += "./";
} }
if (beginIndex > 1) {
pathSoFar.add(node.getName()); pathSoFar.add(node.getName());
pathChinese.add(node.getToChinese() + index); pathChinese.add(node.getToChinese() + index);
}
if (node.getType() == 1) { if (node.getType() == 1 || node.getType() == 2) {
xpath += String.join("/", pathSoFar); xpath += String.join("/", pathSoFar);
try (XmlCursor cursors = currentXml.newCursor()) { try (XmlCursor cursors = currentXml.newCursor()) {
System.out.println(cursors.xmlText());
System.out.println(xpath);
cursors.selectPath(xpath); cursors.selectPath(xpath);
if (cursors.toNextSelection()) { if (cursors.toNextSelection()) {
String textValue = cursors.getTextValue(); String textValue = cursors.getTextValue();
if (!Objects.equals(textValue, "")) {
// 查找List里面是否已经存在相应文本的数据
String finalText = text;
int listIndex = IntStream.range(0, pptxVOS.size())
.filter(i -> finalText.equals(pptxVOS.get(i).getWordText()))
.findFirst()
.orElse(-1);
// 判断在段落内的样式,如果出现样式,向上兼容,直接再出现样式标签
// System.out.println(xpath);
if (xpath.indexOf("w:sectPr") > 0 && xpath.indexOf("w:p[") > 0) {
// 说明出现了文本页面设置,需要进行向上绑定
// 在获取当前的数组长度,获取上面的属性 遍历已经存在的数据
int tindex = 0;
for (PptxVO woVo : pptxVOS) {
// 判断标识是否为false,,代表没有进行赋值
if (!woVo.getIsTrue()) {
PptxVO pptxVO = pptxVOS.get(tindex);
pptxVO.setWordText(pptxVO.getWordText());
woVo.setIsTrue(true);
List<String> kchinese = woVo.getKeynoteChinese();
List<String> examKeynote = woVo.getExamKeynote();
examKeynote.add(String.join("", pathSoFar) + "value" + textValue);
kchinese.add(String.join("", pathChinese) + ",值:" + textValue);
pptxVO.setKeynoteChinese(kchinese);
pptxVO.setExamKeynote(examKeynote);
pptxVO.setType(type);
pptxVOS.set(tindex, woVo);
}
tindex += 1;
}
} else if (listIndex < 0) {
// 如果没有查询到了
if (xpath.indexOf("w:sectPr[") > 0) {
// 页面属性
// 文本
text = "页面属性";
}
if (!Objects.equals(text, "")) {
if (!text.contains("MERGEFIELD")) {
// 给标志符
PptxVO pptxVO = new PptxVO();
pptxVO.setWordText(text);
// 创建list进行存放数据
List<String> kchinese = new ArrayList<>();
List<String> examKeynote = new ArrayList<>();
examKeynote.add(String.join("", pathSoFar) + "value" + textValue);
kchinese.add(String.join("", pathChinese) + ",值:" + textValue);
// 组合完数据后进行存放数据
pptxVO.setKeynoteChinese(kchinese);
pptxVO.setExamKeynote(examKeynote);
pptxVO.setIsTrue(false);
pptxVO.setType(type);
pptxVOS.add(pptxVO);
}
}
} else { // 如果找到了
PptxVO pptxVO = pptxVOS.get(listIndex);
List<String> kchinese = pptxVO.getKeynoteChinese();
List<String> examKeynote = pptxVO.getExamKeynote();
examKeynote.add(String.join("", pathSoFar) + "value" + textValue);
kchinese.add(String.join("", pathChinese) + ",值:" + textValue);
pptxVO.setKeynoteChinese(kchinese);
pptxVO.setExamKeynote(examKeynote);
pptxVO.setIsTrue(false);
pptxVO.setType(type);
pptxVOS.remove(listIndex);
pptxVOS.add(pptxVO);
}
// System.out.println("文本:" + text + " 参数路径:" + String.join(" → ", pathChinese) + ",值:" + text_value);
}
cursors.dispose(); cursors.dispose();
} }
} }
} else { } else {
for (WpsPptxLinkDO child : node.getChildren()) { for (WpsPptxLinkDO child : node.getChildren()) {
traverseTreeAndQueryXml(type, pptxVOS, firstTitle, text, xpath, child, currentXml, new ArrayList<>(pathSoFar), new ArrayList<>(pathChinese), index,2); traverseTreeAndQueryXml(pptxVOS, firstTitle, xpath, child, currentXml, new ArrayList<>(pathSoFar), new ArrayList<>(pathChinese), index,2);
} }
} }
if (!pathSoFar.isEmpty()) {
pathSoFar.remove(pathSoFar.size() - 1); pathSoFar.remove(pathSoFar.size() - 1);
pathChinese.remove(pathChinese.size() - 1); pathChinese.remove(pathChinese.size() - 1);
} }
}
} }

View File

@@ -8,19 +8,9 @@ import java.util.List;
@Data @Data
public class PptxVO { public class PptxVO {
@Schema(description = "相关文本")
private String wordText;
@Schema(description = "考试考点") @Schema(description = "考试考点")
private List<String> examKeynote; private String examKeynote;
@Schema(description = "考点汉化") @Schema(description = "考点汉化")
private List<String> keynoteChinese; private String keynoteChinese;
@Schema(description = "是否有样式修饰")
private Boolean isTrue;
@Schema(description = "类型")
private String type;
} }