【新增】 涵盖PPT部分考点(存在考点待开发)
This commit is contained in:
@@ -92,26 +92,27 @@ public class AutoWpsController {
|
||||
);
|
||||
return CommonResult.success(judgementWpsWordService.docxMaster(wpsDocxInfoVos, file));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定考点的数据
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
// @PostMapping(value = "/slideMaster", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
@PostMapping(value = "/slideMaster")
|
||||
public CommonResult<List<JudgementSlidesVO>> slideMaster(@RequestBody List<WpsSlideInfoVo> wpsSlideInfoVos) throws Exception {
|
||||
// public CommonResult<List<JudgementSlidesVO>> slideMaster(@RequestPart("data") String jsonData, @RequestPart("file") MultipartFile file) throws Exception {
|
||||
// 手动解析JSON数组
|
||||
// ObjectMapper objectMapper = new ObjectMapper();
|
||||
// List<WpsSlideInfoVo> wpsSlideInfoVos = objectMapper.readValue(
|
||||
// jsonData,
|
||||
// new TypeReference<List<WpsSlideInfoVo>>() {
|
||||
// }
|
||||
// );
|
||||
MultipartFile file = null;
|
||||
@PostMapping(value = "/slideMaster", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
// @PostMapping(value = "/slideMaster")
|
||||
// public CommonResult<List<JudgementSlidesVO>> slideMaster(@RequestBody List<WpsSlideInfoVo> wpsSlideInfoVos) throws Exception {
|
||||
public CommonResult<List<JudgementSlidesVO>> slideMaster(@RequestPart("data") String jsonData, @RequestPart("file") MultipartFile file) throws Exception {
|
||||
// 手动解析JSON数组
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
List<WpsSlideInfoVo> wpsSlideInfoVos = objectMapper.readValue(
|
||||
jsonData,
|
||||
new TypeReference<List<WpsSlideInfoVo>>() {
|
||||
}
|
||||
);
|
||||
return CommonResult.success(judgementWpsPptxService.slideMaster(wpsSlideInfoVos, file));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定考点的数据
|
||||
*
|
||||
@@ -119,17 +120,16 @@ public class AutoWpsController {
|
||||
* @throws Exception
|
||||
*/
|
||||
@PostMapping(value = "/xlsxMaster", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
public CommonResult<List<JudgementXlsxVO>> xlsxMaster(@RequestPart("data") String jsonData, @RequestPart("file") MultipartFile file,@RequestParam(value = "cell", required = false) List<String> cell) throws Exception {
|
||||
public CommonResult<List<JudgementXlsxVO>> xlsxMaster(@RequestPart("data") String jsonData, @RequestPart("file") MultipartFile file, @RequestParam(value = "cell", required = false) List<String> cell) throws Exception {
|
||||
// 手动解析JSON数组
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
List<WpsXlsxInfoVo> wpsXlsxInfoVos= objectMapper.readValue(
|
||||
List<WpsXlsxInfoVo> wpsXlsxInfoVos = objectMapper.readValue(
|
||||
jsonData,
|
||||
new TypeReference<List<WpsXlsxInfoVo>>() {
|
||||
}
|
||||
);
|
||||
return CommonResult.success(judgementWpsExcelService.xlsxMaster(wpsXlsxInfoVos, file,cell));
|
||||
return CommonResult.success(judgementWpsExcelService.xlsxMaster(wpsXlsxInfoVos, file, cell));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -7,12 +7,6 @@ public class WpsSlideInfoVo {
|
||||
// 幻灯片位置(第几张幻灯片)
|
||||
private String slideIndex;
|
||||
|
||||
// 形状位置,只有在shape 形状(不包含图片) shapePic 形状图片
|
||||
private String shapeIndex;
|
||||
|
||||
// 形状类型 slide 幻灯片设置 shape 形状(不包含图片) shapePic 形状图片 presentation 总幻灯片设置
|
||||
private String type;
|
||||
|
||||
// 大类名称
|
||||
private String firstName;
|
||||
|
||||
@@ -25,6 +19,6 @@ public class WpsSlideInfoVo {
|
||||
// 考点代码
|
||||
private String examCode;
|
||||
|
||||
// 方式方法
|
||||
// 形状类型 slide 幻灯片设置 shape 形状(不包含图片) shapePic 形状图片 presentation 总幻灯片设置
|
||||
private String method;
|
||||
}
|
||||
|
||||
@@ -2,15 +2,11 @@ package pc.exam.pp.module.judgement.utils.wps_pptx.pptx4j;
|
||||
|
||||
import jakarta.xml.bind.JAXBElement;
|
||||
import jakarta.xml.bind.JAXBException;
|
||||
import org.apache.poi.sl.usermodel.TextParagraph;
|
||||
import org.docx4j.dml.*;
|
||||
import org.docx4j.jaxb.XPathBinderAssociationIsPartialException;
|
||||
import org.docx4j.openpackaging.parts.PresentationML.SlidePart;
|
||||
import org.pptx4j.pml.*;
|
||||
import org.pptx4j.model.*;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
public class ShapePage {
|
||||
|
||||
@@ -419,7 +415,260 @@ public class ShapePage {
|
||||
|
||||
|
||||
// 动画 效果
|
||||
public static String getAnimation(org.pptx4j.pml.Shape sp, CTSlideTiming timing) throws JAXBException, XPathBinderAssociationIsPartialException {
|
||||
// public static String getAnimation(org.pptx4j.pml.Shape sp, CTSlideTiming timing) throws JAXBException, XPathBinderAssociationIsPartialException {
|
||||
// // 获取形状中的ID
|
||||
// if (sp == null) return "无动画";
|
||||
// long spId = sp.getNvSpPr().getCNvPr().getId();
|
||||
// // 获取动画效果
|
||||
// CTTimeNodeList timeNodeList = timing.getTnLst();
|
||||
// for (Object obj : timeNodeList.getParOrSeqOrExcl()) {
|
||||
// if (obj instanceof CTTLTimeNodeParallel) {
|
||||
// CTTLTimeNodeParallel par = (CTTLTimeNodeParallel) obj;
|
||||
// CTTLCommonTimeNodeData node = par.getCTn();
|
||||
// if (node.getChildTnLst().getParOrSeqOrExcl() != null) {
|
||||
// CTTimeNodeList childTimeNodeList = node.getChildTnLst();
|
||||
// for (Object object : childTimeNodeList.getParOrSeqOrExcl()) {
|
||||
// if (object instanceof CTTLSetBehavior) {
|
||||
// if (((CTTLSetBehavior) object).getCBhvr() != null) {
|
||||
// if (((CTTLSetBehavior) object).getCBhvr().getTgtEl().getSpTgt() != null) {
|
||||
// // 检查目标形状ID是否匹配
|
||||
// if (((CTTLSetBehavior) object).getCBhvr().getTgtEl().getSpTgt().getSpid().equals(String.valueOf(spId))) {
|
||||
// // 返回动画效果
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (object instanceof CTTLTimeNodeSequence) {
|
||||
// CTTLTimeNodeSequence seq = (CTTLTimeNodeSequence) object;
|
||||
// CTTimeNodeList seqNodeList = seq.getCTn().getChildTnLst();
|
||||
// for (Object seqObjs : seqNodeList.getParOrSeqOrExcl()) {
|
||||
// if (seqObjs instanceof CTTLSetBehavior) {
|
||||
// if (((CTTLSetBehavior) seqObjs).getCBhvr() != null) {
|
||||
// if (((CTTLSetBehavior) seqObjs).getCBhvr().getTgtEl().getSpTgt() != null) {
|
||||
// // 检查目标形状ID是否匹配
|
||||
// if (((CTTLSetBehavior) seqObjs).getCBhvr().getTgtEl().getSpTgt().getSpid().equals(String.valueOf(spId))) {
|
||||
// // 返回动画效果
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (seqObjs instanceof CTTLTimeNodeSequence) {
|
||||
// CTTLTimeNodeSequence seqObj = (CTTLTimeNodeSequence) seqObjs;
|
||||
// CTTimeNodeList seqNodeLists = seqObj.getCTn().getChildTnLst();
|
||||
// for (Object seqObjss : seqNodeLists.getParOrSeqOrExcl()) {
|
||||
// if (seqObjss instanceof CTTLSetBehavior) {
|
||||
// if (((CTTLSetBehavior) seqObjss).getCBhvr() != null) {
|
||||
// if (((CTTLSetBehavior) seqObjss).getCBhvr().getTgtEl().getSpTgt() != null) {
|
||||
// // 检查目标形状ID是否匹配
|
||||
// if (((CTTLSetBehavior) seqObjss).getCBhvr().getTgtEl().getSpTgt().getSpid().equals(String.valueOf(spId))) {
|
||||
// // 返回动画效果
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// if (node.getDur() != null && !"indefinite".equals(node.getDur())) {
|
||||
// return node.getDur();
|
||||
// }
|
||||
// System.out.println(par.getCTn());
|
||||
// }
|
||||
// }
|
||||
// return "待开发";
|
||||
// }
|
||||
|
||||
public static String getAnimation(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
|
||||
if (sp == null || timing == null || timing.getTnLst() == null) return "无动画";
|
||||
final String spId = String.valueOf(sp.getNvSpPr().getCNvPr().getId());
|
||||
CTTimeNodeList root = timing.getTnLst();
|
||||
|
||||
// 先找进入类(effect)
|
||||
String entrance = findFirstBehavior(root, spId, /*preferEntrance=*/true);
|
||||
if (entrance != null) return entrance;
|
||||
|
||||
// 再找其它类型(包括 CTTLAnimateBehavior 的 ppt_x/ppt_y)
|
||||
String any = findFirstBehavior(root, spId, /*preferEntrance=*/false);
|
||||
return any != null ? any : "无动画";
|
||||
}
|
||||
|
||||
/* 递归遍历所有 time nodes,返回首个命中的行为字符串 */
|
||||
private static String findFirstBehavior(CTTimeNodeList list, String spId, boolean preferEntrance) {
|
||||
if (list == null || list.getParOrSeqOrExcl() == null) return null;
|
||||
|
||||
for (Object raw : list.getParOrSeqOrExcl()) {
|
||||
Object node = unwrap(raw);
|
||||
|
||||
// 1) 直接是某种行为(Behavior)
|
||||
String desc = tryDescribeIfBehavior(node, spId, preferEntrance);
|
||||
if (desc != null) return desc;
|
||||
|
||||
// 2) par / seq / excl,进入子列表递归
|
||||
CTTimeNodeList child = getChildList(node);
|
||||
if (child != null) {
|
||||
String got = findFirstBehavior(child, spId, preferEntrance);
|
||||
if (got != null) return got;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* 如果对象是某种 Behavior,且目标命中当前 spId,则返回描述;否则返回 null */
|
||||
private static String tryDescribeIfBehavior(Object obj, String spId, boolean preferEntrance) {
|
||||
// 统一 unwrap
|
||||
obj = unwrap(obj);
|
||||
|
||||
// --- 进入类效果(Effect)---
|
||||
if (obj instanceof CTTLAnimateEffectBehavior) {
|
||||
CTTLAnimateEffectBehavior b = (CTTLAnimateEffectBehavior) obj;
|
||||
if (isTarget(b.getCBhvr(), spId)) {
|
||||
String filter = safe(b.getFilter()); // 如 "fade"、"strips(downRight)" 等
|
||||
return filter.isEmpty() ? "进入效果" : ("进入效果:" + filter);
|
||||
}
|
||||
}
|
||||
|
||||
// 非优先阶段:其它类型
|
||||
if (!preferEntrance) {
|
||||
// 通用 Animate (B 动画关键:ppt_x / ppt_y)
|
||||
if (obj instanceof CTTLAnimateBehavior) {
|
||||
CTTLAnimateBehavior b = (CTTLAnimateBehavior) obj;
|
||||
if (isTarget(b.getCBhvr(), spId)) {
|
||||
String attr = firstAttrName(b.getCBhvr());
|
||||
if ("ppt_x".equalsIgnoreCase(attr)) return "位置动画:X(ppt_x)";
|
||||
if ("ppt_y".equalsIgnoreCase(attr)) return "位置动画:Y(ppt_y)";
|
||||
return attr.isEmpty() ? "数值动画(Animate)" : ("数值动画(" + attr + ")");
|
||||
}
|
||||
}
|
||||
if (obj instanceof CTTLAnimateMotionBehavior) {
|
||||
CTTLAnimateMotionBehavior b = (CTTLAnimateMotionBehavior) obj;
|
||||
if (isTarget(b.getCBhvr(), spId)) return "路径动画(Motion)";
|
||||
}
|
||||
if (obj instanceof CTTLAnimateRotationBehavior) {
|
||||
CTTLAnimateRotationBehavior b = (CTTLAnimateRotationBehavior) obj;
|
||||
if (isTarget(b.getCBhvr(), spId)) return "旋转动画";
|
||||
}
|
||||
if (obj instanceof CTTLAnimateScaleBehavior) {
|
||||
CTTLAnimateScaleBehavior b = (CTTLAnimateScaleBehavior) obj;
|
||||
if (isTarget(b.getCBhvr(), spId)) return "缩放动画";
|
||||
}
|
||||
if (obj instanceof CTTLSetBehavior) {
|
||||
CTTLSetBehavior b = (CTTLSetBehavior) obj;
|
||||
if (isTarget(b.getCBhvr(), spId)) {
|
||||
String to = (b.getTo()!=null && b.getTo().getStrVal()!=null) ? safe(b.getTo().getStrVal().getVal()) : "";
|
||||
String attr = firstAttrName(b.getCBhvr());
|
||||
if (!attr.isEmpty() || !to.isEmpty()) {
|
||||
return "属性设置(Set):" + (attr.isEmpty() ? "" : attr) + (to.isEmpty() ? "" : (" -> " + to));
|
||||
}
|
||||
return "属性设置(Set)";
|
||||
}
|
||||
}
|
||||
if (obj instanceof CTTLAnimateColorBehavior) {
|
||||
CTTLAnimateColorBehavior b = (CTTLAnimateColorBehavior) obj;
|
||||
if (isTarget(b.getCBhvr(), spId)) return "颜色动画";
|
||||
}
|
||||
if (obj instanceof CTTLCommandBehavior) {
|
||||
CTTLCommandBehavior b = (CTTLCommandBehavior) obj;
|
||||
if (isTarget(b.getCBhvr(), spId)) return "命令动画(Command)";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* 提取并返回子节点列表(par/seq/excl 三种) */
|
||||
private static CTTimeNodeList getChildList(Object node) {
|
||||
node = unwrap(node);
|
||||
if (node instanceof CTTLTimeNodeParallel) {
|
||||
CTTLTimeNodeParallel n = (CTTLTimeNodeParallel) node;
|
||||
return n.getCTn() != null ? n.getCTn().getChildTnLst() : null;
|
||||
}
|
||||
if (node instanceof CTTLTimeNodeSequence) {
|
||||
CTTLTimeNodeSequence n = (CTTLTimeNodeSequence) node;
|
||||
return n.getCTn() != null ? n.getCTn().getChildTnLst() : null;
|
||||
}
|
||||
if (node instanceof CTTLTimeNodeExclusive) {
|
||||
CTTLTimeNodeExclusive n = (CTTLTimeNodeExclusive) node;
|
||||
return n.getCTn() != null ? n.getCTn().getChildTnLst() : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* 判断行为的目标是否命中当前形状 spId */
|
||||
private static boolean isTarget(CTTLCommonBehaviorData cb, String spId) {
|
||||
if (cb == null || cb.getTgtEl() == null || cb.getTgtEl().getSpTgt() == null) return false;
|
||||
String tgt = cb.getTgtEl().getSpTgt().getSpid();
|
||||
return String.valueOf(spId).equals(tgt);
|
||||
}
|
||||
|
||||
/* 读第一个 attrName(如 ppt_x / ppt_y / style.visibility ...)*/
|
||||
private static String firstAttrName(CTTLCommonBehaviorData cb) {
|
||||
if (cb == null || cb.getAttrNameLst() == null) return "";
|
||||
java.util.List<String> names = cb.getAttrNameLst().getAttrName();
|
||||
return (names != null && !names.isEmpty()) ? safe(names.get(0)) : "";
|
||||
}
|
||||
|
||||
/* 统一解包 JAXBElement */
|
||||
private static Object unwrap(Object o) {
|
||||
return (o instanceof JAXBElement) ? ((JAXBElement<?>) o).getValue() : o;
|
||||
}
|
||||
|
||||
/* 安全字符串 */
|
||||
private static String safe(String s) {
|
||||
return s == null ? "" : s.trim();
|
||||
}
|
||||
|
||||
|
||||
// 动画-方向
|
||||
public static String getAnimateDirection(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
|
||||
String dir = getAnimation(sp, timing);
|
||||
if (dir.equals("downRight")) {
|
||||
return "右下";
|
||||
}
|
||||
if (dir.equals("downLeft")) {
|
||||
return "左下";
|
||||
}
|
||||
if (dir.equals("upRight")) {
|
||||
return "右上";
|
||||
}
|
||||
if (dir.equals("upLeft")) {
|
||||
return "左上";
|
||||
}
|
||||
if (dir.equals("right")) {
|
||||
return "向右";
|
||||
}
|
||||
if (dir.equals("left")) {
|
||||
return "向左";
|
||||
}
|
||||
if (dir.equals("down")) {
|
||||
return "向下";
|
||||
}
|
||||
if (dir.equals("up")) {
|
||||
return "向上";
|
||||
}
|
||||
if (dir.equals("fromTop")) {
|
||||
return "从顶部";
|
||||
}
|
||||
if (dir.equals("fromBottom")) {
|
||||
return "从底部";
|
||||
}
|
||||
if (dir.equals("fromLeft")) {
|
||||
return "从左侧";
|
||||
}
|
||||
if (dir.equals("fromRight")) {
|
||||
return "从右侧";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// 动画 触发方式
|
||||
public static String getAnimateTrigger(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
|
||||
// 获取形状中的ID
|
||||
if (sp == null) return "无动画";
|
||||
long spId = sp.getNvSpPr().getCNvPr().getId();
|
||||
@@ -429,27 +678,189 @@ public class ShapePage {
|
||||
if (obj instanceof CTTLTimeNodeParallel) {
|
||||
CTTLTimeNodeParallel par = (CTTLTimeNodeParallel) obj;
|
||||
CTTLCommonTimeNodeData node = par.getCTn();
|
||||
if (node.getDur() != null && !"indefinite".equals(node.getDur())) {
|
||||
return node.getDur();
|
||||
}
|
||||
// 情况2:检查子节点
|
||||
// if (node.getChildTnLst() != null) {
|
||||
// for (Object child : node.getChildTnLst().getParOrSeqOrExcl()) {
|
||||
// if (child instanceof CTTLTimeNodeParallel) {
|
||||
// String duration = getRealDuration(((CTTLTimeNodeParallel)child).getCTn());
|
||||
// if (duration != null) return duration;
|
||||
// }
|
||||
// else if (child instanceof CTTLAnimateEffectBehavior) {
|
||||
// return ((CTTLAnimateEffectBehavior)child).getDur();
|
||||
// }
|
||||
// // 其他类型处理...
|
||||
// }
|
||||
// }
|
||||
System.out.println(par.getCTn());
|
||||
if (node.getChildTnLst().getParOrSeqOrExcl() != null) {
|
||||
CTTimeNodeList childTimeNodeList = node.getChildTnLst();
|
||||
for (Object object : childTimeNodeList.getParOrSeqOrExcl()) {
|
||||
if (object instanceof CTTLTimeNodeSequence) {
|
||||
CTTLTimeNodeSequence seq = (CTTLTimeNodeSequence) object;
|
||||
if (seq.getCTn().getStCondLst() != null) {
|
||||
CTTLTimeConditionList stCondLst = seq.getCTn().getStCondLst();
|
||||
for (CTTLTimeCondition o : stCondLst.getCond()) {
|
||||
if (o.getEvt() != null) {
|
||||
return o.getEvt().value();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CTTimeNodeList seqNodeList = seq.getCTn().getChildTnLst();
|
||||
for (Object seqObj : seqNodeList.getParOrSeqOrExcl()) {
|
||||
if (seqObj instanceof CTTLTimeNodeSequence) {
|
||||
CTTLTimeNodeSequence seqs = (CTTLTimeNodeSequence) seqObj;
|
||||
if (seqs.getCTn().getStCondLst() != null) {
|
||||
CTTLTimeConditionList stCondLst = seqs.getCTn().getStCondLst();
|
||||
for (CTTLTimeCondition o : stCondLst.getCond()) {
|
||||
if (o.getEvt() != null) {
|
||||
return o.getEvt().value();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CTTimeNodeList seqNodeLists = seqs.getCTn().getChildTnLst();
|
||||
for (Object seqObjs : seqNodeLists.getParOrSeqOrExcl()) {
|
||||
if (seqObjs instanceof CTTLTimeNodeSequence) {
|
||||
CTTLTimeNodeSequence seqss = (CTTLTimeNodeSequence) seqObjs;
|
||||
if (seqss.getCTn().getStCondLst() != null) {
|
||||
CTTLTimeConditionList stCondLst = seqss.getCTn().getStCondLst();
|
||||
for (CTTLTimeCondition o : stCondLst.getCond()) {
|
||||
if (o.getEvt() != null) {
|
||||
return o.getEvt().value();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (seqObj instanceof CTTLTimeNodeParallel) {
|
||||
CTTLTimeNodeParallel seqs = (CTTLTimeNodeParallel) seqObj;
|
||||
if (seqs.getCTn().getStCondLst() != null) {
|
||||
CTTLTimeConditionList stCondLst = seqs.getCTn().getStCondLst();
|
||||
for (CTTLTimeCondition o : stCondLst.getCond()) {
|
||||
if (o.getEvt() != null) {
|
||||
return o.getEvt().value();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CTTimeNodeList seqNodeLists = seqs.getCTn().getChildTnLst();
|
||||
for (Object seqObjs : seqNodeLists.getParOrSeqOrExcl()) {
|
||||
if (seqObjs instanceof CTTLTimeNodeSequence) {
|
||||
CTTLTimeNodeSequence seqss = (CTTLTimeNodeSequence) seqObjs;
|
||||
if (seqss.getCTn().getStCondLst() != null) {
|
||||
CTTLTimeConditionList stCondLst = seqss.getCTn().getStCondLst();
|
||||
for (CTTLTimeCondition o : stCondLst.getCond()) {
|
||||
if (o.getEvt() != null) {
|
||||
return o.getEvt().value();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "待开发";
|
||||
return "";
|
||||
}
|
||||
// 动画 持续时间
|
||||
public static String getAnimationDuration(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
|
||||
if (sp == null || timing == null || timing.getTnLst() == null) return "无动画";
|
||||
|
||||
final String spId = String.valueOf(sp.getNvSpPr().getCNvPr().getId());
|
||||
CTTimeNodeList root = timing.getTnLst();
|
||||
|
||||
// 先找“进入类效果(effect)”
|
||||
String entrance = findFirstBehavior(root, spId, /*preferEntrance=*/true);
|
||||
if (entrance != null) return entrance;
|
||||
|
||||
// 找不到进入类,再找其它类型(运动、旋转、缩放、Set 等)
|
||||
String any = findFirstBehavior(root, spId, /*preferEntrance=*/false);
|
||||
return any != null ? any : "无动画";
|
||||
}
|
||||
|
||||
// 动画 延迟
|
||||
public static String getAnimationDelay(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
|
||||
// 获取形状中的ID
|
||||
if (sp == null) return "无动画";
|
||||
long spId = sp.getNvSpPr().getCNvPr().getId();
|
||||
// 获取动画效果
|
||||
CTTimeNodeList timeNodeList = timing.getTnLst();
|
||||
for (Object obj : timeNodeList.getParOrSeqOrExcl()) {
|
||||
if (obj instanceof CTTLTimeNodeParallel) {
|
||||
CTTLTimeNodeParallel par = (CTTLTimeNodeParallel) obj;
|
||||
CTTLCommonTimeNodeData node = par.getCTn();
|
||||
if (node.getChildTnLst().getParOrSeqOrExcl() != null) {
|
||||
CTTimeNodeList childTimeNodeList = node.getChildTnLst();
|
||||
for (Object object : childTimeNodeList.getParOrSeqOrExcl()) {
|
||||
if (object instanceof CTTLTimeNodeSequence) {
|
||||
CTTLTimeNodeSequence seq = (CTTLTimeNodeSequence) object;
|
||||
if (seq.getCTn().getStCondLst() != null) {
|
||||
CTTLTimeConditionList stCondLst = seq.getCTn().getStCondLst();
|
||||
for (CTTLTimeCondition o : stCondLst.getCond()) {
|
||||
if (o.getEvt() != null) {
|
||||
return o.getDelay();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CTTimeNodeList seqNodeList = seq.getCTn().getChildTnLst();
|
||||
for (Object seqObj : seqNodeList.getParOrSeqOrExcl()) {
|
||||
if (seqObj instanceof CTTLTimeNodeSequence) {
|
||||
CTTLTimeNodeSequence seqs = (CTTLTimeNodeSequence) seqObj;
|
||||
if (seqs.getCTn().getStCondLst() != null) {
|
||||
CTTLTimeConditionList stCondLst = seqs.getCTn().getStCondLst();
|
||||
for (CTTLTimeCondition o : stCondLst.getCond()) {
|
||||
if (o.getEvt() != null) {
|
||||
return o.getDelay();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CTTimeNodeList seqNodeLists = seqs.getCTn().getChildTnLst();
|
||||
for (Object seqObjs : seqNodeLists.getParOrSeqOrExcl()) {
|
||||
if (seqObjs instanceof CTTLTimeNodeSequence) {
|
||||
CTTLTimeNodeSequence seqss = (CTTLTimeNodeSequence) seqObjs;
|
||||
if (seqss.getCTn().getStCondLst() != null) {
|
||||
CTTLTimeConditionList stCondLst = seqss.getCTn().getStCondLst();
|
||||
for (CTTLTimeCondition o : stCondLst.getCond()) {
|
||||
if (o.getEvt() != null) {
|
||||
return o.getDelay();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (seqObj instanceof CTTLTimeNodeParallel) {
|
||||
CTTLTimeNodeParallel seqs = (CTTLTimeNodeParallel) seqObj;
|
||||
if (seqs.getCTn().getStCondLst() != null) {
|
||||
CTTLTimeConditionList stCondLst = seqs.getCTn().getStCondLst();
|
||||
for (CTTLTimeCondition o : stCondLst.getCond()) {
|
||||
if (o.getEvt() != null) {
|
||||
return o.getDelay();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CTTimeNodeList seqNodeLists = seqs.getCTn().getChildTnLst();
|
||||
for (Object seqObjs : seqNodeLists.getParOrSeqOrExcl()) {
|
||||
if (seqObjs instanceof CTTLTimeNodeSequence) {
|
||||
CTTLTimeNodeSequence seqss = (CTTLTimeNodeSequence) seqObjs;
|
||||
if (seqss.getCTn().getStCondLst() != null) {
|
||||
CTTLTimeConditionList stCondLst = seqss.getCTn().getStCondLst();
|
||||
for (CTTLTimeCondition o : stCondLst.getCond()) {
|
||||
if (o.getEvt() != null) {
|
||||
return o.getDelay();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// 形状动作,鼠标单机-动作
|
||||
|
||||
@@ -1002,7 +1413,6 @@ public class ShapePage {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
/// 文本轮廓 宽度
|
||||
@@ -1052,5 +1462,86 @@ public class ShapePage {
|
||||
return "待开发";
|
||||
}
|
||||
|
||||
// 文字效果 阴影→绘制
|
||||
public static String getTextBoxParagraphShadowDraw(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
|
||||
if (sp.getTxBody() != null) {
|
||||
for (CTTextParagraph paragraph : sp.getTxBody().getP()) {
|
||||
for (Object obj : paragraph.getEGTextRun()) {
|
||||
if (obj instanceof CTRegularTextRun ctRegularTextRun) {
|
||||
CTTextCharacterProperties rPr = ctRegularTextRun.getRPr();
|
||||
CTEffectList ctEffectList = rPr.getEffectLst();
|
||||
if (ctEffectList.getInnerShdw() != null || ctEffectList.getOuterShdw() != null || ctEffectList.getPrstShdw() != null) {
|
||||
return "是";
|
||||
} else {
|
||||
return "否";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
// 文字效果 阴影→预设
|
||||
// 文字效果 阴影→效果
|
||||
public static String getTextBoxParagraphShadowEffect(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
|
||||
return "待开发";
|
||||
}
|
||||
|
||||
// 文字效果 倒影→绘制
|
||||
public static String getTextBoxParagraphReflectionDraw(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
|
||||
if (sp.getTxBody() != null) {
|
||||
for (CTTextParagraph paragraph : sp.getTxBody().getP()) {
|
||||
for (Object obj : paragraph.getEGTextRun()) {
|
||||
if (obj instanceof CTRegularTextRun ctRegularTextRun) {
|
||||
CTTextCharacterProperties rPr = ctRegularTextRun.getRPr();
|
||||
CTEffectList ctEffectList = rPr.getEffectLst();
|
||||
if (ctEffectList != null && ctEffectList.getReflection() != null) {
|
||||
return "是";
|
||||
} else {
|
||||
return "否";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
// 文字效果 倒影→预设
|
||||
// 文字效果 倒影→效果
|
||||
public static String getTextBoxParagraphReflectionEffect(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
|
||||
if (sp.getTxBody() != null) {
|
||||
for (CTTextParagraph paragraph : sp.getTxBody().getP()) {
|
||||
for (Object obj : paragraph.getEGTextRun()) {
|
||||
if (obj instanceof CTRegularTextRun ctRegularTextRun) {
|
||||
CTTextCharacterProperties rPr = ctRegularTextRun.getRPr();
|
||||
CTEffectList ctEffectList = rPr.getEffectLst();
|
||||
CTReflectionEffect ctReflectionEffect = ctEffectList.getReflection();
|
||||
return SlideUtils.getShadowLikeDescription(ctReflectionEffect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
// 文字效果 发光→绘制
|
||||
public static String getTextBoxParagraphGlowDraw(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
|
||||
return "待开发";
|
||||
}
|
||||
// 文字效果 发光→效果
|
||||
public static String getTextBoxParagraphGlowEffect(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
|
||||
return "待开发";
|
||||
}
|
||||
// 文字效果 转换→弯曲
|
||||
public static String getTextBoxParagraphConvertCurve(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
|
||||
return "待开发";
|
||||
}
|
||||
|
||||
// 文字效果 单机鼠标
|
||||
public static String getTextBoxParagraphMouseClick(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
|
||||
System.out.println(timing);
|
||||
return "待开发";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,859 @@
|
||||
package pc.exam.pp.module.judgement.utils.wps_pptx.pptx4j;
|
||||
|
||||
import jakarta.xml.bind.JAXBElement;
|
||||
import org.docx4j.dml.*;
|
||||
import org.pptx4j.pml.*;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class ShapePic {
|
||||
|
||||
// 大小 - 高度
|
||||
public static String getShapeSizeHeight(Pic sp, CTSlideTiming timing) {
|
||||
CTTransform2D xfrm = sp.getSpPr().getXfrm();
|
||||
// 获取位置和尺寸(单位 EMU,1英寸=914400 EMU,1cm≈360000 EMU)
|
||||
CTPositiveSize2D ext = xfrm.getExt(); // 尺寸
|
||||
double heightPt = emuToPt(ext.getCy());
|
||||
return String.valueOf(heightPt);
|
||||
}
|
||||
|
||||
// 大小 - 宽度
|
||||
public static String getShapeSizeWidthPt(Pic sp, CTSlideTiming timing) {
|
||||
CTTransform2D xfrm = sp.getSpPr().getXfrm();
|
||||
// 获取位置和尺寸(单位 EMU,1英寸=914400 EMU,1cm≈360000 EMU)
|
||||
CTPositiveSize2D ext = xfrm.getExt(); // 尺寸
|
||||
double widthPt = emuToPt(ext.getCx());
|
||||
return String.valueOf(widthPt);
|
||||
}
|
||||
|
||||
// 大小 - 锁定纵横比
|
||||
public static String getShapeSizeLockAspectRatio(Pic sp, CTSlideTiming timing) {
|
||||
CTTransform2D xfrm = sp.getSpPr().getXfrm();
|
||||
// 获取位置和尺寸(单位 EMU,1英寸=914400 EMU,1cm≈360000 EMU)
|
||||
CTPositiveSize2D ext = xfrm.getExt(); // 尺寸
|
||||
Boolean lockAspectRatio = null;
|
||||
if (sp.getSpPr().getPrstGeom() != null &&
|
||||
sp.getSpPr().getPrstGeom().getAvLst() != null) {
|
||||
// 这个部分一般不会直接提供锁定横纵比,要看 spPr.getExtLst()
|
||||
if (sp.getSpPr().getExtLst() != null) {
|
||||
// pptx4j 没有直接的 getter,要自己解析 XML
|
||||
String xml = sp.getSpPr().getExtLst().toString();
|
||||
if (xml.contains("lockAspectRatio=\"1\"") || xml.contains("lockAspectRatio=\"true\"")) {
|
||||
lockAspectRatio = true;
|
||||
} else if (xml.contains("lockAspectRatio=\"0\"") || xml.contains("lockAspectRatio=\"false\"")) {
|
||||
lockAspectRatio = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return String.valueOf(lockAspectRatio);
|
||||
}
|
||||
|
||||
// EMU 转 pt
|
||||
private static double emuToPt(long emu) {
|
||||
return emu / 12700.0;
|
||||
}
|
||||
|
||||
/// 大小 旋转
|
||||
public static String getShapeSizeRotate(Pic sp, CTSlideTiming timing) {
|
||||
return "待开发";
|
||||
}
|
||||
|
||||
// 位置 水平位置
|
||||
public static String getShapePositionLeft(Pic sp, CTSlideTiming timing) {
|
||||
CTTransform2D xfrm = sp.getSpPr().getXfrm();
|
||||
if (xfrm != null) {
|
||||
long x = xfrm.getOff().getX(); // 水平位置(EMU)
|
||||
return String.valueOf(x / 9525.0);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// 位置 垂直位置
|
||||
public static String getShapePositionTop(Pic sp, CTSlideTiming timing) {
|
||||
CTTransform2D xfrm = sp.getSpPr().getXfrm();
|
||||
if (xfrm != null) {
|
||||
long y = xfrm.getOff().getY(); // 垂直位置(EMU)
|
||||
return String.valueOf(y / 9525.0);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// 形状填充 填充方式
|
||||
public static String getShapeFillType(Pic sp, CTSlideTiming timing) {
|
||||
CTShapeProperties spPr = sp.getSpPr();
|
||||
return SlideUtils.getFillType(spPr);
|
||||
}
|
||||
|
||||
// 形状填充 纯色填充-颜色
|
||||
public static String getShapeFillSolidColor(Pic sp, CTSlideTiming timing) {
|
||||
CTShapeProperties spPr = sp.getSpPr();
|
||||
if (spPr != null && spPr.getSolidFill() != null) {
|
||||
return SlideUtils.getSolidFillColor(spPr.getSolidFill());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// 形状填充 渐变填充-效果
|
||||
public static String getShapeFillGradientType(Pic sp, CTSlideTiming timing) {
|
||||
CTShapeProperties spPr = sp.getSpPr();
|
||||
|
||||
if (spPr != null && spPr.getGradFill() != null) {
|
||||
System.out.println("形状: " + sp.getNvPicPr().getCNvPr().getName());
|
||||
return SlideUtils.printGradientFill(spPr.getGradFill());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// 形状填充 图片填充-效果
|
||||
public static String getShapeFillPictureType(Pic sp, CTSlideTiming timing) {
|
||||
CTShapeProperties spPr = sp.getSpPr();
|
||||
|
||||
if (spPr != null && spPr.getBlipFill() != null) {
|
||||
System.out.println("形状: " + sp.getNvPicPr().getCNvPr().getName());
|
||||
return SlideUtils.printImageFill(spPr.getBlipFill());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// 形状填充 纹理填充-效果
|
||||
public static String getShapeFillTextureType(Pic sp, CTSlideTiming timing) {
|
||||
CTShapeProperties spPr = sp.getSpPr();
|
||||
if (spPr != null && spPr.getPattFill() != null) {
|
||||
return SlideUtils.printPatternFill(spPr.getPattFill());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// 形状填充 图案填充-效果
|
||||
public static String getShapeFillPatternType(Pic sp, CTSlideTiming timing) {
|
||||
CTShapeProperties spPr = sp.getSpPr();
|
||||
if (spPr != null && spPr.getPattFill() != null) {
|
||||
return spPr.getPattFill().getPrst().value();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// 形状填充 幻灯片背景填充-效果
|
||||
public static String getShapeFillSlideBackgroundType(Pic sp, CTSlideTiming timing) {
|
||||
return "待开发";
|
||||
}
|
||||
|
||||
// 形状填充 填充透明度
|
||||
public static String getShapeFillOpacity(Pic sp, CTSlideTiming timing) {
|
||||
return "待开发";
|
||||
}
|
||||
|
||||
// 形状线条 绘制
|
||||
public static String getShapeLineDraw(Pic sp, CTSlideTiming timing) {
|
||||
CTShapeProperties spPr = sp.getSpPr();
|
||||
|
||||
if (spPr != null && spPr.getLn() != null) {
|
||||
CTLineProperties ln = spPr.getLn();
|
||||
|
||||
// 宽度(EMU -> pt)
|
||||
double widthPt = ln.getW() / 12700.0;
|
||||
System.out.println("形状: " + sp.getNvPicPr().getCNvPr().getName());
|
||||
System.out.println("线宽: " + widthPt + " pt");
|
||||
|
||||
// 颜色
|
||||
if (ln.getSolidFill() != null && ln.getSolidFill().getSrgbClr() != null) {
|
||||
CTSRgbColor rgb = ln.getSolidFill().getSrgbClr();
|
||||
System.out.println("线条颜色: #" + rgb.getVal());
|
||||
}
|
||||
|
||||
// 虚线样式
|
||||
if (ln.getPrstDash() != null) {
|
||||
System.out.println("线型: " + ln.getPrstDash().getVal().value());
|
||||
}
|
||||
|
||||
// 端点样式
|
||||
if (ln.getCap() != null) {
|
||||
System.out.println("端点: " + ln.getCap().value());
|
||||
}
|
||||
return "是";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// 形状线条 线条颜色
|
||||
public static String getShapeLineColor(Pic sp, CTSlideTiming timing) {
|
||||
CTShapeProperties spPr = sp.getSpPr();
|
||||
|
||||
if (spPr != null && spPr.getLn() != null) {
|
||||
CTLineProperties ln = spPr.getLn();
|
||||
// 颜色
|
||||
if (ln.getSolidFill() != null && ln.getSolidFill().getSrgbClr() != null) {
|
||||
CTSRgbColor rgb = ln.getSolidFill().getSrgbClr();
|
||||
return rgb.getVal();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// 形状线条 线条宽度
|
||||
public static String getShapeLineWidth(Pic sp, CTSlideTiming timing) {
|
||||
CTShapeProperties spPr = sp.getSpPr();
|
||||
|
||||
if (spPr != null && spPr.getLn() != null) {
|
||||
CTLineProperties ln = spPr.getLn();
|
||||
// 宽度(EMU -> pt)
|
||||
double widthPt = ln.getW() / 12700.0;
|
||||
return String.valueOf(widthPt);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// 形状线条 透明度
|
||||
public static String getShapeLineOpacity(Pic sp, CTSlideTiming timing) {
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
// 形状线条 复合类型
|
||||
public static String getStrokeCompound(Pic sp, CTSlideTiming timing) {
|
||||
if (sp == null || sp.getSpPr() == null) return "未定义";
|
||||
CTShapeProperties spPr = sp.getSpPr();
|
||||
CTLineProperties ln = spPr.getLn();
|
||||
if (ln == null) return "未定义";
|
||||
|
||||
STCompoundLine cmpd = ln.getCmpd(); // 可能为 null
|
||||
String v = (cmpd != null) ? cmpd.value() : "sng"; // 默认单线
|
||||
switch (v) {
|
||||
case "dbl":
|
||||
return "双线 (dbl)";
|
||||
case "thickThin":
|
||||
return "粗-细双线 (thickThin)";
|
||||
case "thinThick":
|
||||
return "细-粗双线 (thinThick)";
|
||||
case "tri":
|
||||
return "三重线 (tri)";
|
||||
case "sng":
|
||||
default:
|
||||
return "单线 (sng)";
|
||||
}
|
||||
}
|
||||
|
||||
// 形状线条 短划线类型
|
||||
public static String getStrokeDash(Pic sp, CTSlideTiming timing) {
|
||||
if (sp == null || sp.getSpPr() == null) return "solid";
|
||||
CTShapeProperties spPr = sp.getSpPr();
|
||||
CTLineProperties ln = spPr.getLn();
|
||||
if (ln == null) return "solid";
|
||||
|
||||
// 1) 预设短划线
|
||||
if (ln.getPrstDash() != null && ln.getPrstDash().getVal() != null) {
|
||||
STPresetLineDashVal val = ln.getPrstDash().getVal();
|
||||
return SlideUtils.mapPreset(val);
|
||||
}
|
||||
|
||||
// 2) 自定义短划线
|
||||
if (ln.getCustDash() != null && ln.getCustDash().getDs() != null && !ln.getCustDash().getDs().isEmpty()) {
|
||||
StringBuilder sb = new StringBuilder("custom ");
|
||||
for (CTDashStop ds : ln.getCustDash().getDs()) {
|
||||
int d = ds.getD(); // dash length(相对线宽的比例单位)
|
||||
int sps = ds.getSp(); // space length(相对线宽的比例单位)
|
||||
sb.append("[d=").append(d).append(", sps=").append(sps).append("] ");
|
||||
}
|
||||
return sb.toString().trim();
|
||||
}
|
||||
|
||||
// 3) 未设置 → 视为实线
|
||||
return "solid";
|
||||
}
|
||||
// 形状线条 开始箭头类型
|
||||
public static String getShapeLineStartArrow(Pic sp, CTSlideTiming timing) {
|
||||
CTShapeProperties spPr = sp.getSpPr();
|
||||
if (spPr != null && spPr.getLn() != null) {
|
||||
CTLineProperties ln = spPr.getLn();
|
||||
if (ln.getHeadEnd() != null) {
|
||||
return ln.getHeadEnd().getType().value();
|
||||
}
|
||||
}
|
||||
return "无箭头";
|
||||
}
|
||||
// 形状线条 开始箭头粗细
|
||||
public static String getShapeLineStartArrowWidth(Pic sp, CTSlideTiming timing) {
|
||||
return "待开发";
|
||||
}
|
||||
// 形状线条 结尾箭头类型
|
||||
public static String getShapeLineEndArrow(Pic sp, CTSlideTiming timing) {
|
||||
return "待开发";
|
||||
}
|
||||
// 形状线条 结尾箭头粗细
|
||||
public static String getShapeLineEndArrowWidth(Pic sp, CTSlideTiming timing) {
|
||||
return "待开发";
|
||||
}
|
||||
|
||||
|
||||
// 形状效果 阴影-绘制
|
||||
public static String getShapeShadowDraw(Pic sp, CTSlideTiming timing) {
|
||||
CTShapeProperties spPr = sp.getSpPr();
|
||||
CTEffectList effList = spPr.getEffectLst();
|
||||
if (effList == null) {
|
||||
return "否";
|
||||
}
|
||||
// 判断三种阴影效果
|
||||
return effList.getOuterShdw() != null
|
||||
|| effList.getInnerShdw() != null
|
||||
|| effList.getPrstShdw() != null ? "是" : "否";
|
||||
}
|
||||
|
||||
// 形状效果 阴影-效果
|
||||
public static String getShapeShadowEffect(Pic sp, CTSlideTiming timing) {
|
||||
if (sp == null || sp.getSpPr() == null) {
|
||||
return "无阴影";
|
||||
}
|
||||
CTShapeProperties spPr = sp.getSpPr();
|
||||
CTEffectList effList = spPr.getEffectLst();
|
||||
if (effList == null) {
|
||||
return "无阴影";
|
||||
}
|
||||
|
||||
if (effList.getOuterShdw() != null) {
|
||||
return "外阴影";
|
||||
} else if (effList.getInnerShdw() != null) {
|
||||
return "内阴影";
|
||||
} else if (effList.getPrstShdw() != null) {
|
||||
return "预设阴影";
|
||||
}
|
||||
return "无阴影";
|
||||
}
|
||||
|
||||
// 形状效果 倒影-绘制
|
||||
public static String getShapeReflectionDraw(Pic sp, CTSlideTiming timing) {
|
||||
CTShapeProperties spPr = sp.getSpPr();
|
||||
CTEffectList effList = spPr.getEffectLst();
|
||||
if (effList == null) {
|
||||
return "无倒影";
|
||||
}
|
||||
|
||||
CTReflectionEffect reflection = effList.getReflection();
|
||||
if (reflection != null) {
|
||||
// 如果需要详细参数,这里可以读取
|
||||
return "有倒影";
|
||||
}
|
||||
return "无倒影";
|
||||
}
|
||||
|
||||
// 形状效果 倒影-效果
|
||||
public static String getShapeReflectionEffect(Pic sp, CTSlideTiming timing) {
|
||||
CTReflectionEffect r = SlideUtils.getReflectionPic(sp);
|
||||
if (r == null) return "无倒影";
|
||||
|
||||
// —— 1) 倒影覆盖程度:用 stPos/endPos(0..100000)估算 —— //
|
||||
double st = SlideUtils.to100k(BigInteger.valueOf(r.getStPos()), 0);
|
||||
double ed = SlideUtils.to100k(BigInteger.valueOf(r.getEndPos()), 100000); // 默认 100%
|
||||
double coverage = Math.max(0, ed - st) / 100000.0; // 0.0 ~ 1.0
|
||||
|
||||
String coverageLabel;
|
||||
if (coverage >= 0.85) {
|
||||
coverageLabel = "全倒影";
|
||||
} else if (coverage >= 0.45) {
|
||||
coverageLabel = "半倒影";
|
||||
} else {
|
||||
coverageLabel = "短倒影";
|
||||
}
|
||||
|
||||
// —— 2) 偏移描述:dist EMU -> pt;<1pt 视作“紧贴”,否则 "Xpt 偏移" —— //
|
||||
double distPt = emuToPt(r.getDist()); // 可能为 0
|
||||
String offsetLabel = distPt < 1.0 ? "紧贴" : (SlideUtils.fmt1(distPt) + "pt 偏移");
|
||||
|
||||
return coverageLabel + " " + offsetLabel;
|
||||
}
|
||||
|
||||
// 形状效果 发光
|
||||
public static String getShapeGlow(Pic sp, CTSlideTiming timing) {
|
||||
if (sp == null || sp.getSpPr() == null) return null;
|
||||
CTShapeProperties spPr = sp.getSpPr();
|
||||
CTEffectList eff = spPr.getEffectLst();
|
||||
return (eff != null) ? eff.getGlow().toString() : null;
|
||||
}
|
||||
|
||||
// 形状效果 发光-效果
|
||||
public static String getShapeGlowEffect(Pic sp, CTSlideTiming timing) {
|
||||
return "待开发";
|
||||
}
|
||||
|
||||
// 形状效果 柔化边缘-绘制
|
||||
public static String getShapeSoftEdgesDraw(Pic sp, CTSlideTiming timing) {
|
||||
CTSoftEdgesEffect se = getSoftEdge(sp);
|
||||
return (se != null) ? "是" : "否";
|
||||
}
|
||||
|
||||
// 形状效果 柔化边缘→大小
|
||||
public static String getShapeSoftEdgesSize(Pic sp, CTSlideTiming timing) {
|
||||
CTSoftEdgesEffect se = getSoftEdge(sp);
|
||||
return (se != null) ? String.valueOf(se.getRad()) : null;
|
||||
}
|
||||
// 形状效果 三维效果→绘制
|
||||
public static String getShape3DEffectDraw(Pic sp, CTSlideTiming timing) {
|
||||
return "待开发";
|
||||
}
|
||||
// 形状效果 三维格式→效果
|
||||
public static String getShape3DEffect(Pic sp, CTSlideTiming timing) {
|
||||
return "待开发";
|
||||
}
|
||||
// 形状效果 三维旋转→效果
|
||||
public static String getShape3DRotation(Pic sp, CTSlideTiming timing) {
|
||||
return "待开发";
|
||||
}
|
||||
|
||||
/* —— 内部:spPr/effectLst/softEdge —— */
|
||||
private static CTSoftEdgesEffect getSoftEdge(Pic shape) {
|
||||
if (shape == null || shape.getSpPr() == null) return null;
|
||||
CTShapeProperties spPr = shape.getSpPr();
|
||||
CTEffectList eff = spPr.getEffectLst();
|
||||
return (eff != null) ? eff.getSoftEdge() : null;
|
||||
// 说明:极少数文件把效果写在 effectDag;若拿不到再补 effectDag 解析。
|
||||
}
|
||||
|
||||
|
||||
// 动画 效果
|
||||
// public static String getAnimation(org.pptx4j.pml.Shape sp, CTSlideTiming timing) throws JAXBException, XPathBinderAssociationIsPartialException {
|
||||
// // 获取形状中的ID
|
||||
// if (sp == null) return "无动画";
|
||||
// long spId = sp.getNvSpPr().getCNvPr().getId();
|
||||
// // 获取动画效果
|
||||
// CTTimeNodeList timeNodeList = timing.getTnLst();
|
||||
// for (Object obj : timeNodeList.getParOrSeqOrExcl()) {
|
||||
// if (obj instanceof CTTLTimeNodeParallel) {
|
||||
// CTTLTimeNodeParallel par = (CTTLTimeNodeParallel) obj;
|
||||
// CTTLCommonTimeNodeData node = par.getCTn();
|
||||
// if (node.getChildTnLst().getParOrSeqOrExcl() != null) {
|
||||
// CTTimeNodeList childTimeNodeList = node.getChildTnLst();
|
||||
// for (Object object : childTimeNodeList.getParOrSeqOrExcl()) {
|
||||
// if (object instanceof CTTLSetBehavior) {
|
||||
// if (((CTTLSetBehavior) object).getCBhvr() != null) {
|
||||
// if (((CTTLSetBehavior) object).getCBhvr().getTgtEl().getSpTgt() != null) {
|
||||
// // 检查目标形状ID是否匹配
|
||||
// if (((CTTLSetBehavior) object).getCBhvr().getTgtEl().getSpTgt().getSpid().equals(String.valueOf(spId))) {
|
||||
// // 返回动画效果
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (object instanceof CTTLTimeNodeSequence) {
|
||||
// CTTLTimeNodeSequence seq = (CTTLTimeNodeSequence) object;
|
||||
// CTTimeNodeList seqNodeList = seq.getCTn().getChildTnLst();
|
||||
// for (Object seqObjs : seqNodeList.getParOrSeqOrExcl()) {
|
||||
// if (seqObjs instanceof CTTLSetBehavior) {
|
||||
// if (((CTTLSetBehavior) seqObjs).getCBhvr() != null) {
|
||||
// if (((CTTLSetBehavior) seqObjs).getCBhvr().getTgtEl().getSpTgt() != null) {
|
||||
// // 检查目标形状ID是否匹配
|
||||
// if (((CTTLSetBehavior) seqObjs).getCBhvr().getTgtEl().getSpTgt().getSpid().equals(String.valueOf(spId))) {
|
||||
// // 返回动画效果
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (seqObjs instanceof CTTLTimeNodeSequence) {
|
||||
// CTTLTimeNodeSequence seqObj = (CTTLTimeNodeSequence) seqObjs;
|
||||
// CTTimeNodeList seqNodeLists = seqObj.getCTn().getChildTnLst();
|
||||
// for (Object seqObjss : seqNodeLists.getParOrSeqOrExcl()) {
|
||||
// if (seqObjss instanceof CTTLSetBehavior) {
|
||||
// if (((CTTLSetBehavior) seqObjss).getCBhvr() != null) {
|
||||
// if (((CTTLSetBehavior) seqObjss).getCBhvr().getTgtEl().getSpTgt() != null) {
|
||||
// // 检查目标形状ID是否匹配
|
||||
// if (((CTTLSetBehavior) seqObjss).getCBhvr().getTgtEl().getSpTgt().getSpid().equals(String.valueOf(spId))) {
|
||||
// // 返回动画效果
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// if (node.getDur() != null && !"indefinite".equals(node.getDur())) {
|
||||
// return node.getDur();
|
||||
// }
|
||||
// System.out.println(par.getCTn());
|
||||
// }
|
||||
// }
|
||||
// return "待开发";
|
||||
// }
|
||||
|
||||
public static String getAnimation(org.pptx4j.pml.Pic sp, CTSlideTiming timing) {
|
||||
if (sp == null || timing == null || timing.getTnLst() == null) return "无动画";
|
||||
final String spId = String.valueOf(sp.getNvPicPr().getCNvPr().getId());
|
||||
CTTimeNodeList root = timing.getTnLst();
|
||||
|
||||
// 先找进入类(effect)
|
||||
String entrance = findFirstBehavior(root, spId, /*preferEntrance=*/true);
|
||||
if (entrance != null) return entrance;
|
||||
|
||||
// 再找其它类型(包括 CTTLAnimateBehavior 的 ppt_x/ppt_y)
|
||||
String any = findFirstBehavior(root, spId, /*preferEntrance=*/false);
|
||||
return any != null ? any : "无动画";
|
||||
}
|
||||
|
||||
/* 递归遍历所有 time nodes,返回首个命中的行为字符串 */
|
||||
private static String findFirstBehavior(CTTimeNodeList list, String spId, boolean preferEntrance) {
|
||||
if (list == null || list.getParOrSeqOrExcl() == null) return null;
|
||||
|
||||
for (Object raw : list.getParOrSeqOrExcl()) {
|
||||
Object node = unwrap(raw);
|
||||
|
||||
// 1) 直接是某种行为(Behavior)
|
||||
String desc = tryDescribeIfBehavior(node, spId, preferEntrance);
|
||||
if (desc != null) return desc;
|
||||
|
||||
// 2) par / seq / excl,进入子列表递归
|
||||
CTTimeNodeList child = getChildList(node);
|
||||
if (child != null) {
|
||||
String got = findFirstBehavior(child, spId, preferEntrance);
|
||||
if (got != null) return got;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* 如果对象是某种 Behavior,且目标命中当前 spId,则返回描述;否则返回 null */
|
||||
private static String tryDescribeIfBehavior(Object obj, String spId, boolean preferEntrance) {
|
||||
// 统一 unwrap
|
||||
obj = unwrap(obj);
|
||||
|
||||
// --- 进入类效果(Effect)---
|
||||
if (obj instanceof CTTLAnimateEffectBehavior) {
|
||||
CTTLAnimateEffectBehavior b = (CTTLAnimateEffectBehavior) obj;
|
||||
if (isTarget(b.getCBhvr(), spId)) {
|
||||
String filter = safe(b.getFilter()); // 如 "fade"、"strips(downRight)" 等
|
||||
return filter.isEmpty() ? "进入效果" : ("进入效果:" + filter);
|
||||
}
|
||||
}
|
||||
|
||||
// 非优先阶段:其它类型
|
||||
if (!preferEntrance) {
|
||||
// 通用 Animate (B 动画关键:ppt_x / ppt_y)
|
||||
if (obj instanceof CTTLAnimateBehavior) {
|
||||
CTTLAnimateBehavior b = (CTTLAnimateBehavior) obj;
|
||||
if (isTarget(b.getCBhvr(), spId)) {
|
||||
String attr = firstAttrName(b.getCBhvr());
|
||||
if ("ppt_x".equalsIgnoreCase(attr)) return "位置动画:X(ppt_x)";
|
||||
if ("ppt_y".equalsIgnoreCase(attr)) return "位置动画:Y(ppt_y)";
|
||||
return attr.isEmpty() ? "数值动画(Animate)" : ("数值动画(" + attr + ")");
|
||||
}
|
||||
}
|
||||
if (obj instanceof CTTLAnimateMotionBehavior) {
|
||||
CTTLAnimateMotionBehavior b = (CTTLAnimateMotionBehavior) obj;
|
||||
if (isTarget(b.getCBhvr(), spId)) return "路径动画(Motion)";
|
||||
}
|
||||
if (obj instanceof CTTLAnimateRotationBehavior) {
|
||||
CTTLAnimateRotationBehavior b = (CTTLAnimateRotationBehavior) obj;
|
||||
if (isTarget(b.getCBhvr(), spId)) return "旋转动画";
|
||||
}
|
||||
if (obj instanceof CTTLAnimateScaleBehavior) {
|
||||
CTTLAnimateScaleBehavior b = (CTTLAnimateScaleBehavior) obj;
|
||||
if (isTarget(b.getCBhvr(), spId)) return "缩放动画";
|
||||
}
|
||||
if (obj instanceof CTTLSetBehavior) {
|
||||
CTTLSetBehavior b = (CTTLSetBehavior) obj;
|
||||
if (isTarget(b.getCBhvr(), spId)) {
|
||||
String to = (b.getTo()!=null && b.getTo().getStrVal()!=null) ? safe(b.getTo().getStrVal().getVal()) : "";
|
||||
String attr = firstAttrName(b.getCBhvr());
|
||||
if (!attr.isEmpty() || !to.isEmpty()) {
|
||||
return "属性设置(Set):" + (attr.isEmpty() ? "" : attr) + (to.isEmpty() ? "" : (" -> " + to));
|
||||
}
|
||||
return "属性设置(Set)";
|
||||
}
|
||||
}
|
||||
if (obj instanceof CTTLAnimateColorBehavior) {
|
||||
CTTLAnimateColorBehavior b = (CTTLAnimateColorBehavior) obj;
|
||||
if (isTarget(b.getCBhvr(), spId)) return "颜色动画";
|
||||
}
|
||||
if (obj instanceof CTTLCommandBehavior) {
|
||||
CTTLCommandBehavior b = (CTTLCommandBehavior) obj;
|
||||
if (isTarget(b.getCBhvr(), spId)) return "命令动画(Command)";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* 提取并返回子节点列表(par/seq/excl 三种) */
|
||||
private static CTTimeNodeList getChildList(Object node) {
|
||||
node = unwrap(node);
|
||||
if (node instanceof CTTLTimeNodeParallel) {
|
||||
CTTLTimeNodeParallel n = (CTTLTimeNodeParallel) node;
|
||||
return n.getCTn() != null ? n.getCTn().getChildTnLst() : null;
|
||||
}
|
||||
if (node instanceof CTTLTimeNodeSequence) {
|
||||
CTTLTimeNodeSequence n = (CTTLTimeNodeSequence) node;
|
||||
return n.getCTn() != null ? n.getCTn().getChildTnLst() : null;
|
||||
}
|
||||
if (node instanceof CTTLTimeNodeExclusive) {
|
||||
CTTLTimeNodeExclusive n = (CTTLTimeNodeExclusive) node;
|
||||
return n.getCTn() != null ? n.getCTn().getChildTnLst() : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* 判断行为的目标是否命中当前形状 spId */
|
||||
private static boolean isTarget(CTTLCommonBehaviorData cb, String spId) {
|
||||
if (cb == null || cb.getTgtEl() == null || cb.getTgtEl().getSpTgt() == null) return false;
|
||||
String tgt = cb.getTgtEl().getSpTgt().getSpid();
|
||||
return String.valueOf(spId).equals(tgt);
|
||||
}
|
||||
|
||||
/* 读第一个 attrName(如 ppt_x / ppt_y / style.visibility ...)*/
|
||||
private static String firstAttrName(CTTLCommonBehaviorData cb) {
|
||||
if (cb == null || cb.getAttrNameLst() == null) return "";
|
||||
java.util.List<String> names = cb.getAttrNameLst().getAttrName();
|
||||
return (names != null && !names.isEmpty()) ? safe(names.get(0)) : "";
|
||||
}
|
||||
|
||||
/* 统一解包 JAXBElement */
|
||||
private static Object unwrap(Object o) {
|
||||
return (o instanceof JAXBElement) ? ((JAXBElement<?>) o).getValue() : o;
|
||||
}
|
||||
|
||||
/* 安全字符串 */
|
||||
private static String safe(String s) {
|
||||
return s == null ? "" : s.trim();
|
||||
}
|
||||
|
||||
|
||||
// 动画-方向
|
||||
public static String getAnimateDirection(Pic sp, CTSlideTiming timing) {
|
||||
String dir = getAnimation(sp, timing);
|
||||
if (dir.equals("downRight")) {
|
||||
return "右下";
|
||||
}
|
||||
if (dir.equals("downLeft")) {
|
||||
return "左下";
|
||||
}
|
||||
if (dir.equals("upRight")) {
|
||||
return "右上";
|
||||
}
|
||||
if (dir.equals("upLeft")) {
|
||||
return "左上";
|
||||
}
|
||||
if (dir.equals("right")) {
|
||||
return "向右";
|
||||
}
|
||||
if (dir.equals("left")) {
|
||||
return "向左";
|
||||
}
|
||||
if (dir.equals("down")) {
|
||||
return "向下";
|
||||
}
|
||||
if (dir.equals("up")) {
|
||||
return "向上";
|
||||
}
|
||||
if (dir.equals("fromTop")) {
|
||||
return "从顶部";
|
||||
}
|
||||
if (dir.equals("fromBottom")) {
|
||||
return "从底部";
|
||||
}
|
||||
if (dir.equals("fromLeft")) {
|
||||
return "从左侧";
|
||||
}
|
||||
if (dir.equals("fromRight")) {
|
||||
return "从右侧";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// 动画 触发方式
|
||||
public static String getAnimateTrigger(Pic sp, CTSlideTiming timing) {
|
||||
// 获取形状中的ID
|
||||
if (sp == null) return "无动画";
|
||||
long spId = sp.getNvPicPr().getCNvPr().getId();
|
||||
// 获取动画效果
|
||||
CTTimeNodeList timeNodeList = timing.getTnLst();
|
||||
for (Object obj : timeNodeList.getParOrSeqOrExcl()) {
|
||||
if (obj instanceof CTTLTimeNodeParallel) {
|
||||
CTTLTimeNodeParallel par = (CTTLTimeNodeParallel) obj;
|
||||
CTTLCommonTimeNodeData node = par.getCTn();
|
||||
if (node.getChildTnLst().getParOrSeqOrExcl() != null) {
|
||||
CTTimeNodeList childTimeNodeList = node.getChildTnLst();
|
||||
for (Object object : childTimeNodeList.getParOrSeqOrExcl()) {
|
||||
if (object instanceof CTTLTimeNodeSequence) {
|
||||
CTTLTimeNodeSequence seq = (CTTLTimeNodeSequence) object;
|
||||
if (seq.getCTn().getStCondLst() != null) {
|
||||
CTTLTimeConditionList stCondLst = seq.getCTn().getStCondLst();
|
||||
for (CTTLTimeCondition o : stCondLst.getCond()) {
|
||||
if (o.getEvt() != null) {
|
||||
return o.getEvt().value();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CTTimeNodeList seqNodeList = seq.getCTn().getChildTnLst();
|
||||
for (Object seqObj : seqNodeList.getParOrSeqOrExcl()) {
|
||||
if (seqObj instanceof CTTLTimeNodeSequence) {
|
||||
CTTLTimeNodeSequence seqs = (CTTLTimeNodeSequence) seqObj;
|
||||
if (seqs.getCTn().getStCondLst() != null) {
|
||||
CTTLTimeConditionList stCondLst = seqs.getCTn().getStCondLst();
|
||||
for (CTTLTimeCondition o : stCondLst.getCond()) {
|
||||
if (o.getEvt() != null) {
|
||||
return o.getEvt().value();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CTTimeNodeList seqNodeLists = seqs.getCTn().getChildTnLst();
|
||||
for (Object seqObjs : seqNodeLists.getParOrSeqOrExcl()) {
|
||||
if (seqObjs instanceof CTTLTimeNodeSequence) {
|
||||
CTTLTimeNodeSequence seqss = (CTTLTimeNodeSequence) seqObjs;
|
||||
if (seqss.getCTn().getStCondLst() != null) {
|
||||
CTTLTimeConditionList stCondLst = seqss.getCTn().getStCondLst();
|
||||
for (CTTLTimeCondition o : stCondLst.getCond()) {
|
||||
if (o.getEvt() != null) {
|
||||
return o.getEvt().value();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (seqObj instanceof CTTLTimeNodeParallel) {
|
||||
CTTLTimeNodeParallel seqs = (CTTLTimeNodeParallel) seqObj;
|
||||
if (seqs.getCTn().getStCondLst() != null) {
|
||||
CTTLTimeConditionList stCondLst = seqs.getCTn().getStCondLst();
|
||||
for (CTTLTimeCondition o : stCondLst.getCond()) {
|
||||
if (o.getEvt() != null) {
|
||||
return o.getEvt().value();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CTTimeNodeList seqNodeLists = seqs.getCTn().getChildTnLst();
|
||||
for (Object seqObjs : seqNodeLists.getParOrSeqOrExcl()) {
|
||||
if (seqObjs instanceof CTTLTimeNodeSequence) {
|
||||
CTTLTimeNodeSequence seqss = (CTTLTimeNodeSequence) seqObjs;
|
||||
if (seqss.getCTn().getStCondLst() != null) {
|
||||
CTTLTimeConditionList stCondLst = seqss.getCTn().getStCondLst();
|
||||
for (CTTLTimeCondition o : stCondLst.getCond()) {
|
||||
if (o.getEvt() != null) {
|
||||
return o.getEvt().value();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
// 动画 持续时间
|
||||
public static String getAnimationDuration(Pic sp, CTSlideTiming timing) {
|
||||
if (sp == null || timing == null || timing.getTnLst() == null) return "无动画";
|
||||
|
||||
final String spId = String.valueOf(sp.getNvPicPr().getCNvPr().getId());
|
||||
CTTimeNodeList root = timing.getTnLst();
|
||||
|
||||
// 先找“进入类效果(effect)”
|
||||
String entrance = findFirstBehavior(root, spId, /*preferEntrance=*/true);
|
||||
if (entrance != null) return entrance;
|
||||
|
||||
// 找不到进入类,再找其它类型(运动、旋转、缩放、Set 等)
|
||||
String any = findFirstBehavior(root, spId, /*preferEntrance=*/false);
|
||||
return any != null ? any : "无动画";
|
||||
}
|
||||
|
||||
// 动画 延迟
|
||||
public static String getAnimationDelay(Pic sp, CTSlideTiming timing) {
|
||||
// 获取形状中的ID
|
||||
if (sp == null) return "无动画";
|
||||
long spId = sp.getNvPicPr().getCNvPr().getId();
|
||||
// 获取动画效果
|
||||
CTTimeNodeList timeNodeList = timing.getTnLst();
|
||||
for (Object obj : timeNodeList.getParOrSeqOrExcl()) {
|
||||
if (obj instanceof CTTLTimeNodeParallel) {
|
||||
CTTLTimeNodeParallel par = (CTTLTimeNodeParallel) obj;
|
||||
CTTLCommonTimeNodeData node = par.getCTn();
|
||||
if (node.getChildTnLst().getParOrSeqOrExcl() != null) {
|
||||
CTTimeNodeList childTimeNodeList = node.getChildTnLst();
|
||||
for (Object object : childTimeNodeList.getParOrSeqOrExcl()) {
|
||||
if (object instanceof CTTLTimeNodeSequence) {
|
||||
CTTLTimeNodeSequence seq = (CTTLTimeNodeSequence) object;
|
||||
if (seq.getCTn().getStCondLst() != null) {
|
||||
CTTLTimeConditionList stCondLst = seq.getCTn().getStCondLst();
|
||||
for (CTTLTimeCondition o : stCondLst.getCond()) {
|
||||
if (o.getEvt() != null) {
|
||||
return o.getDelay();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CTTimeNodeList seqNodeList = seq.getCTn().getChildTnLst();
|
||||
for (Object seqObj : seqNodeList.getParOrSeqOrExcl()) {
|
||||
if (seqObj instanceof CTTLTimeNodeSequence) {
|
||||
CTTLTimeNodeSequence seqs = (CTTLTimeNodeSequence) seqObj;
|
||||
if (seqs.getCTn().getStCondLst() != null) {
|
||||
CTTLTimeConditionList stCondLst = seqs.getCTn().getStCondLst();
|
||||
for (CTTLTimeCondition o : stCondLst.getCond()) {
|
||||
if (o.getEvt() != null) {
|
||||
return o.getDelay();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CTTimeNodeList seqNodeLists = seqs.getCTn().getChildTnLst();
|
||||
for (Object seqObjs : seqNodeLists.getParOrSeqOrExcl()) {
|
||||
if (seqObjs instanceof CTTLTimeNodeSequence) {
|
||||
CTTLTimeNodeSequence seqss = (CTTLTimeNodeSequence) seqObjs;
|
||||
if (seqss.getCTn().getStCondLst() != null) {
|
||||
CTTLTimeConditionList stCondLst = seqss.getCTn().getStCondLst();
|
||||
for (CTTLTimeCondition o : stCondLst.getCond()) {
|
||||
if (o.getEvt() != null) {
|
||||
return o.getDelay();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (seqObj instanceof CTTLTimeNodeParallel) {
|
||||
CTTLTimeNodeParallel seqs = (CTTLTimeNodeParallel) seqObj;
|
||||
if (seqs.getCTn().getStCondLst() != null) {
|
||||
CTTLTimeConditionList stCondLst = seqs.getCTn().getStCondLst();
|
||||
for (CTTLTimeCondition o : stCondLst.getCond()) {
|
||||
if (o.getEvt() != null) {
|
||||
return o.getDelay();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CTTimeNodeList seqNodeLists = seqs.getCTn().getChildTnLst();
|
||||
for (Object seqObjs : seqNodeLists.getParOrSeqOrExcl()) {
|
||||
if (seqObjs instanceof CTTLTimeNodeSequence) {
|
||||
CTTLTimeNodeSequence seqss = (CTTLTimeNodeSequence) seqObjs;
|
||||
if (seqss.getCTn().getStCondLst() != null) {
|
||||
CTTLTimeConditionList stCondLst = seqss.getCTn().getStCondLst();
|
||||
for (CTTLTimeCondition o : stCondLst.getCond()) {
|
||||
if (o.getEvt() != null) {
|
||||
return o.getDelay();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/// 形状动作,鼠标单机-动作
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package pc.exam.pp.module.judgement.utils.wps_pptx.pptx4j;
|
||||
|
||||
import org.docx4j.openpackaging.exceptions.Docx4JException;
|
||||
import org.docx4j.openpackaging.packages.PresentationMLPackage;
|
||||
import org.docx4j.openpackaging.parts.PresentationML.SlidePart;
|
||||
import org.pptx4j.pml.CTSlideTiming;
|
||||
|
||||
public class SlideAllSetting {
|
||||
// 设计 主题模板
|
||||
public static String getAllSlideTheme( SlidePart slidePart, PresentationMLPackage presentation) throws Docx4JException {
|
||||
// 获取第一个幻灯片母版(通常主主题在这里)
|
||||
return "WPS";
|
||||
}
|
||||
|
||||
// 幻灯片切换 切换声音
|
||||
|
||||
|
||||
}
|
||||
@@ -22,7 +22,7 @@ public class SlideConversion {
|
||||
XMLSlideShow pptxXml = new XMLSlideShow(inputStream)) {
|
||||
int index = 0;
|
||||
String firstId = getStringRandom();
|
||||
setSlideDataInfo(firstId, "", "幻灯片", "w:p", "", false, dataInfoVOS);
|
||||
setSlideDataInfo(firstId, "", "幻灯片", "slide", "", false, dataInfoVOS);
|
||||
for (XSLFSlide slides : pptxXml.getSlides()){
|
||||
index += 1;
|
||||
String secondId = getStringRandom();
|
||||
@@ -30,7 +30,7 @@ public class SlideConversion {
|
||||
// 第三层
|
||||
String thirdId = getStringRandom();
|
||||
int indexCnvPr = 1;
|
||||
setSlideDataInfo(thirdId, secondId, "幻灯片设置", "slide", String.valueOf(index), true, dataInfoVOS);
|
||||
setSlideDataInfo(thirdId, secondId, "幻灯片设置", "slideSetting", String.valueOf(index) + "_0", true, dataInfoVOS);
|
||||
XmlCursor spCursor = slides.getXmlObject().newCursor();
|
||||
spCursor.selectPath("declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//p:sp");
|
||||
while (spCursor.toNextSelection()) {
|
||||
@@ -39,7 +39,7 @@ public class SlideConversion {
|
||||
if (cNvPrXml.toNextSelection()) {
|
||||
String name = cNvPrXml.getTextValue();
|
||||
String fourId = getStringRandom();
|
||||
setSlideDataInfo(fourId, secondId, "形状"+indexCnvPr+"->"+name, "shape", String.valueOf(indexCnvPr), true, dataInfoVOS);
|
||||
setSlideDataInfo(fourId, secondId, "形状"+indexCnvPr+"->"+name, "shape", String.valueOf(index) + "_" + String.valueOf(indexCnvPr), true, dataInfoVOS);
|
||||
indexCnvPr += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,20 +3,15 @@ package pc.exam.pp.module.judgement.utils.wps_pptx.pptx4j;
|
||||
import org.docx4j.openpackaging.exceptions.Docx4JException;
|
||||
import org.docx4j.openpackaging.packages.OpcPackage;
|
||||
import org.docx4j.openpackaging.packages.PresentationMLPackage;
|
||||
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
|
||||
import org.docx4j.openpackaging.parts.PresentationML.SlidePart;
|
||||
import org.docx4j.openpackaging.parts.WordprocessingML.NumberingDefinitionsPart;
|
||||
import org.docx4j.openpackaging.parts.WordprocessingML.StyleDefinitionsPart;
|
||||
import org.docx4j.wml.P;
|
||||
import org.pptx4j.pml.CTSlideTiming;
|
||||
import org.pptx4j.pml.GroupShape;
|
||||
import org.pptx4j.pml.Pic;
|
||||
import org.pptx4j.pml.Shape;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import pc.exam.pp.module.judgement.controller.admin.AutoWps.vo.WpsSlideInfoVo;
|
||||
import pc.exam.pp.module.judgement.utils.wps_pptx.pptx4j.vo.JudgementSlidesVO;
|
||||
import pc.exam.pp.module.judgement.utils.wps_word.docx4j.paragraph.Paragraphs;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -26,21 +21,19 @@ import java.util.List;
|
||||
public class SlideMaster {
|
||||
|
||||
public static List<JudgementSlidesVO> slideMaster(List<WpsSlideInfoVo> wpsSlideInfoVos, MultipartFile file) throws IOException, Docx4JException {
|
||||
File files = new File("E:\\Project\\Exam\\Software\\Temp\\1.pptx");
|
||||
// File files = new File("E:\\Project\\Exam\\Software\\Temp\\1.pptx");
|
||||
List<JudgementSlidesVO> judgementSlidesVOS = new ArrayList<>();
|
||||
// 1、获取想要判断的文件地址(文件流)
|
||||
// try (InputStream inputStream = file.getInputStream()) {
|
||||
try {
|
||||
try (InputStream inputStream = file.getInputStream()) {
|
||||
// try {
|
||||
// 加载 .pptx 文件
|
||||
PresentationMLPackage ppt =
|
||||
(PresentationMLPackage) OpcPackage.load(files);
|
||||
(PresentationMLPackage) OpcPackage.load(inputStream);
|
||||
// 你可以在这里处理 ppt,比如读取文字、页数等
|
||||
for (WpsSlideInfoVo wpsSlideInfoVo : wpsSlideInfoVos) {
|
||||
// 幻灯片位置(第几张幻灯片)
|
||||
String slideIndex = wpsSlideInfoVo.getSlideIndex();
|
||||
String shapeIndex = wpsSlideInfoVo.getShapeIndex();
|
||||
// 形状类型 slide 幻灯片设置 shape 形状(不包含图片) shapePic 形状图片 presentation 总幻灯片设置
|
||||
String type = wpsSlideInfoVo.getType();
|
||||
String slideIndex = wpsSlideInfoVo.getSlideIndex().split("_")[0];
|
||||
String shapeIndex = wpsSlideInfoVo.getSlideIndex().split("_")[1];
|
||||
// 大类名称
|
||||
String firstName = wpsSlideInfoVo.getFirstName();
|
||||
// 方法名称
|
||||
@@ -51,11 +44,13 @@ public class SlideMaster {
|
||||
String examCode = wpsSlideInfoVo.getExamCode();
|
||||
// 方式方法
|
||||
String method = wpsSlideInfoVo.getMethod();
|
||||
if (type.equals("shape")) {
|
||||
// 查询幻灯片图片
|
||||
List<SlidePart> slideParts = ppt.getMainPresentationPart().getSlideParts();
|
||||
int slideIndexFoFile = 0;
|
||||
for (SlidePart slidePart : slideParts) {
|
||||
|
||||
String content = wpsSlideInfoVo.getSlideIndex() + "@" + firstName + "@" + function + "@" + examName + "@" + examCode + "@" + method;
|
||||
// 查询幻灯片图片
|
||||
List<SlidePart> slideParts = ppt.getMainPresentationPart().getSlideParts();
|
||||
int slideIndexFoFile = 0;
|
||||
for (SlidePart slidePart : slideParts) {
|
||||
if (method.equals("shape")) {
|
||||
// 获取幻灯片内容
|
||||
slideIndexFoFile++;
|
||||
if (slideIndex.equals(String.valueOf(slideIndexFoFile))) {
|
||||
@@ -63,14 +58,12 @@ public class SlideMaster {
|
||||
// 遍历 shape tree 中的 sp(shape)元素
|
||||
GroupShape spTree = slidePart.getJaxbElement().getCSld().getSpTree();
|
||||
CTSlideTiming timing = slidePart.getJaxbElement().getTiming();
|
||||
List<Object> shapes = spTree.getSpOrGrpSpOrGraphicFrame();
|
||||
List<Object> shapes = spTree.getSpOrGrpSpOrGraphicFrame();
|
||||
int shapeIndexFoFile = 0;
|
||||
for (Object shapeObj : shapes) {
|
||||
for (Object shapeObj : shapes) {
|
||||
shapeIndexFoFile++;
|
||||
if (shapeObj instanceof Shape) {
|
||||
Shape shape = (Shape) shapeObj;
|
||||
if (shapeObj instanceof Shape shape) {
|
||||
if (shapeIndex.equals(String.valueOf(shapeIndexFoFile))) {
|
||||
// 查询出具体想要查询哪个段落的数据
|
||||
// 目标对象
|
||||
ShapePage shapeFunction = new ShapePage();
|
||||
// 获取参数中类型的定义
|
||||
@@ -80,13 +73,48 @@ public class SlideMaster {
|
||||
// 实际参数值
|
||||
Object[] arguments = {shape, timing};
|
||||
String value = (String) methodWithArgs.invoke(shapeFunction, arguments);
|
||||
System.out.println(value);
|
||||
JudgementSlidesVO judgementSlidesVO = new JudgementSlidesVO();
|
||||
judgementSlidesVO.setContent(content + "@" + value);
|
||||
judgementSlidesVO.setContentIn(firstName + examName + value);
|
||||
judgementSlidesVO.setScoreRate(1);
|
||||
judgementSlidesVOS.add(judgementSlidesVO);
|
||||
}
|
||||
} else if (shapeObj instanceof Pic pic) {
|
||||
if (shapeIndex.equals(String.valueOf(shapeIndexFoFile))) {
|
||||
// 目标对象
|
||||
ShapePic shapePicFunction = new ShapePic();
|
||||
// 获取参数中类型的定义
|
||||
Class<?>[] paramTypes = {Pic.class, CTSlideTiming.class};
|
||||
// 带参数的方法调用示例
|
||||
Method methodWithArgs = shapePicFunction.getClass().getMethod(function, paramTypes);
|
||||
// 实际参数值
|
||||
Object[] arguments = {pic, timing};
|
||||
String value = (String) methodWithArgs.invoke(shapePicFunction, arguments);
|
||||
JudgementSlidesVO judgementSlidesVO = new JudgementSlidesVO();
|
||||
judgementSlidesVO.setContent(content + "@" + value);
|
||||
judgementSlidesVO.setContentIn(firstName + examName + value);
|
||||
judgementSlidesVO.setScoreRate(1);
|
||||
judgementSlidesVOS.add(judgementSlidesVO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (method.equals("slideSetting")) {
|
||||
SlideSetting slideSettingFunction = new SlideSetting();
|
||||
Class<?>[] paramTypes = {SlidePart.class, PresentationMLPackage.class};
|
||||
Method methodWithArgs = slideSettingFunction.getClass().getMethod(function, paramTypes);
|
||||
Object[] arguments = {slidePart, ppt};
|
||||
String value = (String) methodWithArgs.invoke(slideSettingFunction, arguments);
|
||||
JudgementSlidesVO judgementSlidesVO = new JudgementSlidesVO();
|
||||
judgementSlidesVO.setContent(content + "@" + value);
|
||||
judgementSlidesVO.setContentIn(firstName + examName + value);
|
||||
judgementSlidesVO.setScoreRate(1);
|
||||
judgementSlidesVOS.add(judgementSlidesVO);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
package pc.exam.pp.module.judgement.utils.wps_pptx.pptx4j;
|
||||
|
||||
import org.docx4j.dml.CTPositiveSize2D;
|
||||
import org.docx4j.dml.CTTransform2D;
|
||||
import org.docx4j.openpackaging.exceptions.Docx4JException;
|
||||
import org.docx4j.openpackaging.packages.PresentationMLPackage;
|
||||
import org.docx4j.openpackaging.parts.PresentationML.SlideLayoutPart;
|
||||
import org.docx4j.openpackaging.parts.PresentationML.SlideMasterPart;
|
||||
import org.docx4j.openpackaging.parts.PresentationML.SlidePart;
|
||||
import org.pptx4j.pml.CTBackground;
|
||||
import org.pptx4j.pml.CTBackgroundProperties;
|
||||
import org.pptx4j.pml.CTSlideTiming;
|
||||
import org.pptx4j.pml.*;
|
||||
import org.docx4j.dml.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
// 单个幻灯片设置
|
||||
public class SlideSetting {
|
||||
// 幻灯片 版式
|
||||
public static String getSlideLayout(SlidePart slidePart, PresentationMLPackage presentation) throws Docx4JException {
|
||||
SlideLayoutPart layoutPart = slidePart.getSlideLayoutPart();
|
||||
if (layoutPart.getContents().getCSld() != null) {
|
||||
return layoutPart.getContents().getCSld().getName();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
// 设计 主题模板
|
||||
public static String getSlideTheme(SlidePart slidePart, PresentationMLPackage presentation) throws Docx4JException {
|
||||
// 获取第一个幻灯片母版(通常主主题在这里)
|
||||
return "WPS";
|
||||
}
|
||||
|
||||
// 背景填充 填充方式
|
||||
public static String getSlideBackground(SlidePart slidePart, PresentationMLPackage presentation) throws Docx4JException {
|
||||
CTBackground ctBackground = slidePart.getContents().getCSld().getBg();
|
||||
if (ctBackground != null) {
|
||||
CTBackgroundProperties ctBackgroundProperties = ctBackground.getBgPr();
|
||||
return getBackgroundFillType(ctBackgroundProperties);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
private static String getBackgroundFillType(CTBackgroundProperties bgPr) {
|
||||
if (bgPr.getSolidFill() != null) return "纯色填充";
|
||||
if (bgPr.getGradFill() != null) return "渐变填充";
|
||||
if (bgPr.getBlipFill() != null) return "图片填充";
|
||||
if (bgPr.getPattFill() != null) return "图案填充";
|
||||
if (bgPr.getGrpFill() != null) return "组合填充";
|
||||
if (bgPr.getNoFill() != null) return "无填充";
|
||||
return "未知填充类型";
|
||||
}
|
||||
// 背景填充 纯色填充-颜色
|
||||
public static String getSlideBackgroundSolidColor(SlidePart slidePart, PresentationMLPackage presentation) throws Docx4JException {
|
||||
CTBackground ctBackground = slidePart.getContents().getCSld().getBg();
|
||||
if (ctBackground != null) {
|
||||
CTBackgroundProperties ctBackgroundProperties = ctBackground.getBgPr();
|
||||
return getColorValue(ctBackgroundProperties);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
private static String getColorValue(CTBackgroundProperties solidFill) {
|
||||
if (solidFill.getSolidFill().getSrgbClr() != null) {
|
||||
return "RGB颜色: " + solidFill.getSolidFill().getSrgbClr().getVal();
|
||||
} else if (solidFill.getSolidFill().getSchemeClr() != null) {
|
||||
return "主题颜色: " + solidFill.getSolidFill().getSchemeClr().getVal();
|
||||
} else if (solidFill.getSolidFill().getHslClr() != null) {
|
||||
return "HSL颜色";
|
||||
} else if (solidFill.getSolidFill().getSysClr() != null) {
|
||||
return "系统颜色";
|
||||
} else if (solidFill.getSolidFill().getPrstClr() != null) {
|
||||
return "预设颜色: " + solidFill.getSolidFill().getPrstClr().getVal();
|
||||
}
|
||||
return "未知颜色类型";
|
||||
}
|
||||
|
||||
// 背景填充 隐藏背景图形
|
||||
public static String getSlideBackgroundHideShape(SlidePart slidePart, PresentationMLPackage presentation) throws Docx4JException {
|
||||
return "待开发";
|
||||
}
|
||||
|
||||
// 幻灯片切换 切换效果
|
||||
public static String getSlideTransition(SlidePart slidePart, PresentationMLPackage presentation) throws Docx4JException {
|
||||
Sld slides = (Sld) slidePart.getJaxbElement();
|
||||
Sld slide = (Sld) slidePart.getContents();
|
||||
CTSlideTransition ctSlideTransition = slide.getTransition();
|
||||
return "";
|
||||
}
|
||||
// 幻灯片切换 切换声音
|
||||
public static String getSlideTransitionSound(SlidePart slidePart, PresentationMLPackage presentation) throws Docx4JException {
|
||||
Sld slide = (Sld) slidePart.getContents();
|
||||
CTSlideTransition ctSlideTransition = slide.getTransition();
|
||||
CTTransitionSoundAction ctTransitionSoundAction = ctSlideTransition.getSndAc();
|
||||
if (ctTransitionSoundAction != null) {
|
||||
return ctTransitionSoundAction.getStSnd().getSnd().getName();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// 幻灯片切换 切换速度
|
||||
public static String getSlideTransitionSpeed(SlidePart slidePart, PresentationMLPackage presentation) throws Docx4JException {
|
||||
Sld slide = (Sld) slidePart.getContents();
|
||||
CTSlideTransition ctSlideTransition = slide.getTransition();
|
||||
Long speed = ctSlideTransition.getAdvTm();
|
||||
if (speed != null) {
|
||||
return String.valueOf(speed) + "毫秒";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// 隐藏幻灯片
|
||||
public static String getSlideHide(SlidePart slidePart, PresentationMLPackage presentation) throws Docx4JException {
|
||||
Sld sld = slidePart.getJaxbElement();
|
||||
if (sld != null) {
|
||||
return sld.isShow() ? "显示幻灯片" : "隐藏幻灯片";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// 页眉页脚 包含→日期和时间
|
||||
public static String getSlideHeaderFooterDateTime(SlidePart slidePart, PresentationMLPackage presentation) throws Docx4JException {
|
||||
GroupShape spTree = slidePart.getJaxbElement().getCSld().getSpTree();
|
||||
List<Object> shapes = spTree.getSpOrGrpSpOrGraphicFrame();
|
||||
for (Object shapeObj : shapes) {
|
||||
if (shapeObj instanceof Shape) {
|
||||
Shape shape = (Shape) shapeObj;
|
||||
if (shape.getNvSpPr().getCNvPr().getName().equals("日期")) {
|
||||
return "包含";
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
// 页眉页脚 包含→幻灯片编号
|
||||
public static String getSlideHeaderFooterSlideNumber(SlidePart slidePart, PresentationMLPackage presentation) throws Docx4JException {
|
||||
GroupShape spTree = slidePart.getJaxbElement().getCSld().getSpTree();
|
||||
List<Object> shapes = spTree.getSpOrGrpSpOrGraphicFrame();
|
||||
for (Object shapeObj : shapes) {
|
||||
if (shapeObj instanceof Shape) {
|
||||
Shape shape = (Shape) shapeObj;
|
||||
if (shape.getNvSpPr().getCNvPr().getName().equals("编号")) {
|
||||
return "包含";
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
// 页眉页脚 包含→页脚
|
||||
public static String getSlideHeaderFooterFooter(SlidePart slidePart, PresentationMLPackage presentation) throws Docx4JException {
|
||||
GroupShape spTree = slidePart.getJaxbElement().getCSld().getSpTree();
|
||||
List<Object> shapes = spTree.getSpOrGrpSpOrGraphicFrame();
|
||||
for (Object shapeObj : shapes) {
|
||||
if (shapeObj instanceof Shape) {
|
||||
Shape shape = (Shape) shapeObj;
|
||||
if (shape.getNvSpPr().getCNvPr().getName().equals("页脚")) {
|
||||
return "包含";
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -98,23 +98,34 @@ public class SlideUtils {
|
||||
// 常见值:solid, dash, dot, dashDot, lgDash, lgDashDot, lgDashDotDot,
|
||||
// sysDash, sysDot, sysDashDot, sysDashDotDot
|
||||
switch (v) {
|
||||
case SOLID: return "solid";
|
||||
case DASH: return "dash";
|
||||
case DOT: return "dot";
|
||||
case DASH_DOT: return "dashDot";
|
||||
case LG_DASH: return "lgDash";
|
||||
case LG_DASH_DOT: return "lgDashDot";
|
||||
case LG_DASH_DOT_DOT:return "lgDashDotDot";
|
||||
case SYS_DASH: return "sysDash";
|
||||
case SYS_DOT: return "sysDot";
|
||||
case SYS_DASH_DOT: return "sysDashDot";
|
||||
case SYS_DASH_DOT_DOT:return "sysDashDotDot";
|
||||
default: return v.value(); // 兜底:返回原枚举字符串
|
||||
case SOLID:
|
||||
return "solid";
|
||||
case DASH:
|
||||
return "dash";
|
||||
case DOT:
|
||||
return "dot";
|
||||
case DASH_DOT:
|
||||
return "dashDot";
|
||||
case LG_DASH:
|
||||
return "lgDash";
|
||||
case LG_DASH_DOT:
|
||||
return "lgDashDot";
|
||||
case LG_DASH_DOT_DOT:
|
||||
return "lgDashDotDot";
|
||||
case SYS_DASH:
|
||||
return "sysDash";
|
||||
case SYS_DOT:
|
||||
return "sysDot";
|
||||
case SYS_DASH_DOT:
|
||||
return "sysDashDot";
|
||||
case SYS_DASH_DOT_DOT:
|
||||
return "sysDashDotDot";
|
||||
default:
|
||||
return v.value(); // 兜底:返回原枚举字符串
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ——— 内部:拿到 spPr/effectLst/reflection ——— */
|
||||
public static CTReflectionEffect getReflection(org.pptx4j.pml.Shape shape) {
|
||||
if (shape == null || shape.getSpPr() == null) return null;
|
||||
@@ -124,14 +135,24 @@ public class SlideUtils {
|
||||
// 如遇到效果写在 effectDag,可再补充从 spPr.getEffectDag() 解析。
|
||||
}
|
||||
|
||||
public static CTReflectionEffect getReflectionPic(org.pptx4j.pml.Pic shape) {
|
||||
if (shape == null || shape.getSpPr() == null) return null;
|
||||
CTShapeProperties spPr = shape.getSpPr();
|
||||
CTEffectList eff = spPr.getEffectLst();
|
||||
return (eff != null) ? eff.getReflection() : null;
|
||||
// 如遇到效果写在 effectDag,可再补充从 spPr.getEffectDag() 解析。
|
||||
}
|
||||
|
||||
/* ——— 工具 ——— */
|
||||
public static double emuToPt(BigInteger emu) {
|
||||
if (emu == null) return 0.0;
|
||||
return emu.doubleValue() / 12700.0; // 1 pt = 12700 EMU
|
||||
}
|
||||
|
||||
public static double to100k(BigInteger v, int def) {
|
||||
return v == null ? def : v.doubleValue();
|
||||
}
|
||||
|
||||
public static String fmt1(double d) {
|
||||
return new DecimalFormat("#.##").format(d); // 保留 1~2 位,去掉多余 0
|
||||
}
|
||||
@@ -141,6 +162,7 @@ public class SlideUtils {
|
||||
if (val == null || val.length != 3) return "000000";
|
||||
return String.format("%02X%02X%02X", val[0] & 0xFF, val[1] & 0xFF, val[2] & 0xFF);
|
||||
}
|
||||
|
||||
public static String extractAlpha(java.util.List<CTPositiveFixedPercentage> alphas) {
|
||||
if (alphas != null && !alphas.isEmpty()) {
|
||||
double pct = alphas.get(0).getVal() / 1000.0;
|
||||
@@ -148,10 +170,47 @@ public class SlideUtils {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int iOr0(BigInteger bi) {
|
||||
return bi == null ? 0 : bi.intValue();
|
||||
}
|
||||
|
||||
public static String fmt(double d) {
|
||||
return (Math.round(d * 100.0) / 100.0) + ""; // 保留 2 位小数
|
||||
}
|
||||
|
||||
public static String getShadowLikeDescription(CTReflectionEffect reflection) {
|
||||
if (reflection == null) return "无阴影效果";
|
||||
|
||||
// 1. 判断是否为底部反射(类似阴影)
|
||||
boolean isBottomReflection =
|
||||
(reflection.getAlgn().value().equals("b")) ||
|
||||
(reflection.getSy() < 0);
|
||||
|
||||
if (!isBottomReflection) {
|
||||
return "特殊反射效果";
|
||||
}
|
||||
|
||||
// 2. 生成类似阴影的描述
|
||||
StringBuilder desc = new StringBuilder("阴影效果-");
|
||||
|
||||
// 模糊程度
|
||||
double blurPt = reflection.getBlurRad() / 12700.0;
|
||||
if (blurPt > 5) desc.append("强模糊");
|
||||
else if (blurPt > 2) desc.append("模糊");
|
||||
else desc.append("清晰");
|
||||
|
||||
// 距离/强度
|
||||
double distance = reflection.getEndPos() / 1000.0;
|
||||
if (distance > 40) desc.append("-大距离");
|
||||
else if (distance > 20) desc.append("-中距离");
|
||||
else desc.append("-小距离");
|
||||
|
||||
// 透明度
|
||||
int alpha = reflection.getStA();
|
||||
if (alpha < 30000) desc.append("-高透明");
|
||||
else if (alpha < 60000) desc.append("-半透明");
|
||||
|
||||
return desc.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,4 +14,6 @@ public class JudgementSlidesVO {
|
||||
// 考点名称
|
||||
private String contentIn;
|
||||
|
||||
private int scoreRate;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user