dsh-pptx-anim
给 .pptx 批量注入真正的 PowerPoint 进入动画与幻灯片切换 —— 补上 python-pptx 没有动画 API 的缺口。
python-pptx不实现<p:timing>,所以市面上绝大多数"用代码生成 PPT"的方案都只能产出静态页。 本插件直接写 OOXML 的时间轴树,动画是文件里的数据:目标机器不需要装 PowerPoint / WPS。
提供的工具
| 工具 | 作用 |
|---|---|
pptx_animate |
给 pptx 注入进入动画 + 页面切换(不修改源文件) |
pptx_anim_validate |
结构校验:元素顺序、空条件列表、动画目标是否指向真实形状 |
pptx_anim_env |
探测哪个 Python 能 import pptx |
依赖
- Node.js ≥ 20(DSH 本身自带)
- Python 3 且能
import pptx(即python-pptx)——工具会在python/python3/py里自动探测; 找不到就显式传python参数,或设置环境变量DSH_PPTX_ANIM_PYTHON。
没有 Python 也能用 DSH,只是这个插件会返回"找不到解释器"的明确提示,不会静默失败。
用法
pptx_animate({ input: "C:/x/deck.pptx" })
→ 生成 C:/x/deck_anim.pptx,返回每页动画节点数
pptx_anim_validate({ input: "C:/x/deck_anim.pptx" })
→ 结构校验通过 / 列出问题
指定预设:
pptx_animate({ input: "...", preset: "cards", transition: "fade" })
预设
| preset | 适用 | 交错 | 时长 | 图片 | 文字 |
|---|---|---|---|---|---|
auto(默认) |
按每页构成自动判定 | — | — | — | — |
title |
封面 | 180ms | 450ms | 淡出 | 淡出 |
proposition |
命题大字页 | 150ms | 420ms | 淡出 | 淡出 |
image |
图文页 | 200ms | 500ms | 淡出 | 擦除(上) |
cards |
三/四栏卡片页 | 110ms | 320ms | 擦除 | 擦除 |
data |
数据密集页 | 90ms | 320ms | 淡出 | 淡出 |
none |
只加切换、不加动画 | — | — | — | — |
只使用 animEffect 型效果(淡出 / 擦除 / 盒状 / 圆形 / 菱形 / 十字)——它们是最稳的单节点编码。
形状命名(精准控制播放顺序)
生成 deck 时给形状命名 s01、s02……(按阅读顺序):
shape = slide.shapes.add_textbox(...)
shape.name = 's01'
有名字按序号播;没名字按 z-order 播(自动生成的 deck 通常一致,手改过会错位)。
已验证 / 未验证
已验证(2026-10-29,Windows 11 + DSH 0.2.1):
- 15 页一次性注入 193 个
animEffect节点 + 全页切换 - 修掉两个会让 PowerPoint 提示"需要修复"的坑:
transition必须排在timing之前(CT_Slide 子元素顺序)、stCondLst不能为空 - 注入后的文件能被 LibreOffice 正常打开(15 页、无缺字体)
validate.py对故意打乱顺序的文件能报错
未验证:
- PowerPoint / WPS 的实机播放效果(开发机只装了 ONLYOFFICE,无 PowerPoint COM)
- 单页 25+ 动画节点的极端情况
⇒ 交付时请同时保留「无动画版」,并提示首次放映前用 F5 预览一次。
禁区
- 不做 Morph 变形、运动路径(
animMotion)、触发器交互链、按段落逐条动画 —— 这些要么需要 PowerPoint 专有数据,要么手写风险远高于收益 - 一页动画 > 25 个节点会让放映发卡,应拆页
- 不要把
p:timing追加在p:transition之前
工作原理
lib/index.js Host 半:注册 3 个工具,探测 Python,spawn 助手脚本
scripts/pptx_anim.py 读 pptx → 按预设生成 <p:timing> 树 → 写回新文件
scripts/validate.py 直接解 zip 检查 slide XML 的结构合法性
动画树的形状(简化):
p:timing → p:tnLst → p:par(tmRoot) → p:seq(mainSeq)
→ p:par(点击组) → p:par(延迟0) → p:par(delay=交错) × N
└ presetClass="entr" + p:set + p:animEffect
安装
前置
- Node.js ≥ 20(DSH 自带)
- Python 3 且能
import pptx(pip install python-pptx)- 工具会自动在
python/python3/py里找;都不行时用工具参数python指定绝对路径, 或设环境变量DSH_PPTX_ANIM_PYTHON - 找不到时工具会明确报错并列出尝试过的解释器,不会静默失败
- 工具会自动在
方式 A:本地挂载(自用 / 开发,已在 DSH 0.2.1 桌面版验证)
克隆或复制本仓库到 DSH profile 的
plugins/下:~/.dsh/profiles/<profile>/plugins/dsh-pptx-anim/在该 profile 的
cordis.patch.yml末尾追加:- insert: - id: pptx-anim name: ./plugins/dsh-pptx-anim/lib/index.js重启 DSH(Host 半改动必须重启),确认工具已加载(让 agent 调用
pptx_anim_env, 或看工具列表里有没有pptx_animate)。
方式 B:作为 bundle 安装
本仓库自带 cordis.patch.yml(声明了 dsh.bundle.patch),包被装进 profile 后会自动挂 row:
dsh plugin --profile <profile> add dsh-pptx-anim # 从 npm
dsh plugin --profile <profile> add file:<本地目录或 tgz> # 从本地
以本地目录方式安装时,包目录是符号链接。本插件只有 Host 半(无客户端模块), 符号链接不影响加载;含客户端 UI 的插件不要用这种方式。
安装后自检
pptx_anim_env({}) → 应返回一个可用的 Python
pptx_animate({ input: "<任一 .pptx 的绝对路径>" }) → 生成 <原名>_anim.pptx
pptx_anim_validate({ input: "<原名>_anim.pptx" }) → 应显示「结构校验通过」
License
MIT
No comments yet. Be the first to write one.