界面已本地化;技能介绍与说明文档按所选语言由 AI 自动翻译,代码、命令、路径和专业术语保留原文,以原作者文档为准。
探索技能
文档与办公 · SKILL.md

pptx-generator

pptx-generator

【文档与办公】生成、编辑、读取 PowerPoint 演示文稿。支持用 PptxGenJS 从零创建(封面、目录、内容页、章节分隔页、总结页),通过 XML 工作流编辑已有 PPTX,或使用 markitdown 提取文本。触发器:PPT, PPTX, PowerPoint, 演示文稿, 幻灯片, 幻灯片组。

独立 GitHub 快照 · 自动分类 · 以原作者文档为准

技能说明

GitHub

name: pptx-generator description: "生成、编辑、读取 PowerPoint 演示文稿。支持用 PptxGenJS 从零创建(封面、目录、内容页、章节分隔页、总结页),通过 XML 工作流编辑已有 PPTX,或使用 markitdown 提取文本。触发器:PPT, PPTX, PowerPoint, 演示文稿, 幻灯片, 幻灯片组。" license: MIT agent_created: true metadata: version: "1.2" category: productivity source: "MiniMax-AI/skills 仓库(经授权安装),实战反馈修正 v1.2" sources: - https://gitbrent.github.io/PptxGenJS/ - https://github.com/microsoft/markitdown

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.md5 种幻灯片页面类型(封面、目录、章节分隔、内容、总结)+ 附加布局模式
design-system.md调色板、字体参考、风格配方(Sharp/Soft/Rounded/Pill)、排版与间距
editing.md基于模板的编辑工作流、XML 操作、格式化规则、常见陷阱
pitfalls.mdQA 流程、常见错误、关键 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:

  1. 文件命名:slides/slide-01.js, slides/slide-02.js 等
  2. 图片存放:slides/imgs/
  3. 最终 PPTX 存放:slides/output/
  4. 尺寸:10" x 5.625" (LAYOUT_16x9)
  5. 字体:全部统一使用 微软雅黑(包括英文、数字、中文混排场景)
  6. 颜色:6 位十六进制,不带 #(例如 "FF0000")
  7. 必须使用 theme 对象契约(见 Theme 对象契约)
  8. 必须遵循 PptxGenJS API 参考
  9. 中文文本字符串使用单引号包裹,避免双引号嵌套问题
  10. 严格遵循布局间距规则(见下方 布局防重叠规则),每个 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 ≥ 0x 为负则内容被裁剪
右边界任何元素的 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"9pt7字符标签,窄框易折行
"STEP 1" 类0.55"10pt6字符以内
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: 卡片头部边界检测 + 行内文字重叠

问题:

  1. 引用文本/副标题与大标题位于同一行(同一 y 坐标),视觉上相互重叠
  2. 卡片头部标题文字(中文 + 英文混排)溢出卡片头部的彩色背景区域

标准解法:

// ❌ 错误:引用文本与大标题同一行
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 项12pt1.61.33"≥ 1.45"
5 项11pt1.51.15"≥ 1.30"
4 项12pt1.61.07"≥ 1.20"
3 项12pt1.60.80"≥ 0.95"
3 项11pt1.50.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 — 图标(可选)
我的收藏