【新增】 pptx验证考点修正
This commit is contained in:
@@ -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;
|
||||||
/**
|
/**
|
||||||
* 类型
|
* 类型
|
||||||
|
@@ -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;
|
||||||
/**
|
/**
|
||||||
* 类型
|
* 类型
|
||||||
|
@@ -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;
|
||||||
/**
|
/**
|
||||||
* 类型
|
* 类型
|
||||||
|
@@ -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);
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user