使用原生 `python-pptx` 图表和形状对象,将图表较多的源图片重建为可编辑的 PowerPoint 文件,并通过 Microsoft PowerPoint 回渲染、自检数字/图例/标注、定点修复错位区域,持续迭代直到结果稳定匹配源图。适用于柱状图、折线图、饼图、组合图、信息图风格的图表面板,以及其他需要在 PPT 中保持尽量可编辑的幻灯片图形。
当用户希望把现有图表图片重建为可编辑的 .pptx,并且要求图表数据仍能在 PowerPoint/Excel 中编辑时,请使用这个技能。最终预览 PNG 必须来自 PowerPoint 自己的渲染流程,而不是其他绘图库。
核心原则有三条:
python-pptx 图表、文本框、线条和形状对象。当请求包含以下任一需求时,应触发这个技能:
.jpg、.png 或截图转换为可编辑的 PowerPoint 内容.pptx 和一个与 PPT 布局一致的 PNG 预览图以下情况不要使用这个技能:
对于名为 <stem>.<ext> 的源文件,除非用户另有要求,否则使用以下目录约定:
<source_dir>,例如 /Users/chenql/Desktop/workspace/plot/越南报告/原图<source_dir> 的同级 pptx 目录记为 <pptx_dir>,例如 /Users/chenql/Desktop/workspace/plot/越南报告/pptx<pptx_dir> 不存在,必须先创建,再写入最终 .pptx输出文件默认放置如下:
<source_dir>/<stem>_plot.py:可复现的脚本,用于生成 PPTX 和预览 PNG<pptx_dir>/<stem>_recreated_editable.pptx:可编辑的 PowerPoint 成果文件<source_dir>/<stem>_recreated.png:由 PowerPoint 自身渲染出的预览图如果输入是目录,则目录内每张源图都应按上述规则各自产出一组同名输出文件。除非用户明确要求,否则不要把多张图合并到同一个 .pptx。
只有在排查不匹配问题时才保留额外的调试裁图或辅助图片。除非用户明确要求保留,否则在完成前应删除这些临时文件。
保持 SKILL.md 简洁,细则分流到附带资源:
当任务需要脚本化时,按以下顺序组织实现:
series.data_labels 和 point.data_label 配置图表原生数值标签PowerPoint -> PDF -> PNGpython-pptx 对象来重建图表。CHART 对象,这样用户仍然可以在 PowerPoint 内通过 Excel 编辑数据。python-pptx 的数据标签 API:优先配置 series.data_labels,再用 point.data_label 做单点位置微调;不要手工再叠一层重复数值文本框。bbox、style、confidence 和 parent;没有归属关系的标签不得直接进入最终版面。9M2024/2024H1 这类半结构化标签必须二次校对。如果用户给出的是原图目录,而不是单张图片路径:
.png、.jpg、.jpeg*_recreated.png、调试裁图、隐藏文件以及其他明显不是原始输入图的文件当且仅当用户明确要求使用子 agent、委派或并行处理时:
.pptx 的完整转换<source_dir> 保存 *_plot.py 和 *_recreated.png,同级 <pptx_dir> 保存 *_recreated_editable.pptx如果用户给的是目录,但没有明确要求子 agent、委派或并行处理,则主 agent 应按同样的单图标准逐张处理,只是不启动子 agent。
在写代码之前:
<source_dir>,并推导同级的 <pptx_dir><pptx_dir>;如果没有,则创建该目录不要一边读图一边直接摆文本框。先把页面拆成结构化对象。每个对象至少包含:
{
"id": "label_ups_us_2021",
"type": "data_label",
"text": "10.7%",
"bbox": [120, 84, 176, 108],
"style": {
"font_size": 24,
"font_weight": "bold",
"color": "#333333"
},
"confidence": 0.93,
"parent": "series_ups_us_2021",
"group_id": "labels_ups_us"
}
这里的关键不是 OCR 出字符串,而是保留几何和归属关系:
bboxparentgroup_id建议优先通过 extract_layout.py 固定 JSON 契约,再进入排版阶段。
选择能够还原源图、同时保持可编辑性的最小 PowerPoint 结构:
BAR_CLUSTERED 或 COLUMN_CLUSTEREDPIE在这一步要保留关系约束,而不是只填绝对坐标:
对图表本体上的数值标签,默认按下面这条路径实现,不要直接手工摆文本框:
series.data_labels.show_value = Trueseries.data_labels.number_format、series.data_labels.position 和字体point.data_label.position 做单点 override只有非图表本体的数据说明,例如脚注、区间说明、独立 callout,才优先使用普通文本框。不要为了图表值再额外复制一层重复数值文本框。
建议用 build_ppt.py 先校验 layout 契约,再决定哪些对象用原生图表、哪些对象用文本框或形状实现。
最终 PNG 的一致性应来自 Microsoft PowerPoint,而不是 matplotlib 或 Quick Look。
这一阶段必须统一走 render_ppt.py,不要让 agent 自己额外拼装 osascript、AppleScript 或 sips 命令。唯一允许的导出方式是调用该脚本的 --execute 路径。
强制使用的命令模式如下:
python3 /Users/chenql/Desktop/workspace/plot/skill/imgtopptx/scripts/render_ppt.py \
--pptx /abs/path/to/input_recreated_editable.pptx \
--pdf /abs/path/to/output.pdf \
--png /abs/path/to/output.png \
--execute
例如:
python3 /Users/chenql/Desktop/workspace/plot/skill/imgtopptx/scripts/render_ppt.py --pptx /Users/chenql/Desktop/workspace/plot/a0_recreated_editable.pptx --pdf /tmp/a0_render_test.pdf --png /tmp/a0_render_test.png --execute
脚本内部负责执行以下渲染流程,agent 不应绕开它:
.pptxrender_ppt.py 使用 PowerPoint 自动化导出 PDFrender_ppt.py 再将 PDF 转为 PNG如果需要查看将要执行的路径、AppleScript 或输出位置,可以先不带 --execute 调用 render_ppt.py 查看 dry-run contract,但最终导出 PNG 时仍必须回到 --execute 命令。
如果无法使用 PowerPoint 自动化,要明确说明无法保证与 PowerPoint 完全一致,并把任何 matplotlib 生成的 PNG 仅视为备用预览图。
回渲染 PNG 之后,必须与原图做显式校验。不要只看整体像不像,要检查具体对象是否还贴在正确位置。
至少覆盖以下五类检查:
统一使用 validation-rules.md 中的评分与阈值,并优先通过 validate_layout.py 产出如下结构:
{
"page": 1,
"score": 86,
"checks": {
"numeric_text_match": 0.98,
"legend_alignment": 0.62,
"parent_attachment": 0.74,
"overlap_safety": 0.91,
"visual_similarity": 0.88
},
"issues": [],
"repair_hints": []
}
当总分 < 90 或任一 critical mismatch 失败时,必须进入修复流程。
修复时不要整页重生成。顺序固定如下:
series.data_labels.position 或 point.data_label.position默认最多修 2 轮。只有满足 fallback-policy.md 中的条件时,才允许把失败区域作为局部图片贴回 PPT:
局部贴图时要遵守三条底线:
修复计划建议通过 repair_layout.py 生成,再回到渲染和校验阶段复检。
以下情况一律视为 critical mismatch,必须修复:
< 90series.data_labels.position 或 point.data_label.position,不要先退回手工文本框。marker + spacing + label,不要拆开修。只有当以下条件全部满足时,任务才算完成:
.pptx 能在 PowerPoint 中打开