关于 pptx
用于创建、编辑和检查 PowerPoint 演示文稿的技能,涵盖脚本生成、基于 XML 的模板修改,以及校验和视觉检查工具。
主要功能
- 01使用 pptxgenjs 创建演示文稿
- 02通过 XML 编辑幻灯片和模板
- 03使用 markitdown 提取幻灯片文本
- 04生成带标签的幻灯片缩略图
- 05校验文稿结构和图表
适用场景
- 01生成新的 PowerPoint 演示文稿
- 02改编现有文稿或模板
- 03检查幻灯片内容和版式
- 04查找文稿结构错误
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ fcakyon/ claude-codex-settings --skill pptx安装后在 Claude Code 中输入/pptx确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSE.txtscripts/__init__.pyadd_slide.pyclean.pyscripts/office/helpers/__init__.pypptx_chart.pypptx_slide.pypptx_theme.pyscripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsdopc-coreProperties.xsdopc-digSig.xsdopc-relationships.xsdscripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsddml-chartDrawing.xsddml-diagram.xsddml-lockedCanvas.xsddml-main.xsddml-picture.xsddml-spreadsheetDrawing.xsddml-wordprocessingDrawing.xsdpml.xsdshared-additionalCharacteristics.xsdshared-bibliography.xsdshared-commonSimpleTypes.xsdshared-customXmlDataProperties.xsdshared-customXmlSchemaProperties.xsdshared-documentPropertiesCustom.xsdshared-documentPropertiesExtended.xsdshared-documentPropertiesVariantTypes.xsdshared-math.xsd详细介绍
PPTX 创建、编辑与分析
.pptx 是由 XML 文件组成的 ZIP 压缩包。请根据任务选择方法:
| 任务 | 方法 |
|---|---|
| 创建新演示文稿 | 编写 pptxgenjs 脚本,参见下方注意事项 |
| 编辑现有演示文稿,或基于模板构建 | 解压 → 编辑 ppt/slides/slideN.xml → 重新压缩 |
| 读取内容 | markitdown deck.pptx(每张幻灯片一个块,位于 `` 标记下);可视化网格:python scripts/thumbnail.py deck.pptx |
脚本
路径均相对于本技能目录。其余部分为普通 Python、node 或 Shell。
| 脚本 | 功能 |
|---|---|
scripts/thumbnail.py deck.pptx [prefix] | 生成每张幻灯片的带标签网格,用于挑选模板版式。仅支持 .pptx。请传入 prefix:默认值为 thumbnails,会覆盖同一目录中其他演示文稿生成的网格 |
scripts/add_slide.py unpacked/ slide2.xml [--after slideN.xml] | 复制一张幻灯片(或 slideLayoutN.xml),并同步处理所有包内关联信息。也可直接传入 .pptx 文件,配合 -o out.pptx 使用 |
scripts/clean.py unpacked/ | 删除不再被引用的幻灯片、媒体文件和关系文件。请在 <p:sldIdLst> 确定后再运行 |
scripts/office/validate.py deck.pptx [--original src.pptx] | 进行架构、关系、内容类型、图表和幻灯片检查;每个失败项都会注明修复方法。对于任何基于模板生成的演示文稿,请传入 --original:它会以模板为基线进行架构检查,这样模板自身的 XSD 错误不会被误报为你的问题 |
scripts/office/soffice.py --headless --convert-to pdf deck.pptx | LibreOffice 封装脚本。在此沙箱中直接运行 soffice 会挂起 |
使用 pptxgenjs 创建:常见陷阱
pptxgenjs 已预装,无需先运行 npm install,直接编写脚本并 require('pptxgenjs') 即可。仅当该 require 失败时,才执行 npm install pptxgenjs。模型已熟悉该 API,以下是需要留意的陷阱:
- 在添加幻灯片之前设置
pres.layout。 默认画布为LAYOUT_16x9,即 10" × 5.625",而非 13.3" 宽。超出边缘的坐标会被照常写入,不会被裁剪,形状只是不在幻灯片上。(LAYOUT_WIDE为 13.3" × 7.5"。) - 十六进制颜色:绝不使用
#,也绝不使用 8 位数字。 应写作color: "FF0000"。"#FF0000"以及将透明度写入十六进制(如"00000020")都会损坏文件。若需半透明,请在填充和图片上使用transparency: 0-100,在阴影上使用opacity: 0.0-1.0。两者在对方上都会被静默忽略。 - pptxgenjs 会就地修改选项对象(首次使用时将数值转换为 EMU)。切勿在两次
add*调用之间共用同一个shadow或选项对象,每次都应新建对象。 - 阴影的
offset必须 ≥ 0,负值会损坏文件。若要使阴影向上投射,请使用angle: 270并配合正的 offset。 letterSpacing会被静默忽略,正确的选项是charSpacing。- 列表: 每个条目都设置
bullet: true,切勿使用字面的•(会渲染出双重项目符号)。数组中除最后一项外,每个条目都设置breakLine: true。为带项目符号的段落留间距时,使用paraSpaceAfter而非lineSpacing(否则间距会非常大)。 - 每个输出文件只使用一个
new pptxgen(),切勿复用实例。 rectRadius仅对ROUNDED_RECTANGLE生效,对RECTANGLE无效。- 不支持渐变填充,请改用渐变图片作为背景。
- 文本框内置内边距。 当文本需要与形状、线条或图标在同一 x 坐标上对齐时,请设置
margin: 0。 - 演讲者备注应写入
slide.addNotes("...")(纯文本,每张幻灯片一次),切勿放在幻灯片上的文本框中。 - 保持图表为原生图表。 凡是 PowerPoint 可以绘制的图表,都使用
addChart()(组合图请传入{type, data, options}数组)。对于该库未暴露的 PowerPoint 原生功能(如趋势线、误差线),请自行计算额外的数据系列,或对生成的 OOXML 进行后处理,不要退而使用渲染图片。只有 PowerPoint 没有原生形式的图表类型(桑基图、网络图、弦图)才以图片形式插入。 - 默认图表渲染时较为简陋,没有标题和数据标签,配色也较过时。请设置
showTitle+title;设置showValue: true+dataLabelPosition;使用你的配色方案设置chartColors: [...];并简化图表边框,即设置catAxisLabelColor/valAxisLabelColor、valGridLine: { color, size }、catGridLine: { style: "none" },单一数据系列时设置showLegend: false。 - 在堆叠条形图或柱形图中,
dataLabelPosition必须为ctr、inEnd或inBase。 使用outEnd会损坏文件。 - 使用
secondaryValAxis/secondaryCatAxis的组合图系列,需要在图表选项中同时提供valAxes和catAxes,且各含两项。 否则 pptxgenjs 会写入其从未声明的坐标轴 id,PowerPoint 会丢弃该图表并报告文件已损坏。仅提供valAxes是不够的。 writeFile()之后,运行python scripts/office/validate.py deck.pptx。 它会报告上述两类图表问题,以及 PowerPoint 会拒绝的幻灯片 XML 缺陷,并为每一项给出修复方法。请在生成代码中修复,不要手动编辑打包后的 XML。- 切勿调整
<p:presentation>的子元素顺序。 pptxgenjs 会将<p:notesMasterIdLst>写在<p:sldIdLst>之后,并让两个母版指向同一个主题部件。PowerPoint 能正常读取这一结构,但一旦移动该元素,同一份演示文稿就会无法打开。 - 图标: 使用
ReactDOMServer.renderToStaticMarkup将react-icons渲染为 SVG,用sharp栅格化为至少 256px 的图像,然后通过addImage({ data: "image/png;base64," + buf.toString("base64") })插入。image/png;base64,前缀是必需的。react-icons、react、react-dom和sharp已预装,仅当 require 失败时,才执行npm install react-icons react react-dom sharp。
编辑现有演示文稿和模板
先选择版式:运行 python scripts/thumbnail.py template.pptx template-thumbs,它会生成一个带标签的网格图,包含每张幻灯片,并输出所创建的文件,即 template-thumbs.jpg;超过 12 张幻灯片时会拆分为 template-thumbs-N.jpg。务必将第二个参数设为以演示文稿命名。 该参数默认为 thumbnails,因此若在同一目录中为两个演示文稿生成缩略图,它们会悄无声息地互相覆盖,第一个演示文稿的网格图就会丢失。(此方法仅用于模板分析;视觉质检需要使用 转换为图片 中的全分辨率渲染图。该脚本只接受 .pptx,因此需先将 .potx 复制为 .pptx 文件名。)配合 markitdown 使用,将每个内容章节映射到模板幻灯片上,并变换版式,不要让所有章节都使用同一种标题加要点的幻灯片。
python3 -c "import sys,zipfile; zipfile.ZipFile(sys.argv[1]).extractall('unpacked')" deck.pptx
python scripts/add_slide.py unpacked/ slide2.xml --after slide2.xml # duplicate a slide (or slideLayoutN.xml); prints the new slide's path
# reorder / delete slides = edit <p:sldIdLst> in ppt/presentation.xml
python scripts/clean.py unpacked/ # after deletions: removes orphaned slides, media, rels
# edit slide content in ppt/slides/slideN.xml
(cd unpacked && rm -f ../out.pptx && zip -Xr ../out.pptx .) # zip from INSIDE the dir; rm first or deleted parts survive
python scripts/office/validate.py out.pptx --original deck.pptx
- 先完成所有结构性工作,即添加、删除和重新排序,然后再编辑任何幻灯片的内容。
add_slide.py会原样复制幻灯片文件,因此如果先编辑再复制,复制出的内容也会包含编辑后的内容;而clean.py会删除<p:sldIdLst>中缺失的任何幻灯片,包括你刚写入的幻灯片。 - 切勿手动复制幻灯片文件。
add_slide.py会完成新幻灯片所需的全部注册工作,并报告其创建结果(例如Created ppt/slides/slide17.xml from slide2.xml)。它也可以直接处理文件:add_slide.py deck.pptx slide2.xml -o out.pptx。务必传入-o,否则会直接覆盖原始输入演示文稿。 复制出的幻灯片仍然引用源幻灯片的图表、SmartArt 和嵌入对象部件,而不是复制这些部件,因此编辑一张幻灯片的图表会同时改变另一张的图表。 - 如果使用
python-pptx,有三件事它不会处理:复制幻灯片(其唯一入口是add_slide(layout));通过text_frame.text = "..."保留格式(这会把段落合并为一个无样式的文本run,应改为赋值run.text);读取大多数模板图形所用的 SVG/EMF(add_picture会抛出UnidentifiedImageError)。 - 旧版
.ppt必须先转换:python scripts/office/soffice.py --headless --convert-to pptx file.ppt。.potx模板的解包与打包方式相同,输出时请保留.potx扩展名。 - 若要复用模板中的图标或图片,请复制已包含该图标或图片的幻灯片或版式。
填充模板时:
- 如果你用脚本修改 XML,请使用
defusedxml.minidom解析。通过xml.etree.ElementTree对 OOXML 进行往返处理会重写命名空间前缀,从而损坏演示文稿。 - 模板占位与源内容条目不一致时的处理。 如果模板显示 4 位团队成员,而你只有 3 位,请删除第 4 位成员的整个组(图片加文本框),而不只是删除其文本,然后在质检中检查是否留有孤立的视觉元素。
- 每个列表项使用一个
<a:p>,切勿把多个条目合并到同一段落中。复制相邻的<a:pPr>以保持间距,并在标题、章节标题和行内标签(如Status:、Owner:)的<a:rPr>上设置b="1"。 - 项目符号应继承版式设置。仅在需要覆盖时才添加
<a:buChar>、<a:buAutoNum>(编号列表)或<a:buNone>,切勿在文本中直接写入字面的•。 - 文本首尾带空格时,需在其
<a:t>上设置xml:space="preserve"。
设计思路
不要做乏味的幻灯片。 白底上的普通要点不会给任何人留下深刻印象。请为每张幻灯片考虑此列表中的设计思路。
开始之前
- 选择大胆且贴合内容的配色方案:配色应当为本主题量身定制。如果把这些颜色换到一个完全不同的演示文稿中仍然“说得通”,说明你的选择还不够具体。
- 主次分明,而非平均分配:一种颜色应占据主导地位(视觉权重约 60-70%),搭配 1-2 种辅助色调和一种醒目的强调色。切勿让所有颜色权重相同。
- 深浅对比:标题页和结论页使用深色背景,内容页使用浅色背景,形成“三明治”结构。也可以全程采用深色背景,营造高级质感。
- 确定一个视觉母题:选定一个独特元素并在各页重复使用,例如圆角图片框或彩色圆形中的图标。贯穿每一张幻灯片。不要把色条或强调色条纹作为母题(参见 Avoid 列表)。
配色方案
选择与主题相匹配的颜色,不要默认使用通用蓝色。以下配色方案可供参考:
| 主题 | 主色 | 辅助色 | 强调色 |
|---|---|---|---|
| 午夜行政风 | 1E2761(海军蓝) | CADCFC(冰蓝) | FFFFFF(白色) |
| 森林与苔藓 | 2C5F2D(森林绿) | 97BC62(苔藓绿) | F5F5F5(奶油白) |
| 珊瑚活力 | F96167(珊瑚色) | F9E795(金色) | 2F3C7E(海军蓝) |
| 温暖赤陶 | B85042(赤陶色) | E7E8D1(沙色) | A7BEAE(鼠尾草绿) |
| 海洋渐变 | 065A82(深蓝) | 1C7293(青色) | 21295C(午夜蓝) |
| 炭灰极简 | 36454F(炭灰) | F2F2F2(米白) | 212121(黑色) |
| 青色信赖 | 028090(青色) | 00A896(海沫绿) | 02C39A(薄荷绿) |
| 莓果与奶油 | 6D2E46(莓红) | A26769(灰玫瑰) | ECE2D0(奶油白) |
| 鼠尾草宁静 | 84B59F(鼠尾草绿) | 69A297(桉树绿) | 50808E(石板灰) |
| 樱桃醒目 | 990011(樱桃红) | FCF6F5(米白) | 2F3C7E(海军蓝) |
每页幻灯片
每张幻灯片都需要视觉元素,例如图片、图表、图标或形状。纯文字的幻灯片容易被遗忘。
版式选项:
- 双栏(左侧文字,右侧插图)
- 图标加文字的行式布局(彩色圆形中的图标,粗体标题,下方为描述)
- 2x2 或 2x3 网格(一侧为图片,另一侧为内容块网格)
- 半幅出血图片(左侧或右侧整幅图片),上方叠加内容
数据展示:
- 大号数据强调(60-72pt 的大数字,下方配小标签)
- 对比栏(前后对比、优缺点、并列选项)
- 时间线或流程图(编号步骤,配箭头)
视觉细节:
- 在小节标题旁放置彩色圆形图标
- 关键数据或标语使用斜体强调文字
排版
你写入 .pptx 的字体名称由用户的 PowerPoint 渲染,而不是由本环境渲染。 视觉 QA 通过 LibreOffice 渲染,它会替换本地没有的字体。对于某些字体,替换字体的宽度不同,因此 QA 预览中的文字溢出(或恰好容纳)情况可能与真实演示文稿不一致。为保证 QA 结果可信:
- 安全字体(在 QA 中宽度还原准确,且随 Office 一同提供):Arial、Calibri、Cambria、Times New Roman、Courier New、Bookman Old Style、Century Schoolbook。正文及所有对容纳效果有要求的内容都使用这些字体。
- 零 QA 风险的个性化标题:将安全列表中的衬线标题字体(Cambria、Bookman Old Style、Century Schoolbook)与安全列表中的无衬线正文字体(Calibri 或 Arial)搭配。这样既能获得视觉对比,又不影响可靠的溢出检查。
- 如果用户要求安全列表之外的字体(例如 Georgia 或 Trebuchet MS):在用户指定的位置使用该字体,但为这些容器预留更多余量(约 10%),且不要信任这些元素的 QA 文本适配结果,因为该字体的预览只是近似效果。如果用户未指定,正文优先使用安全列表中的字体。
- QA 不可靠的字体(替换字体宽度不同,溢出检查可能有误):Georgia、Trebuchet MS、Impact、Arial Black、Garamond、Consolas、Palatino Linotype。Calibri Light 的替换结果因环境而异,同样视为 QA 不可靠。可用于留有余量的标题或点缀文字,但不要信任这些元素的 QA 文本适配结果。
- 切勿默认使用 Aptos:它是 Office 2023 年后的默认字体,在此环境中没有度量兼容的替换字体,且旧版 Office 中也没有,因此在两端都不可靠。
| 元素 | 字号 |
|---|---|
| 幻灯片标题 | 36-44pt 加粗 |
| 章节标题 | 20-24pt 加粗 |
| 正文 | 14-16pt |
| 图注 | 10-12pt,弱化颜色 |
间距
- 最小页边距 0.5"
- 内容块之间留出 0.3-0.5"
- 留出呼吸空间,不要填满每一英寸
避免(常见错误)
- 不要重复相同的版式:在幻灯片之间变换分栏、卡片和强调框
- 不要居中正文:段落和列表左对齐,仅标题居中
- 不要吝惜字号对比:标题需要 36pt 以上,才能从 14-16pt 的正文中凸显出来
- 不要默认使用蓝色:选择能反映具体主题的颜色
- 不要随意混用间距:选择 0.3" 或 0.5" 的间距并始终保持一致
- 不要只装饰一张幻灯片而其余保持朴素:要么全面投入设计,要么全程保持简洁
- 不要制作纯文字幻灯片:添加图片、图标、图表或其他视觉元素;避免仅有标题加项目符号的版式
- 不要忘记文本框内边距:在将线条或形状与文字边缘对齐时,将文本框设置为
margin: 0,或偏移形状以抵消内边距 - 不要使用低对比度元素:图标和文字都需要与背景形成强对比;避免浅色文字置于浅色背景上,或深色文字置于深色背景上
- 绝对不要在标题下方添加装饰线:这是 AI 生成幻灯片的典型特征;请改用留白或背景色
- 绝对不要添加装饰性色条或强调条:包括贯穿幻灯片宽度的页眉或页脚色条、沿幻灯片一侧的竖向侧边条、卡片或内容块一侧的细强调条,以及矩形上的“单侧边框”。这些会被视为 AI 生成的冗余填充。若要突出卡片,请使用淡背景色、投影或图标,而不是边缘条纹
- 不要默认使用米色或象牙色背景:未指定背景时,使用白色(
FFFFFF)或用户的品牌配色;避免使用F5F5DC、FAF0E6、FAEBD7、FFF8E1等偏暖的中性色默认值 - 不要交付超出形状边界的文字:如果文字放不下,请缩小字号、拆分到多张幻灯片,或放大容器;切勿让内容被截断或溢出边界
质检(必需)
首次渲染通常会存在一些实际问题,例如重叠、溢出和错位。请找出并修复这些问题,仅重新渲染你修改过的幻灯片,然后停止。
内容质检
markitdown output.pptx
检查是否有内容缺失、拼写错误或顺序错误。
使用模板时,检查是否残留占位文本:
markitdown output.pptx | grep -iE "\bx{3,}\b|lorem|ipsum|\bTODO|\[insert|this.*(page|slide).*layout"
如果 grep 返回结果,请先修复后再宣布成功。
文件质检(必需)
python scripts/office/validate.py output.pptx # built from scratch
python scripts/office/validate.py output.pptx --original src.pptx # built from a template
如果演示文稿源自模板,务必传入 --original。 模板本身可能包含 XSD 会拒绝的部分,因此直接运行可能会报告你并未造成的失败,同时真正的回归问题可能被淹没其中。--original 会以模板为基线进行 schema 和幻灯片检查,抑制模板原本已有的错误。关系、内容类型、图表等结构检查会忽略 --original,无论如何都会报告模板遗留的问题,因此请单独依据其本身判断这些结果。
pptxgenjs 生成的图表 XML 可能导致 PowerPoint 无法打开,而其他所有工具都能接受:python-pptx 可以打开这些演示文稿,LibreOffice 可以渲染,XSD 检查也能通过。每个失败都会说明修复方法。请在生成代码中修复后重新构建。
视觉质检
将幻灯片转换为图片(参见转换为图片)并逐一检查。在反复阅读生成代码后,你往往会看到预期中的效果,而不是实际渲染的结果,因此请以全新视角查看图片(如果可用,使用子 Agent 效果很好)。需要留意的用户可见缺陷:
- 文本溢出,或文本在文本框或幻灯片边界处被截断。请优先检查此项。 这是最常见的缺陷,且始终对用户可见。(对于预览器渲染不可靠的字体(见排版部分),预览仅为近似:应信任你预留的约 10% 余量,而不是预览中看起来的适配情况。)
- 元素重叠(文字穿过形状、线条穿过文字、元素堆叠)
- 来源引用或页脚与上方内容相撞
- 元素间距过近(< 0.3")或卡片/区块几乎相接
- 间距不均(某处大片空白,另一处过于拥挤)
- 与幻灯片边缘的边距不足(< 0.5")
- 分栏或类似元素对齐不一致
- 低对比度文字(例如米色背景上的浅灰色文字)
- 模板装饰元素在文本替换后位置错误,例如标题下划线按单行标题定位,而替换后的标题换行成了两行
- 低对比度图标(例如深色背景上没有对比色圆形底的深色图标)
- 文本框过窄导致换行过多
- 残留占位内容
转换为图片
将演示文稿转换为单独的幻灯片图片以便视觉检查:
python scripts/office/soffice.py --headless --convert-to pdf output.pptx
rm -f slide-*.jpg
pdftoppm -jpeg -r 150 output.pdf slide
ls -1 "$PWD"/slide-*.jpg
将上面打印的绝对路径直接传给查看工具。 rm 会清除之前运行留下的过期图片。pdftoppm 会根据页数补零:少于 10 页的演示文稿为 slide-1.jpg,10 至 99 页为 slide-01.jpg,100 页及以上为 slide-001.jpg。
修复后,请重新运行上面的全部四条命令。 必须先从修改后的 .pptx 重新生成 PDF,pdftoppm 才能反映你的修改。
依赖
pptxgenjs(npm,已预装,仅当 require('pptxgenjs') 失败时才需安装)· markitdown[pptx]、Pillow、defusedxml、lxml(pip,用于文本导出、缩略图、清理和校验)· LibreOffice(soffice,通过 scripts/office/soffice.py 在沙箱环境中自动配置)· pdftoppm(Poppler)