dotnet OpenXML 读取 PPT 主序列进入退出强调动画
本文告诉大家如何读取 PPT 文件里面,放在主动画序列 MainSequence 的进入和退出和强调的动画,和在 OpenXML 里面的存放方式
如以下的课件内容,给一个元素添加了进入强调退出的动画,动画之间没有相关影响,通过点击触发动画,如下图

大概的动画内容如下
<p:timing>
<p:tnLst>
<p:par>
<p:cTn id="1" dur="indefinite" restart="never" nodeType="tmRoot">
<p:childTnLst>
<p:seq concurrent="1" nextAc="seek">
<p:cTn id="2" dur="indefinite" nodeType="mainSeq">
<p:childTnLst>
<p:par>
<p:cTn id="3" fill="hold">
<p:stCondLst>
<p:cond delay="indefinite" />
</p:stCondLst>
<p:childTnLst>
<p:par>
<p:cTn id="4" fill="hold">
<p:stCondLst>
<p:cond delay="0" />
</p:stCondLst>
<p:childTnLst>
<p:par>
<p:cTn id="5" presetID="1" presetClass="entr" presetSubtype="0" fill="hold" grpId="0" nodeType="clickEffect">
<p:stCondLst>
<p:cond delay="0" />
</p:stCondLst>
<p:childTnLst>
<!-- 忽略代码-->
</p:childTnLst>
</p:cTn>
</p:par>
</p:childTnLst>
</p:cTn>
</p:par>
</p:childTnLst>
</p:cTn>
</p:par>
<p:par>
<p:cTn id="7" fill="hold">
<p:stCondLst>
<p:cond delay="indefinite" />
</p:stCondLst>
<p:childTnLst>
<p:par>
<p:cTn id="8" fill="hold">
<p:stCondLst>
<p:cond delay="0" />
</p:stCondLst>
<p:childTnLst>
<p:par>
<p:cTn id="9" presetID="25" presetClass="emph" presetSubtype="0" fill="hold" grpId="2" nodeType="clickEffect">
<p:stCondLst>
<p:cond delay="0" />
</p:stCondLst>
<p:childTnLst>
<!-- 忽略代码-->
</p:childTnLst>
</p:cTn>
</p:par>
</p:childTnLst>
</p:cTn>
</p:par>
</p:childTnLst>
</p:cTn>
</p:par>
<p:par>
<p:cTn id="14" fill="hold">
<p:stCondLst>
<p:cond delay="indefinite" />
</p:stCondLst>
<p:childTnLst>
<p:par>
<p:cTn id="15" fill="hold">
<p:stCondLst>
<p:cond delay="0" />
</p:stCondLst>
<p:childTnLst>
<p:par>
<p:cTn id="16" presetID="10" presetClass="exit" presetSubtype="0" fill="hold" grpId="1" nodeType="clickEffect">
<!-- 忽略代码-->
</p:cTn>
</p:par>
</p:childTnLst>
</p:cTn>
</p:par>
</p:childTnLst>
</p:cTn>
</p:par>
</p:childTnLst>
</p:cTn>
<!-- 忽略代码-->
</p:seq>
</p:childTnLst>
</p:cTn>
</p:par>
</p:tnLst>
<!-- 忽略代码-->
</p:timing>
根据 cTn 也就是 OpenXML sdk 定义的 CommonTimeNode 类型的 PresetClass 属性可以了解到,动画 id 是 5 的是进入动画,动画 id 是 9 的是强调动画,动画 id 是 10 的是退出动画
可以看到在 PPT 里面,多个不同的动画,这些动画没有关联,也就是没有在上一个播放完成后,而是通过点击触发的,放在主序列的动画的内容大概如下
<p:timing>
<p:tnLst>
<p:par>
<p:cTn id="1" dur="indefinite" restart="never" nodeType="tmRoot">
<p:childTnLst>
<p:seq concurrent="1" nextAc="seek">
<p:cTn id="2" dur="indefinite" nodeType="mainSeq">
<p:childTnLst>
<p:par>
<!-- 进入动画-->
</p:par>
<p:par>
<!-- 强调动画-->
</p:par>
<p:par>
<!-- 退出动画-->
</p:par>
</p:childTnLst>
</p:cTn>
<!-- 忽略代码-->
</p:seq>
</p:childTnLst>
</p:cTn>
</p:par>
</p:tnLst>
<!-- 忽略代码-->
</p:timing>
如上面的内容,大概可以理解存放的方式了,只是在 PPT 里面,有多个 ParallelTimeNode 和 CommonTimeNode 的嵌套。从 mainSeq 也就是 MainSequence 主动画序列以下,获取到的实际的进入动画,是经过了如下路径才能获取
cTn (mainSeq) -> childTnLst -> par -> cTn (id="3") -> childTnLst -> par -> cTn (id="4") -> childTnLst -> par -> cTn (id="5" presetClass="entr")
可以使用以下代码读取
static void Main(string[] args)
{
using var presentationDocument =
DocumentFormat.OpenXml.Packaging.PresentationDocument.Open("Test.pptx", false);
var presentationPart = presentationDocument.PresentationPart;
var slidePart = presentationPart!.SlideParts.First();
var slide = slidePart.Slide;
var timing = slide.Timing;
// 第一级里面默认只有一项
var commonTimeNode = timing?.TimeNodeList?.ParallelTimeNode?.CommonTimeNode;
if (commonTimeNode?.NodeType?.Value == TimeNodeValues.TmingRoot)
{
// 这是符合约定
// nodeType="tmRoot"
}
if (commonTimeNode?.ChildTimeNodeList == null) return;
// 理论上只有一项,而且一定是 SequenceTimeNode 类型
var sequenceTimeNode = commonTimeNode.ChildTimeNodeList.GetFirstChild<SequenceTimeNode>();
var mainSequenceTimeNode = sequenceTimeNode.CommonTimeNode;
if (mainSequenceTimeNode?.NodeType?.Value == TimeNodeValues.MainSequence)
{
// [TimeLine 对象 (PowerPoint) | Microsoft Docs](https://docs.microsoft.com/zh-cn/office/vba/api/PowerPoint.TimeLine )
// MainSequence 主动画序列
var mainParallelTimeNode = mainSequenceTimeNode.ChildTimeNodeList;
foreach (var openXmlElement in mainParallelTimeNode)
{
// 并行关系的
if (openXmlElement is ParallelTimeNode parallelTimeNode)
{
var timeNode = parallelTimeNode.CommonTimeNode.ChildTimeNodeList
.GetFirstChild<ParallelTimeNode>().CommonTimeNode.ChildTimeNodeList
.GetFirstChild<ParallelTimeNode>().CommonTimeNode;
switch (timeNode.PresetClass.Value)
{
case TimeNodePresetClassValues.Entrance:
// 进入动画
break;
case TimeNodePresetClassValues.Exit:
// 退出动画
break;
case TimeNodePresetClassValues.Emphasis:
// 强调动画
break;
case TimeNodePresetClassValues.Path:
// 路由动画
break;
case TimeNodePresetClassValues.Verb:
break;
case TimeNodePresetClassValues.MediaCall:
// 播放动画
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
}
// 文档规定,必须存在一个AttributeNameList列表,一定存在AttributeName元素,如果有多个只取第一个元素。
// 见"[MS-OI 29500].PDF 第2.1.1137章节(g选项)"
}
可以通过如下方式获取本文的源代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 2c06ddf74e45c31ad7842dd06dc09bcc67b6142e
以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
获取代码之后,进入 PptxDemo 文件夹
以上的测试使用的 PPT 课件也放在此文件夹
本文的属性是依靠 dotnet OpenXML 解压缩文档为文件夹工具 工具协助测试的,这个工具是开源免费的工具,欢迎使用
更多请看 Office 使用 OpenXML SDK 解析文档博客目录
dotnet OpenXML 读取 PPT 主序列进入退出强调动画的更多相关文章
- dotnet OpenXML 读取 PPT 内嵌 ole 格式 Excel 表格的信息
在 Office 中,可以在 PPT 里面插入表格,插入表格有好多不同的方法,对应 OpenXML 文档存储的更多不同的方式.本文来介绍如何读取 PPT 内嵌 ole 格式的 xls+ 表格的方法 在 ...
- dotnet OpenXML 转换 PathFillModeValues 为颜色特效
在 OpenXml 预设形状,有一些形状设置了 PathFillModeValues 枚举,此枚举提供了亮暗的蒙层特效.具体的特效是让形状选择一个画刷,在画刷上加上特效.如立体几何 Cube 形状,在 ...
- java使用poi读取ppt文件和poi读取excel、word示例
java使用poi读取ppt文件和poi读取excel.word示例 http://www.jb51.net/article/48092.htm
- DotNet加密方式解析--散列加密
没时间扯淡类,赶紧上车吧. 在现代社会中,信息安全对于每一个人都是至关重要的,例如我们的银行账户安全.支付宝和微信账户安全.以及邮箱等等,说到信息安全,那就必须得提到加密技术,至于加密的一些相关概念, ...
- OpenXml读取word内容(二)
注意事项 上一篇已经说明,这次就不一一说了,直接来正文: word内容 相关代码 方法1 static void Main(string[] args) { string wordPathStr = ...
- OpenXml读取word内容(一)
OpenXml读取word内容注意事项 1.使用OpenXml读取word内容,word后缀必须是".docx":如果word后缀是".doc"需要转成&quo ...
- OpenXml读取word内容注意事项
OpenXml读取word内容注意事项 1.使用OpenXml读取word内容,word后缀必须是".docx":如果word后缀是".doc"需要转成&quo ...
- php 读取excel 时间列
用PHP做一个导入excel功能,发现读取excel时间列的时候总是数据不对,去网上查找了这个函数,转换了一下就好了,真尼玛迷茫了,什么情况,先记录一下,以后再研究吧. 函数如下: function ...
- 使用openxml读取xml数据
xml的数据格式如下: <?xml version="1.0"?> <Language Name="Chinese"> <Loca ...
- Java读取Excel指定列的数据详细教程和注意事项
本文使用jxl.jar工具类库实现读取Excel中指定列的数据. jxl.jar是通过java操作excel表格的工具类库,是由java语言开发而成的.这套API是纯Java的,并不依赖Windows ...
随机推荐
- 2024-03-20:用go语言,自 01背包问世之后,小 A 对此深感兴趣。 一天,小 A 去远游,却发现他的背包不同于 01 背包,他的物品大致可分为 k 组。 每组中的物品只能选择1件,现在他想
2024-03-20:用go语言,自 01背包问世之后,小 A 对此深感兴趣. 一天,小 A 去远游,却发现他的背包不同于 01 背包,他的物品大致可分为 k 组. 每组中的物品只能选择1件,现在他想 ...
- 爬虫实战:探索XPath爬虫技巧之热榜新闻
之前我们已经详细讨论了如何使用BeautifulSoup这个强大的工具来解析HTML页面,另外还介绍了利用在线工具来抓取HTTP请求以获取数据的方法.在今天的学习中,我们将继续探讨另一种常见的网络爬虫 ...
- Clang开发注意事项
Clang tools need their builtin headers and search for them the same way Clang does. Thus, the defaul ...
- C# SM2
Cipher using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle. ...
- vue项目 nginx部署
nginx.conf中的server配置片段 server { listen 8080 ;#默认端口是80,如果端口没被占用可以不用修改 server_name localhost; #charset ...
- 看看谷歌如何在目标检测任务使用预训练权值 | CVPR 2022
论文提出能够适配硬件加速的动态网络DS-Net,通过提出的double-headed动态门控来实现动态路由.基于论文提出的高性能网络设计和IEB.SGS训练策略,仅用1/2-1/4的计算量就能达到静态 ...
- 汇编语言-int指令
int 指令 int 指令的格式为:int n,n为中断类型码,它的功能是引发终端过程. CPU执行int n指令,相当于引发一个n号中断的中断过程,执行过程如下. 取中断类型码n: 标志寄存器入栈, ...
- 11.硬核的volatile考点分析
大家好,我是王有志.关注王有志,一起聊技术,聊游戏,聊在外漂泊的生活. 今天我们学习并发编程中另一个重要的关键字volatile,虽然面试中它的占比低于synchronized,但依旧是不可忽略的内容 ...
- 【放假第1天】采购季倒计时 2G 50/年,4G 618/3年 云服务器选购攻略 阿里云 腾讯云 京东云对比 搭建网站、数据分析
更新日期:4月4日(阿里云价格回调,京东云采购季持续进行) <最新对比表>已更新在文章头部-腾讯云文档,文章具有时效性,请以腾讯文档为准! https://docs.qq.com/do ...
- OpenHarmony源码解析之电话子系统——通话流程
(以下内容来自开发者分享,不代表 OpenHarmony 项目群工作委员会观点) 王大鹏 深圳开鸿数字产业发展有限公司 一.简介 OpenAtom OpenHarmony(以下简称"Open ...