pptx 单页封面标题改写
适用场景
用户给一份 pptx(本地路径 或 资料库 space 链接),要求按后文内容调整某一页的主标题/子标题,并强调「其他页面保持不变」。
典型信号:把【第N页】的【主标题】和【子标题】根据【第X页到第Y页】的内容进行调整。
核心原则
- 只动一页 XML:zip 级替换
ppt/slides/slideN.xml,其余 entry 用原字节写回(保留ZipInfo顺序/属性),保证「其他页面 100% 不动」可验证。 - 不要用 python-pptx 整体重存:会重排 entry、丢视频引用、体积变化不可控。
- 先量宽度再定文案:标题框是
wrap="none"(不换行),超宽会直接顶到/越过幻灯片右边缘被裁掉。
字宽预算(微软雅黑,实测值)
封面模板固定参数(WorkBuddy 培训课件系列):
| 元素 | 字号 | 框 off x / cx (EMU) | 每字宽 | 安全上限 |
|---|---|---|---|---|
| 主标题 | 45pt 加粗 | 666750 / 10858500 | CJK 60px,拉丁 ≈0.55 字 | ≈1121px ≈19 字 |
| 子标题 | 16.5pt 常规 | 1314450 / 4333875 | CJK 22px | ≈1142px(到边缘) |
| 元信息行 | 12.75pt | 666750 / 10858500 | — | — |
- 文本框宽 1139.9px,幻灯片右边缘可用 1210px(= 1280 − 左边距 70)。
- 1121px 是经实渲验证的安全线(19 个汉字 + 全角标点)。1240px 会越出幻灯片,必须砍字。
- 预量脚本:
from PIL import ImageFont
def px(t, pt, fp):
return ImageFont.truetype(fp, int(round(pt*96/72))).getlength(t)
px('资料库、知识库和企微机器人:让 AI 干活', 45, r'C:/Windows/Fonts/msyhbd.ttc') # -> 1121
px('资料库是什么 · 知识库怎么打通 · 企微机器人怎么建', 16.5, r'C:/Windows/Fonts/msyh.ttc')
文案写法约定(本课件系列已确立)
- 主标题 =
话题A、话题B和话题C:一句价值主张,总宽 ≤1121px。价值主张只有 ~2 个汉字+「让 AI 」的余量,别写长句。 - 已上线例:
助理、项目和自动化:让 AI 离开聊天窗口、技能、看板与应用:把 AI 变成顺手的工具、资料库、知识库和企微机器人:让 AI 干活 - 子标题 = 与主标题话题一一对应的要点,用
·分隔(3 个话题就 3 条)。子标题框宽cx同步改到5300000EMU 保持留白一致。 - 反面教材:只列第一块内容的旧子标题(如「资料库是什么 · 内容怎么进资料库 · 协作与发布」而没有知识库/机器人)。
- 主标题要跟原文用词对齐:后文叫「企微机器人」,标题就别写「客服机器人」。
操作步骤
- 读结构:
zipfile列出 slides 数与各页<a:t>文本;散文式扫一遍,确认目标页是篇章封面、后文范围对应哪些页。 - 确认范围歧义:用户给的范围若小于该章实际范围(例如章封面管 64—82 页,用户只说 64—68),先问一句再动手。
- 量宽度(上面脚本),选不超 1121px 的文案。
- 改 XML:只做
<a:t>旧</a:t>→<a:t>新</a:t>的精确替换(每个目标串在 slide XML 里必须唯一,count != 1就报错退出);子标题的 3 条要点由 5 个 run 组成(要点 /·/ 要点 /·/ 要点),只替换 3 个要点 run,保留分隔 run。 - 重打包:逐一
infolist()复制,命中目标页才换数据,其余原样;ZipInfo的date_time/compress_type/external_attr/create_system一并复制。 - 写回:先备份原文件(
*.原版备份.pptx放工作目录),再覆盖原路径。 - 验收(缺一不可):
- 逐 entry md5 比对:差异清单必须只有ppt/slides/slideN.xml;
- 逐页<a:t>文本比对:其他页必须完全一致;
-zip.testzip()返回None;
- PowerPoint COM 把目标页导出 PNG 目检(见pptx-windows-render技能),确认文案没顶到右边缘。
已知坑
- 写回原文件报
Device or resource busy:文件正被 PowerPoint / WorkBuddy 预览器打开(同目录会有~$xxx.pptx锁文件)。别反复重试(实测 3 次都失败),改成把成品输出到同目录副本xxx.已改.pptx,并把情况告诉用户;用户关掉 PowerPoint 后再覆盖原文件。 - 用户会把「同一份母版的另一章抽取成另一个
新建 PPTX 演示文稿.pptx」再让你改——先读第 1 页确认是哪一章(页数、章节号、后文内容都比对一遍),不要沿用上一份的判断。 wrap="none"不会自动换行,也不会自动缩字号;超宽就是被裁。- 别改
rPr(sz/lang/字体),只改文本,否则排版会跳。 - 改完如果还要同步到资料库网盘,走
library-drive-replace技能(100 MiB 上限的绕行方案)。 - 封面页的「建议用时 10—15 分钟 · 第 61—64 页」等元信息不属于主/子标题,用户没点名就别动,但要在回复里提示它是否已过期。