Pptx generator
A curated collection of WorkBuddy agent skills — academic pipeline, frontend slides, PPTX generator, tool-call repair, and more.
npx -y skills add yinqd3/workbuddy-skills --skill pptx-generatorAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
生成、编辑、读取 PowerPoint 演示文稿。支持用 PptxGenJS 从零创建(封面、目录、内容页、章节分隔页、总结页),通过 XML 工作流编辑已有 PPTX,或使用 markitdown 提取文本。触发器:PPT, PPTX, PowerPoint, 演示文稿, 幻灯片, 幻灯片组。
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
20.8 KB, as published. Nobody here has run it
PPTX Generator & Editor
Overview
本 Skill 处理所有 PowerPoint 任务:读取/分析已有演示文稿、通过 XML 操作编辑基于模板的演示文稿,以及使用 PptxGenJS 从零创建演示文稿。内置完整的设计系统(调色板、字体、风格配方)和每种幻灯片类型的详细指南。
Quick Reference
| 任务 | 方式 |
|---|---|
| 读取/分析内容 | python -m markitdown presentation.pptx |
| 编辑或基于模板创建 | 见 Editing Presentations |
| 从零创建 | 见下方 从零创建工作流 |
| 项目 | 值 |
|---|---|
| 画布尺寸 | 10" x 5.625" (LAYOUT_16x9) |
| 颜色格式 | 6 位十六进制,不带 #(例如 "FF0000") |
| 英文字体 | 微软雅黑(中文PPT建议全篇统一) |
| 中文字体 | 微软雅黑 |
| 页码徽章位置 | x: 9.3", y: 5.1" |
| 基础主题键 | primary, secondary, accent, light, bg |
| 可选扩展键 | gold, coral, violet(根据需要添加) |
| 形状 | RECTANGLE, OVAL, LINE, ROUNDED_RECTANGLE |
| 图表 | BAR, LINE, PIE, DOUGHNUT, SCATTER, BUBBLE, RADAR |
参考文件
| 文件 | 内容 |
|---|---|
| slide-types.md | 5 种幻灯片页面类型(封面、目录、章节分隔、内容、总结)+ 附加布局模式 |
| design-system.md | 调色板、字体参考、风格配方(Sharp/Soft/Rounded/Pill)、排版与间距 |
| editing.md | 基于模板的编辑工作流、XML 操作、格式化规则、常见陷阱 |
| pitfalls.md | QA 流程、常见错误、关键 PptxGenJS 陷阱 |
| pptxgenjs.md | 完整的 PptxGenJS API 参考 |
读取内容
# 文本提取
python -m markitdown presentation.pptx
从零创建 — 工作流
当没有模板或参考演示文稿时使用。
第 1 步:调研需求
搜索以理解用户需求 — 主题、受众、目的、语气、内容深度。
第 2 步:选择调色板与字体
使用 调色板参考 选择与主题和受众匹配的调色板。使用 字体参考 选择字体配对。
第 3 步:选择设计风格
使用 风格配方 选择与演示文稿基调相匹配的视觉风格(Sharp, Soft, Rounded 或 Pill)。
第 4 步:规划幻灯片大纲
将每一张幻灯片精确分类为 5 种页面类型 之一。规划每张幻灯片的内容和布局。确保视觉多样性 — 不要在不同幻灯片上重复相同布局。
第 5 步:生成幻灯片 JS 文件
在 slides/ 目录下为每张幻灯片创建一个 JS 文件。每个文件必须导出一个同步的 createSlide(pres, theme) 函数。遵循 幻灯片输出格式 和 slide-types.md 中的类型特定指南。如果有 subagent,最多同时生成 5 张幻灯片。
告诉每个 subagent:
- 文件命名:
slides/slide-01.js,slides/slide-02.js等 - 图片存放:
slides/imgs/ - 最终 PPTX 存放:
slides/output/ - 尺寸:10" x 5.625" (LAYOUT_16x9)
- 字体:全部统一使用 微软雅黑(包括英文、数字、中文混排场景)
- 颜色:6 位十六进制,不带 #(例如
"FF0000") - 必须使用 theme 对象契约(见 Theme 对象契约)
- 必须遵循 PptxGenJS API 参考
- 中文文本字符串使用单引号包裹,避免双引号嵌套问题
- 严格遵循布局间距规则(见下方 布局防重叠规则),每个 slide 生成后必须做 Y 轴重叠检查
大规模 PPTX(30+ 张幻灯片)并行生成策略:
- 启动 8-9 个 subagent 并行生成,每个负责 ~5 张幻灯片
- 均分场景覆盖:封面/分隔页分配给专门的 agent,内容页按顺序均分
- 每个 subagent 必须遵循相同的 theme 契约和 slide 模板
- 最后 compile.js 合并所有 slide 模块
布局防重叠规则(强制)
内容页垂直布局每层元素的底部必须严格小于下一层元素的顶部。 常见重叠场景和标准解法如下:
顶部区域(y: 0 ~ 1.8)三层结构
┌─ 行 1: 章节标签 ─┬── y_min=0.30, h_max=0.25, 底部≤0.55
├─ 行 2: 页面标题 ─┬── y_min=0.75, h_max=0.50, fontSize_max=26
├─ 行 3: 副标题 ───┬── y_min=1.40, h_max=0.30, fontSize_max=14
└─── 之后的内容 ───┬── y≥1.85
| 元素 | 最小 y | 最大 h | 最大字号 | 说明 |
|---|---|---|---|---|
| 章节标签 | 0.30" | 0.25" | 13pt | 紧凑显示 |
| 页面标题 | 0.75" | 0.50" | 26pt | 长标题会换行,用小字号保证一行显示 |
| 副标题 | 1.40" | 0.30" | 14pt | 灰色/辅助色 |
相邻元素垂直间距规则
| 场景 | 最小间距 | 说明 |
|---|---|---|
| 标题底部 → 副标题顶部 | ≥ 0.15" | 防止文字串行重叠 |
| 副标题底部 → 卡片/形状顶部 | ≥ 0.15" | 副标题与内容块之间 |
| 卡片底部 → 反馈循环文本 | ≥ 0.15" | 流程图中箭头文本 |
| 内容底部 → 总结面板顶部 | ≥ 0.10" | 底部总结框 |
| 总结面板底部 → 页码徽章 | ≥ 0.05" | 最后一行的间距 |
容器内元素不越界规则
卡片/组内的子元素必须完全在容器边界内。 这是编写自定义函数时最容易出错的地方。
例如: 靶心图(2×2网格)
┌─────────────────────┐
│ 卡片框 (cx±1.05, cy±0.8) │
│ ├── 靶心环 (cx±0.32) │ ← ✅ 在卡片内
│ └── 弹孔 (cx+dx, cy+dy) │ ← ⚠️ dx,dy 必须在 ±0.77 内
│ 标注 (cy+0.4~0.8) │ ← ✅ 在卡片内
└─────────────────────┘
容器内元素边界检查清单:
- 所有子元素的 x ≥ 容器.x 且 x+w ≤ 容器.x+容器.w
- 所有子元素的 y ≥ 容器.y 且 y+h ≤ 容器.y+容器.h
- 相对坐标(如 cx+dx, cy+dy)的偏移量不超出容器的半宽/半高
- 卡片内的标注/描述文本完整可见,不被卡片边界裁剪
水平边界规则
幻灯片画布为 10" × 5.625",所有元素必须在画布范围内:
| 规则 | 条件 | 后果 |
|---|---|---|
| 左边界 | 任何元素的 x ≥ 0 | x 为负则内容被裁剪 |
| 右边界 | 任何元素的 x + w ≤ 10 | 超右则内容被裁剪 |
| 上边界 | y ≥ 0 | 同上 |
| 下边界 | y + h ≤ 5.625 | 超下则内容被裁剪 |
| 安全边距 | 建议 x ≥ 0.4, x + w ≤ 9.6 | 打印/投影仪可能裁边 |
常见越界场景:
- 时间线/卡片布局:最后一个节点的卡片右边缘超过 10"
// ❌ 越界:cx + cardW/2 > 10" // ✅ 修正:缩减 totalW 或增大 startX const totalW = 7.5; // 不够宽?用 7.5 const startX = 1.0; // 不靠左?用 1.0 // 验证:startX + totalW + cardW/2 ≤ 10 - 文本框内容太长:建议使用
fit: "shrink"自动缩小文本slide.addText("长标题文字", { x: 0.5, y: 2, w: 9, h: 0.6, fontSize: 24, fit: "shrink" });
重叠快速自查清单
生成每张 slide 后,逐项检查:
- 章节标签底部(y+h) < 标题顶部(y) ?(至少 0.10" 间隙)
- 标题底部(y+h) < 副标题顶部(y) ?(至少 0.15" 间隙)
- 副标题底部(y+h) < 卡片/形状的 yStart ?
- 所有 "STEP" 标签的底部低于上一层元素的底部?
- 页码徽章不在任何内容框的范围内?
- 标题文本的 fontSize ≤ 26pt(内容页)?
- 所有元素的 x ≥ 0 且 x+w ≤ 10?
- 对称布局(如多卡片时间线)的最左和最右卡片不超出边界?
- 底部面板的底部(y+h) ≤ 5.3,给页码徽章留空间?
- 自定义函数中的子元素(弹孔/图标)不超出父容器边界?
关于 fontSize 的硬性上限
| 元素 | 上限 | 原因 |
|---|---|---|
| 内容页标题 | 26pt | 长中文标题(15-20字)在 9" 宽空间内一行显示 |
| 章节分隔页标题 | 32pt | 标题较短,可以稍大 |
| 封面主标题 | 48-54pt | 封面空间大 |
| 副标题/描述 | 14pt | 辅助文本,不需要大字号 |
| 卡片内标题 | 16-18pt | 卡片空间有限 |
| 卡片内正文 | 10-12pt | 紧凑信息展示 |
| 表格/代码内容 | 9-11pt | 密集数据场景 |
上下文感知布局规则(v1.2 新增)
以下规则无法通过纯坐标检查发现,需要结合文本内容和容器边界做语义判断:
Rule A: 标签行文换行检测 + 页码基线对齐
问题: 标签文本(如 PART 01、STEP N 等)因容器宽度不足导致自动折行,或页码徽章与相邻底部面板的文字基线不齐。
标准解法:
❌ 错误:w=0.55 的标签框放 "PART 01"(7字符 @ 10pt)→ 可能折行为 "PAR" / "T 01"
✅ 正确:w≥0.65 或 fontSize≤9pt,确保标签文字单行完整显示
| 场景 | 最小宽度 | 最大字号 | 说明 |
|---|---|---|---|
| "PART 01" 类 | 0.65" | 9pt | 7字符标签,窄框易折行 |
| "STEP 1" 类 | 0.55" | 10pt | 6字符以内 |
| 3字符标签 | 0.40" | 11pt | 如 "01"、"A" 等 |
页码徽章基线对齐检查:
- 页码徽章的垂直中心线应与相邻底部面板的文字基线对齐
- 底部面板
y + h/2≈ 页码徽章y + h/2(差值 ≤ 0.05") - 徽章不应与面板重叠:面板右边缘 x+w ≤ 徽章 x(或徽章 x 在面板右侧)
Rule B: 时间线上方元素重叠检测
问题: 时间线布局中,年份/标签文字(位于时间线上方)与标题区或副标题区域重叠。
标准解法:
时间线 Y 轴布局模板:
┌─ 标题 ─────────────┬── y=0.60~0.70, 底部≤1.05
├─ 副标题 ───────────┬── y=1.00~1.10, 底部≤1.30
├─ 年份标签 ─────────┬── y≥1.20 (副标题底部), h=0.30
├─ 时间线 ───────────┬── y≥1.65, 圆圈中心在时间线上
├─ 卡片/节点 ────────┬── y=时间线底部+0.3~0.4
└─ 底部面板 ─────────┬── y≥4.0
检查清单:
- 年份标签顶部 y ≥ 副标题底部 y(至少 0.05" 间隙)
- 时间线节点卡片的内容(描述文字)不超出卡片边界
- 最下方节点/卡片的底部 ≤ 底部面板的顶部 - 0.15"
Rule C: 卡片头部边界检测 + 行内文字重叠
问题:
- 引用文本/副标题与大标题位于同一行(同一 y 坐标),视觉上相互重叠
- 卡片头部标题文字(中文 + 英文混排)溢出卡片头部的彩色背景区域
标准解法:
// ❌ 错误:引用文本与大标题同一行
slide.addText("大标题", { x: 0.65, y: 0.52, w: 6, h: 0.35, fontSize: 22 });
slide.addText("· 引用文本", { x: 3.4, y: 0.52, w: 5, h: 0.35, fontSize: 14 }); // ← 重叠!
// ✅ 正确:引用文本放在单独一行
slide.addText("大标题", { x: 0.65, y: 0.52, w: 6, h: 0.35, fontSize: 22 });
slide.addText("· 引用文本", { x: 0.65, y: 0.95, w: 6, h: 0.3, fontSize: 14 }); // ← 新行
卡片头部溢出检测:
- 卡片头部标题文本框的右边缘(x + w)不得超出卡片头部的彩色背景区域
- 中文 + 英文混排时,英文部分会使文本总宽度超出预期 → 使用
fit: "shrink"或减小字号 - 头部文本字号建议:中英文混排 ≤ 11pt,纯中文 ≤ 12pt
Rule D: 底部边缘碰撞检测 + 垂直间距均匀分布
问题: 容器(卡片、面板)内的最后一行文字几乎接触到容器底部边界;中间区域的元素间距过于拥挤。
标准解法:
容器内文字垂直分布:
┌─────────────────────┐
│ 标题 (y+0.08~0.15) │ ← 顶部留空
│ 主文字 (y+0.35~0.45) │ ← 间距 0.20~0.30"
│ 描述 (y+0.70~0.80) │ ← 间距 0.25~0.35"
│ ░░░ 底部安全边距 ░░░ │ ← 至少 0.10" 留白
└─────────────────────┘
卡片内垂直间距规则:
| 区域 | 距卡片顶部 | 间距 | 说明 |
|---|---|---|---|
| 头部标签 | 0.08~0.15" | — | 卡片内部标题 |
| 主文字 | 0.35~0.45" | 0.20~0.30" | 大号强调文字 |
| 描述文字 | 0.70~0.80" | 0.25~0.35" | 更靠近底部 |
| 底部安全边距 | — | ≥ 0.10" | 文字底部到卡片底部 |
中间区域拥挤检测:
- 当一页有多个并行元素(如 3 张卡片)时,确保元素间的垂直间距 ≥ 0.15"
- 元素内部文字不超出底部边界(最后一行文字底部 ≤ 元素底部 - 0.10")
- 卡片内最后一行文字的 fontSize 适配:长文本使用 11pt,确保在有限宽度内不换行
Rule E: 列表/概念图方框文字适配
问题: 列表项(bullet items)或概念图方框内的多行文字总高度超出文本框高度,导致文字被裁剪。
标准解法:
// 计算所需高度
const lineCount = items.length;
const lineHeight = fontSize * lineSpacingMultiple / 72; // pt → inches
const requiredH = lineCount * lineHeight + 0.10; // + 底部边距
// 检查:textBox.h ≥ requiredH
if (textBox.h < requiredH) {
// 修复选项:
// 1. 增加卡片高度
// 2. 减小 fontSize
// 3. 减小 lineSpacingMultiple
}
列表项高度速查表:
| 条目数 | 字号 | 行间距倍率 | 所需高度 | 建议框高 |
|---|---|---|---|---|
| 5 项 | 12pt | 1.6 | 1.33" | ≥ 1.45" |
| 5 项 | 11pt | 1.5 | 1.15" | ≥ 1.30" |
| 4 项 | 12pt | 1.6 | 1.07" | ≥ 1.20" |
| 3 项 | 12pt | 1.6 | 0.80" | ≥ 0.95" |
| 3 项 | 11pt | 1.5 | 0.69" | ≥ 0.85" |
验证方法:
- 使用 PptxGenJS 的
fit: "shrink"作为保险(但不要依赖它作为唯一手段) - 生成后通过 python-pptx 解析每张 slide 的文本框高度和内容行数做验证
- 如果页面布局复杂(顶部卡片 + 中部概念图 + 底部面板),确保所有元素之间有合理的垂直间隙
第 6 步:编译为最终 PPTX
创建 slides/compile.js 来合并所有幻灯片模块:
// slides/compile.js
const pptxgen = require('pptxgenjs');
const pres = new pptxgen();
pres.layout = 'LAYOUT_16x9';
const theme = {
primary: "003D24", // 最深色,用于深色背景/标题
secondary: "6B4FCF", // 次要强调色(紫色)
accent: "006A3F", // 主强调色(墨绿)
light: "A8D5BA", // 浅色强调
bg: "FFFFFF", // 背景色(学术PPT建议白色)
// 可选扩展键(根据需要添加):
gold: "C49A2A", // 金色 - 页号角标/特殊强调
coral: "C2411F" // 珊瑚红 - 警告/错误标识
};
for (let i = 1; i <= 43; i++) {
const num = String(i).padStart(2, '0');
const slideModule = require(`./slide-${num}.js`);
slideModule.createSlide(pres, theme);
}
pres.writeFile({ fileName: './output/presentation.pptx' });
运行:cd slides && NODE_OPTIONS= node compile.js
(注意:如果遇到 --use-system-ca is not allowed in NODE_OPTIONS 错误,需要清空该环境变量)
第 7 步:QA(必需)
参见 QA 流程。
输出结构
slides/
├── slide-01.js # 幻灯片模块
├── slide-02.js
├── ...
├── imgs/ # 幻灯片中使用的图片
└── output/ # 最终产物
└── presentation.pptx
幻灯片输出格式
每张幻灯片是一个完整的、可运行的 JS 文件:
// slide-01.js
const pptxgen = require("pptxgenjs");
const slideConfig = {
type: 'cover',
index: 1,
title: '演示文稿标题'
};
// 必须是同步的(不能是 async)
function createSlide(pres, theme) {
const slide = pres.addSlide();
slide.background = { color: theme.bg };
slide.addText(slideConfig.title, {
x: 0.5, y: 2, w: 9, h: 1.2,
fontSize: 48, fontFace: "微软雅黑",
color: theme.primary, bold: true, align: "center"
});
return slide;
}
// 独立预览 — 使用幻灯片特定的文件名
if (require.main === module) {
const pres = new pptxgen();
pres.layout = 'LAYOUT_16x9';
const theme = {
primary: "22223b",
secondary: "4a4e69",
accent: "9a8c98",
light: "c9ada7",
bg: "f2e9e4"
};
createSlide(pres, theme);
pres.writeFile({ fileName: "slide-01-preview.pptx" });
}
module.exports = { createSlide, slideConfig };
Theme 对象契约(强制)
编译脚本传递一个 theme 对象。以下 5 个键是必须的,可以根据需要增加额外的键(如 gold, coral, violet 等):
| 键 | 用途 | 示例 |
|---|---|---|
theme.primary | 最深色,用于深色背景/标题 | "003D24" |
theme.secondary | 次要强调色 | "6B4FCF" |
theme.accent | 主强调色(装饰条/标识/高亮) | "006A3F" |
theme.light | 浅色强调(辅助文字/浅填色) | "A8D5BA" |
theme.bg | 背景色(学术PPT建议白色) | "FFFFFF" |
必须包含以上 5 键,但可以扩展。例如可以添加 gold, coral, violet 等键用于特殊场景。
⚠️ PptxGenJS v3.x 关键陷阱(必读)
以下的踩坑经验来自于实战,严重程度较高,请在生成幻灯片时严格遵守:
1. 使用 pres.shapes.* 而非 pres.ShapeType.*
PptxGenJS v3.x 不支持 pres.ShapeType.RECTANGLE,必须使用 pres.shapes.RECTANGLE:
// 正确
slide.addShape(pres.shapes.RECTANGLE, { ... });
slide.addShape(pres.shapes.OVAL, { ... });
slide.addShape(pres.shapes.ROUNDED_RECTANGLE, { ... });
// 错误(v3.x 中不存在)
slide.addShape(pres.ShapeType.RECTANGLE, { ... });
2. slide.background 使用 { color: ... } 而非 { fill: ... }
// 正确
slide.background = { color: "FFFFFF" };
slide.background = { color: theme.primary };
// 错误(会被静默忽略,幻灯片背景透明)
slide.background = { fill: "FFFFFF" };
slide.background = { fill: { color: "FFFFFF" } };
3. 项目符号用 bullet: true,不要用 bullet: { code: "•" }
// 正确
{ text: "第一项", options: { bullet: true, breakLine: true } }
// 错误(不支持 code 属性)
{ text: "第一项", options: { bullet: { code: "•" } } }
4. 中文文本使用单引号包裹
如果中文文本中包含双引号(如"关键"、"注意"等),用双引号包裹会产生 SyntaxError:
// 正确
slide.addText('模型判断"我对哪些样本最不确定"', { ... });
// 错误(字符串内的双引号未转义)
slide.addText("模型判断"我对哪些样本最不确定"", { ... });
5. 运行 node compile.js 时清空 NODE_OPTIONS
cd slides && NODE_OPTIONS= node compile.js
页码徽章(必需)
除封面页外的所有幻灯片必须在右下角包含页码徽章。
- 位置:x: 9.3", y: 5.1"
- 只显示当前页码(如
3或03),不要显示 "3/12" - 使用调色板颜色,保持微妙
圆形徽章(默认)
slide.addShape(pres.shapes.OVAL, {
x: 9.3, y: 5.1, w: 0.4, h: 0.4,
fill: { color: theme.accent }
});
slide.addText("3", {
x: 9.3, y: 5.1, w: 0.4, h: 0.4,
fontSize: 12, fontFace: "微软雅黑",
color: "FFFFFF", bold: true,
align: "center", valign: "middle"
});
胶囊形徽章
slide.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 9.1, y: 5.15, w: 0.6, h: 0.35,
fill: { color: theme.accent },
rectRadius: 0.15
});
slide.addText("03", {
x: 9.1, y: 5.15, w: 0.6, h: 0.35,
fontSize: 11, fontFace: "微软雅黑",
color: "FFFFFF", bold: true,
align: "center", valign: "middle"
});
依赖项
pip install "markitdown[pptx]"— 文本提取npm install -g pptxgenjs— 从零创建npm install -g react-icons react react-dom sharp— 图标(可选)