【新增】 PPTX 动画考点优化

This commit is contained in:
dlaren
2025-08-17 19:32:50 +08:00
parent 9ef12b439b
commit 1c0ba2b8a0
3 changed files with 259 additions and 900 deletions

View File

@@ -7,6 +7,7 @@ import org.docx4j.jaxb.XPathBinderAssociationIsPartialException;
import org.pptx4j.pml.*;
import java.math.BigInteger;
import java.util.List;
public class ShapePage {
@@ -79,6 +80,7 @@ public class ShapePage {
}
return "";
}
/// 替换文字 说明
public static String getShapeText(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
return "待开发";
@@ -266,6 +268,7 @@ public class ShapePage {
// 3) 未设置 → 视为实线
return "solid";
}
// 形状线条 开始箭头类型
public static String getShapeLineStartArrow(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
CTShapeProperties spPr = sp.getSpPr();
@@ -277,14 +280,17 @@ public class ShapePage {
}
return "无箭头";
}
// 形状线条 开始箭头粗细
public static String getShapeLineStartArrowWidth(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
return "待开发";
}
// 形状线条 结尾箭头类型
public static String getShapeLineEndArrow(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
return "待开发";
}
// 形状线条 结尾箭头粗细
public static String getShapeLineEndArrowWidth(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
return "待开发";
@@ -391,14 +397,17 @@ public class ShapePage {
CTSoftEdgesEffect se = getSoftEdge(sp);
return (se != null) ? String.valueOf(se.getRad()) : null;
}
// 形状效果 三维效果→绘制
public static String getShape3DEffectDraw(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
return "待开发";
}
// 形状效果 三维格式→效果
public static String getShape3DEffect(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
return "待开发";
}
// 形状效果 三维旋转→效果
public static String getShape3DRotation(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
return "待开发";
@@ -415,440 +424,46 @@ public class ShapePage {
// 动画 效果
// 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;
}
long spId = sp.getNvSpPr().getCNvPr().getId();
CTTimeNodeList ctTimeNodeList = timing.getTnLst();
if (ctTimeNodeList == null) return "无动画";
// 第一层
List<Object> parOrSeqOrExcl = ctTimeNodeList.getParOrSeqOrExcl();
String value = getAniationInfo(parOrSeqOrExcl, null, String.valueOf(spId), "type");
if (!value.isEmpty()) {
return value;
}
return null;
return "";
}
/* 如果对象是某种 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 "位置动画Xppt_x";
if ("ppt_y".equalsIgnoreCase(attr)) return "位置动画Yppt_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));
public static String getAniationInfo(List<Object> objects, List<Object> upObjects, String spId, String parameter) {
for (Object object : objects) {
if (object instanceof CTTLSetBehavior) {
String spIds = ((CTTLSetBehavior) object).getCBhvr().getTgtEl().getSpTgt().getSpid();
// 判断ID是否一致
if (spIds.equals(spId)) {
// 持续时间
if (parameter.equals("dur")) {
return ((CTTLSetBehavior) object).getCBhvr().getCTn().getDur();
}
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();
// 获取动画效果
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(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();
}
}
}
}
}
}
}
// 向上获取延迟
for (Object upObject : upObjects) {
if (upObject instanceof CTTLTimeNodeParallel) {
// 获取动画效果
if (parameter.equals("type")) {
Integer type = ((CTTLTimeNodeParallel) upObject).getCTn().getPresetSubtype();
return String.valueOf(type);
}
// 触发方式
if (parameter.equals("function")) {
return ((CTTLTimeNodeParallel) upObject).getCTn().getNodeType().value();
}
// 获取延迟方法
for (Object condObject : ((CTTLTimeNodeParallel) upObject).getCTn().getStCondLst().getCond()) {
if (condObject instanceof CTTLTimeCondition) {
// 获取延迟
if (parameter.equals("delay")) {
return ((CTTLTimeCondition) condObject).getDelay();
}
}
}
@@ -856,10 +471,69 @@ public class ShapePage {
}
}
}
if (object instanceof CTTLTimeNodeParallel obj) {
String result = getAniationInfo(obj.getCTn().getChildTnLst().getParOrSeqOrExcl(), objects, spId, parameter);
if (!result.isEmpty()) {
return result;
}
}
if (object instanceof CTTLTimeNodeSequence obj) {
String result = getAniationInfo(obj.getCTn().getChildTnLst().getParOrSeqOrExcl(), objects, spId, parameter);
if (!result.isEmpty()) {
return result;
}
}
}
return "";
}
// 动画-方向
public static String getAnimateDirection(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
return "待开发";
}
// 动画 触发方式
public static String getAnimateTrigger(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
long spId = sp.getNvSpPr().getCNvPr().getId();
CTTimeNodeList ctTimeNodeList = timing.getTnLst();
if (ctTimeNodeList == null) return "无动画";
// 第一层
List<Object> parOrSeqOrExcl = ctTimeNodeList.getParOrSeqOrExcl();
String value = getAniationInfo(parOrSeqOrExcl, null, String.valueOf(spId), "function");
if (!value.isEmpty()) {
return value;
}
return "";
}
// 动画 持续时间
public static String getAnimationDuration(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
long spId = sp.getNvSpPr().getCNvPr().getId();
CTTimeNodeList ctTimeNodeList = timing.getTnLst();
if (ctTimeNodeList == null) return "无动画";
// 第一层
List<Object> parOrSeqOrExcl = ctTimeNodeList.getParOrSeqOrExcl();
String value = getAniationInfo(parOrSeqOrExcl, null, String.valueOf(spId), "dur");
if (!value.isEmpty()) {
return value;
}
return "";
}
// 动画 延迟
public static String getAnimationDelay(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
long spId = sp.getNvSpPr().getCNvPr().getId();
CTTimeNodeList ctTimeNodeList = timing.getTnLst();
if (ctTimeNodeList == null) return "无动画";
// 第一层
List<Object> parOrSeqOrExcl = ctTimeNodeList.getParOrSeqOrExcl();
String value = getAniationInfo(parOrSeqOrExcl, null, String.valueOf(spId), "delay");
if (!value.isEmpty()) {
return value;
}
return "";
}
/// 形状动作,鼠标单机-动作
@@ -1223,6 +897,7 @@ public class ShapePage {
}
return "0";
}
/// 段落 缩进→度量值
public static String getTextBoxParagraphIndentMeasure(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
if (sp.getTxBody() != null) {
@@ -1236,6 +911,7 @@ public class ShapePage {
}
return "0";
}
/// 段落 间距→段前
public static String getTextBoxParagraphSpaceBefore(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
if (sp.getTxBody() != null) {
@@ -1249,6 +925,7 @@ public class ShapePage {
}
return "";
}
/// 段落 间距→段后
public static String getTextBoxParagraphSpaceAfter(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
if (sp.getTxBody() != null) {
@@ -1262,6 +939,7 @@ public class ShapePage {
}
return "";
}
/// 段落 间距→行距→类型
public static String getTextBoxParagraphSpaceLine(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
if (sp.getTxBody() != null) {
@@ -1278,6 +956,7 @@ public class ShapePage {
}
return "";
}
/// 段落 间距→行距→设置值
public static String getTextBoxParagraphSpaceLineValue(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
if (sp.getTxBody() != null) {
@@ -1285,7 +964,7 @@ public class ShapePage {
// 遍历所有段落
for (CTTextParagraph paragraph : textBody.getP()) {
if (paragraph.getPPr().getLnSpc().getSpcPct() != null) {
return paragraph.getPPr().getLnSpc().getSpcPct().getVal() / 100000 + "倍行距"; // EMU 转 pt
return paragraph.getPPr().getLnSpc().getSpcPct().getVal() / 100000 + "倍行距"; // EMU 转 pt
} else if (paragraph.getPPr().getLnSpc().getSpcPts() != null) {
return paragraph.getPPr().getLnSpc().getSpcPts().getVal() / 10 + "磅固定行距"; // EMU 转 pt
}
@@ -1294,6 +973,7 @@ public class ShapePage {
}
return "";
}
/// 段落 项目符号和编号→类型
public static String getTextBoxParagraphSymbol(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
return "待开发";
@@ -1331,6 +1011,7 @@ public class ShapePage {
}
return "";
}
/// 文本填充 纯色填充→颜色
public static String getTextBoxParagraphFillColor(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
if (sp.getTxBody() != null) {
@@ -1355,26 +1036,32 @@ public class ShapePage {
}
return "";
}
/// 文本填充 渐变填充→效果
public static String getTextBoxParagraphFillGradient(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
return "待开发";
}
/// 文本填充 图片填充→效果
public static String getTextBoxParagraphFillImage(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
return "待开发";
}
/// 文本填充 纹理填充→效果
public static String getTextBoxParagraphFillTexture(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
return "待开发";
}
/// 文本填充 图案填充→效果
public static String getTextBoxParagraphFillPattern(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
return "待开发";
}
/// 文本填充 填充透明度
public static String getTextBoxParagraphFillOpacity(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
return "待开发";
}
/// 文本轮廓 颜色
public static String getTextBoxParagraphOutlineColor(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
if (sp.getTxBody() != null) {
@@ -1391,6 +1078,7 @@ public class ShapePage {
return "";
}
/// 文本轮廓 透明度
public static String getTextBoxParagraphOutlineOpacity(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
if (sp.getTxBody() != null) {
@@ -1404,8 +1092,7 @@ public class ShapePage {
int alpha = 0;
if (fill.getSrgbClr() != null) {
alpha = Integer.parseInt(fill.getSrgbClr().getVal());
}
else if (fill.getSchemeClr() != null) {
} else if (fill.getSchemeClr() != null) {
alpha = fill.getSchemeClr().getVal().ordinal();
}
return String.valueOf((100000 - alpha) / 1000.0);
@@ -1415,6 +1102,7 @@ public class ShapePage {
}
return "";
}
/// 文本轮廓 宽度
public static String getTextBoxParagraphOutlineWidth(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
if (sp.getTxBody() != null) {
@@ -1434,6 +1122,7 @@ public class ShapePage {
}
return "";
}
/// 文本轮廓 高度
public static String getTextBoxParagraphOutlineHeight(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
if (sp.getTxBody() != null) {
@@ -1453,10 +1142,12 @@ public class ShapePage {
}
return "";
}
/// 文本轮廓 复合类型
public static String getTextBoxParagraphOutlineType(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
return "待开发";
}
/// 文本轮廓 短划线类型
public static String getTextBoxParagraphOutlineDashType(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
return "待开发";
@@ -1481,6 +1172,7 @@ public class ShapePage {
}
return "";
}
// 文字效果 阴影→预设
// 文字效果 阴影→效果
public static String getTextBoxParagraphShadowEffect(org.pptx4j.pml.Shape sp, CTSlideTiming timing) {
@@ -1525,14 +1217,17 @@ public class ShapePage {
}
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 "待开发";

View File

@@ -5,6 +5,7 @@ import org.docx4j.dml.*;
import org.pptx4j.pml.*;
import java.math.BigInteger;
import java.util.List;
public class ShapePic {
@@ -409,440 +410,46 @@ public class ShapePic {
// 动画 效果
// 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;
}
long spId = sp.getNvPicPr().getCNvPr().getId();
CTTimeNodeList ctTimeNodeList = timing.getTnLst();
if (ctTimeNodeList == null) return "无动画";
// 第一层
List<Object> parOrSeqOrExcl = ctTimeNodeList.getParOrSeqOrExcl();
String value = getAniationInfo(parOrSeqOrExcl, null, String.valueOf(spId), "type");
if (!value.isEmpty()) {
return value;
}
return null;
return "";
}
/* 如果对象是某种 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 "位置动画Xppt_x";
if ("ppt_y".equalsIgnoreCase(attr)) return "位置动画Yppt_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));
public static String getAniationInfo(List<Object> objects, List<Object> upObjects, String spId, String parameter) {
for (Object object : objects) {
if (object instanceof CTTLSetBehavior) {
String spIds = ((CTTLSetBehavior) object).getCBhvr().getTgtEl().getSpTgt().getSpid();
// 判断ID是否一致
if (spIds.equals(spId)) {
// 持续时间
if (parameter.equals("dur")) {
return ((CTTLSetBehavior) object).getCBhvr().getCTn().getDur();
}
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();
}
}
}
}
}
}
}
// 向上获取延迟
for (Object upObject : upObjects) {
if (upObject instanceof CTTLTimeNodeParallel) {
// 获取动画效果
if (parameter.equals("type")) {
Integer type = ((CTTLTimeNodeParallel) upObject).getCTn().getPresetSubtype();
return String.valueOf(type);
}
// 触发方式
if (parameter.equals("function")) {
return ((CTTLTimeNodeParallel) upObject).getCTn().getNodeType().value();
}
// 获取延迟方法
for (Object condObject : ((CTTLTimeNodeParallel) upObject).getCTn().getStCondLst().getCond()) {
if (condObject instanceof CTTLTimeCondition) {
// 获取延迟
if (parameter.equals("delay")) {
return ((CTTLTimeCondition) condObject).getDelay();
}
}
}
@@ -850,6 +457,66 @@ public class ShapePic {
}
}
}
if (object instanceof CTTLTimeNodeParallel obj) {
String result = getAniationInfo(obj.getCTn().getChildTnLst().getParOrSeqOrExcl(), objects, spId, parameter);
if (!result.isEmpty()) {
return result;
}
}
if (object instanceof CTTLTimeNodeSequence obj) {
String result = getAniationInfo(obj.getCTn().getChildTnLst().getParOrSeqOrExcl(), objects, spId, parameter);
if (!result.isEmpty()) {
return result;
}
}
}
return "";
}
// 动画-方向
public static String getAnimateDirection(org.pptx4j.pml.Pic sp, CTSlideTiming timing) {
return "待开发";
}
// 动画 触发方式
public static String getAnimateTrigger(org.pptx4j.pml.Pic sp, CTSlideTiming timing) {
long spId = sp.getNvPicPr().getCNvPr().getId();
CTTimeNodeList ctTimeNodeList = timing.getTnLst();
if (ctTimeNodeList == null) return "无动画";
// 第一层
List<Object> parOrSeqOrExcl = ctTimeNodeList.getParOrSeqOrExcl();
String value = getAniationInfo(parOrSeqOrExcl, null, String.valueOf(spId), "function");
if (!value.isEmpty()) {
return value;
}
return "";
}
// 动画 持续时间
public static String getAnimationDuration(org.pptx4j.pml.Pic sp, CTSlideTiming timing) {
long spId = sp.getNvPicPr().getCNvPr().getId();
CTTimeNodeList ctTimeNodeList = timing.getTnLst();
if (ctTimeNodeList == null) return "无动画";
// 第一层
List<Object> parOrSeqOrExcl = ctTimeNodeList.getParOrSeqOrExcl();
String value = getAniationInfo(parOrSeqOrExcl, null, String.valueOf(spId), "dur");
if (!value.isEmpty()) {
return value;
}
return "";
}
// 动画 延迟
public static String getAnimationDelay(org.pptx4j.pml.Pic sp, CTSlideTiming timing) {
long spId = sp.getNvPicPr().getCNvPr().getId();
CTTimeNodeList ctTimeNodeList = timing.getTnLst();
if (ctTimeNodeList == null) return "无动画";
// 第一层
List<Object> parOrSeqOrExcl = ctTimeNodeList.getParOrSeqOrExcl();
String value = getAniationInfo(parOrSeqOrExcl, null, String.valueOf(spId), "delay");
if (!value.isEmpty()) {
return value;
}
return "";
}

View File

@@ -3,6 +3,13 @@ package pc.exam.pp.module.judgement.utils.wps_pptx.pptx4j;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.xmlbeans.XmlCursor;
import org.docx4j.openpackaging.packages.OpcPackage;
import org.docx4j.openpackaging.packages.PresentationMLPackage;
import org.docx4j.openpackaging.parts.PresentationML.SlidePart;
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.utils.wps_pptx.pptx4j.vo.SlideDataInfoVO;
@@ -18,52 +25,42 @@ public class SlideConversion {
// 3、获取第三层目录 幻灯片设置/形状 - 幻灯片母版 - 幻灯片设置 - 文件操作
public static List<SlideDataInfoVO> SlideDataInfos(MultipartFile file) throws Exception {
List<SlideDataInfoVO> dataInfoVOS = new ArrayList<>();
try (InputStream inputStream = file.getInputStream();
XMLSlideShow pptxXml = new XMLSlideShow(inputStream)) {
int index = 0;
try (InputStream inputStream = file.getInputStream()) {
PresentationMLPackage ppt =
(PresentationMLPackage) OpcPackage.load(inputStream);
// 获取页数
List<SlidePart> slideParts = ppt.getMainPresentationPart().getSlideParts();
int slideIndexFoFile = 0;
String firstId = getStringRandom();
setSlideDataInfo(firstId, "", "幻灯片", "slide", "", false, dataInfoVOS);
for (XSLFSlide slides : pptxXml.getSlides()){
index += 1;
for (SlidePart slidePart : slideParts) {
slideIndexFoFile ++;
String secondId = getStringRandom();
setSlideDataInfo(secondId, firstId, ""+index+"", "sld", String.valueOf(index), true, dataInfoVOS);
setSlideDataInfo(secondId, firstId, ""+slideIndexFoFile+"", "sld", String.valueOf(slideIndexFoFile), true, dataInfoVOS);
// 获取形状
GroupShape spTree = slidePart.getJaxbElement().getCSld().getSpTree();
List<Object> shapes = spTree.getSpOrGrpSpOrGraphicFrame();
int slideIndexFoShape = 0;
// 第三层
String thirdId = getStringRandom();
int indexCnvPr = 1;
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()) {
XmlCursor cNvPrXml = spCursor.newCursor();
cNvPrXml.selectPath("declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//p:cNvPr/@name");
if (cNvPrXml.toNextSelection()) {
String name = cNvPrXml.getTextValue();
String fourId = getStringRandom();
setSlideDataInfo(fourId, secondId, "形状"+indexCnvPr+"->"+name, "shape", String.valueOf(index) + "_" + String.valueOf(indexCnvPr), true, dataInfoVOS);
indexCnvPr += 1;
}
}
XmlCursor picCursor = slides.getXmlObject().newCursor();
System.out.println(picCursor.xmlText());
picCursor.selectPath("declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//p:pic");
int indexCnvPrPic = 1;
while (picCursor.toNextSelection()) {
setSlideDataInfo(thirdId, secondId, "幻灯片设置", "slideSetting", String.valueOf(slideIndexFoFile) + "_0", true, dataInfoVOS);
for (Object shapeObj : shapes) {
slideIndexFoShape ++;
// 形状
String fourId = getStringRandom();
setSlideDataInfo(fourId, secondId, "图像"+indexCnvPrPic+"->图像", "shapePic", String.valueOf(indexCnvPrPic), true, dataInfoVOS);
indexCnvPrPic += 1;
if (shapeObj instanceof Shape) {
setSlideDataInfo(fourId, secondId, "形状"+slideIndexFoShape+"->"+((Shape) shapeObj).getNvSpPr().getCNvPr().getName(), "shape", String.valueOf(slideIndexFoFile) + "_" + String.valueOf(slideIndexFoShape), true, dataInfoVOS);
}
if (shapeObj instanceof Pic) {
setSlideDataInfo(fourId, secondId, "形状"+slideIndexFoShape+"->"+((Pic) shapeObj).getNvPicPr().getCNvPr().getName(), "shape", String.valueOf(slideIndexFoFile) + "_" + String.valueOf(slideIndexFoShape), true, dataInfoVOS);
}
}
}
// 设置
String firstIds = getStringRandom();
setSlideDataInfo(firstIds, "", "设置", "presentation", String.valueOf(0), false, dataInfoVOS);
String secondIds = getStringRandom();
setSlideDataInfo(secondIds, firstIds, "幻灯片设置", "presentation", String.valueOf(0), true, dataInfoVOS);
// 母版
// String dFirstId = getStringRandom();
// setPptxInfo("母版", "p:sld", "p:sld", filePath, dFirstId, "0", pptxInfoReqVos);
} catch (Exception e) {
throw new RuntimeException(e);
e.printStackTrace();
}
return dataInfoVOS;
}