ZKT PPT美化-标准模版

SKILL效率
效率 未标注权限 许可证不明确
安装这个技能

基于直客通品牌PPT模版样式对PPT进行美化,包含直客通LOGO、品牌色调、品牌文化等品牌特征元素

一句话选型结论

按资料字段整理

ZKT PPT美化-标准模版是效率类的 Agent Skill,安装方式未标注,权限级别未标注,许可证不明确,有可直接复制的安装命令。技能本质是给模型读的说明书,效果取决于模型与客户端;装完先用一个小任务验证,再放进正式流程。

分类效率 安装方式未标注 权限级别未标注权限 许可证许可证不明确
累计安装 未标注 本周 未标注
GitHub 星标 未标注 仓库 未标注
下载量 未标注 技能市场下载数
权限级别 未标注权限 安装前请确认风险范围
许可证 许可证不明确 未说明

安装

未标注
在支持 Skills 的客户端里执行,装完问一句「你有哪些技能」验证
skillhub install user_87f9fd3d/zhiketong
  1. 1
    确认客户端支持

    确认你的客户端支持 Skills(Claude、Codex、Cursor 等),并升级到较新的版本。

  2. 2
    拿到技能文件

    执行上面的命令安装;也可以把仓库里的 SKILL.md 手动放进客户端的 skills 目录。

  3. 3
    刷新技能列表

    重新打开客户端,或刷新技能列表,让新放进来的技能被加载。

  4. 4
    验证是否生效

    问一句「你有哪些技能」,确认列表里出现它,再拿一个小任务试跑。

技能档案

效率
字段来自技能仓库与公开索引,中文说明由本站标注
作者 / 维护方user_87f9fd3d仓库 未标注 · 版本 未标注
宿主客户端未标注技能可被这些客户端加载
安装方式未标注安装包 community
权限级别未标注权限安装前请确认风险范围
许可证未说明许可证不明确,商用前请自行确认条款
仓库可用性available技能仓库当前是否可访问
最近核验未标注上游最后核验时间 · 数据更新 1791734508
正文体量63.8 KBSKILL.md 原文大小,越大说明说明书写得越细

典型使用场景

3 类
按分类整理的常见用法,具体以 SKILL.md 为准
整理待办与日程

把零散任务收进清单,排出优先级。

批量处理重复任务

把固定动作做成模板,重复执行。

把流程写成清单

把口头流程整理成可复用的步骤。

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 有可直接复制的安装命令,不用自己翻文档找入口。

先想清楚的地方

  • 没有标注权限级别,实际能做什么要装好后确认。
  • 许可证不明确,商用或二次分发前先到仓库确认条款。
  • 没有做站内核验,内容以作者仓库为准。
  • 技能只是说明书,实际效果取决于模型与客户端,装完先用小任务试一遍。

更适合

  • 需要在效率场景里给模型补一套做法的人。
  • 愿意先读一遍 SKILL.md、确认它会让模型做什么的人。

不太适合

  • 对许可证要求很严、必须明确可商用的人。
  • 只想装完就自动变强、不打算看说明书的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
技能权限级别安装方式累计安装宿主客户端安装命令
ZKT PPT美化-标准模版当前 未标注权限 未标注 未标注 未标注 有
Nano PDF 文档 联网访问 ClawHub 市场 424.9 万 OpenClaw 有
自动更新程序 浏览器控制 ClawHub 市场 296.4 万 OpenClaw 有
Gemini 助手 联网访问 ClawHub 市场 254.7 万 OpenClaw 有
word DOCX 文档 联网访问 ClawHub 市场 239.6 万 OpenClaw 有
Excel XLSX 前端 联网访问 ClawHub 市场 227.0 万 OpenClaw 有

SKILL.md 全文

63.8 KB
模型实际读到的说明书原文,来自技能仓库

Data Report PPT Generator

Overview

Generate a complete, editable .pptx data report by combining source PPT data
with a template's visual style. The output PPT contains native editable charts
(bar, line, doughnut), styled data tables, KPI highlight cards, timeline
visuals, and preserved source images — all following strict color, font, and
layout specifications.

When to Use

  • User provides a source data PPTX and a template PPT/Python script
  • User asks to "generate a data report PPT", "create a styled presentation
    from data", or "convert data to slides"
  • User wants native editable charts in the output PPT (not images)
  • User wants strict style consistency with a template (colors, fonts, layout)
  • User wants content generated from scratch first (Mode 0): "帮我从0到1做一份…PPT"、"帮我写一份营销活动方案PPT"、无源文件的类型+主题请求 → 先创作内容,落素版草稿,再自动美化

Pre-Workflow: Employee Identity Check & Report Consent (MANDATORY)

> ⚠️ This check MUST be performed BEFORE starting any workflow step. It determines whether Step 6 (auxiliary report) will be executed, AND obtains the user's consent for anonymous reporting in a single question — Step 6 will NOT ask again.

Before starting the PPT generation workflow, you MUST ask the user whether they are a 直客通 (ZKT) employee using AskUserQuestion. The question must clearly state that if they answer "Yes", an anonymous usage report will be automatically sent after the PPT is generated:

  • If the user answers "是直客通员工" (Yes): Proceed with the full workflow (Steps 1–6). The user's "Yes" answer serves as both identity confirmation and consent for the anonymous report. Step 6 will execute the auxiliary report script directly without asking again. Remember the user's choice for Step 6.
  • If the user answers "非直客通员工" (No): Proceed with the PPT generation workflow (Steps 1–5), but SKIP Step 6 entirely. Do not run the report script, do not ask about it again.

The question presented to the user MUST include the following information:
1. This is a one-time check — they will NOT be asked again about the report
2. If they confirm they are a ZKT employee, an anonymous usage report will be automatically sent after PPT generation
3. The report contains only: skill name, an anonymous random ID (ZKT + 6 digits, auto-generated), execution status, and timestamp
4. The report does NOT contain any real user identity (name, email, employee ID, OS username) or any PPT content
5. The report is sent to https://pro-ai.zhiketong.net

This check only determines whether an anonymous usage report will be sent. It does NOT collect or store any real user identity information.

Pre-Workflow: Source Content Beautification Mode (MANDATORY)

> ⚠️ This question MUST be asked AFTER the employee identity check, BEFORE starting any workflow step. It determines whether to beautify based on the user's source file content, or use the skill's default generation logic.

After the employee identity check, you MUST ask the user whether to beautify based on their uploaded source content using AskUserQuestion:

  • If the user answers "是,根据源文件美化" (Yes): Content MUST be 100% from the source file — do NOT add, remove, or modify any text content, tables, or data. However, the following template elements MUST still follow the skill's template specifications:
  • Cover style and background image (use template cover_bg.jpg/cover_logo.png)
  • Inner page header style (CN title + EN subtitle + inner logo position)
  • Inner page logo position (exact template coordinates)
  • Color palette / element tone specifications (brand red, dark, light pink, gray)
  • Original images from the source PPT MUST be preserved — extract and embed them without compression or distortion. Use proportional scaling, NOT stretching/squashing.
  • If the user answers "否,按默认逻辑生成" (No): Proceed with the skill's default generation logic (Steps 1-6 as defined below), including company intro pages, TOC, section dividers, data charts, etc.
  • Auto-route to Mode 0: If the user request is itself "从 0 到 1 生成新内容"(无源文件、只给了 PPT 类型与主题),DO NOT ask this binary question — enter the Mode 0 (Content Creation) section directly and follow its flow. The identity check from the previous step still applies.

The question presented to the user MUST include the following information:
1. If "Yes": Content will be 100% from the source file, but cover style, inner page header, logo position, and color tones will follow the template specification
2. If "Yes": Original images in the source PPT will be preserved — no compression or distortion
3. If "No": The skill's default generation logic will be used (including company intro, TOC, section dividers, charts, and data cards)

<!-- ===================== MODE 0 ADDED (2026-09-03) START ===================== -->

Mode 0: Content Creation Mode(从 0 到 1 · 先创作内容再自动美化)

> 本模式是本 skill 的内容"供给侧"入口:当用户手上还没有任何源文件、想直接要一份"某类型"的酒店业务 PPT 时,先帮他把整份内容(结构/文案/数据位)从 0 写出来,落成一份"素版内容草稿 PPTX",再自动交给下方 Workflow 的「根据源文件美化」路径套标准模板,一次对话闭环。

Trigger(命中即自动路由,不再问"是否美化源文件")

  • 用户请求"从 0 到 1 / 帮我写 / 帮我做一份…PPT",且给的是类型与主题而非上传文件,例如:
  • "帮我做一份酒店国庆营销活动方案 PPT"
  • "生成一份给总经理看的 Q3 经营数据总结 PPT(数字我后面自己填)"
  • "做一份会员储值促销培训 PPT"
  • 用户明说"先帮我写内容 / 先出大纲 / 内容你来起草,我先定稿"。
  • 不适用:已有源文件要美化(走 Source Beautification);已有数据表要出报告(走 Default Generation)。

前置(MANDATORY)

  1. 员工身份确认(复用主流程 Pre-Workflow 提问)→ 决定是否执行 Step 6 上报。
  2. 命中本模式后,跳过"根据源文件美化 / 按默认逻辑生成"二选一提问(草稿必然走源文件美化路径)。

Step C1 类型与信息采集(AskUserQuestion,只问缺的信息)

> 用户一句话里已给的信息不要重复问;缺的关键信息必须问。每次先确认"PPT 类型"(用户明确要求:通过询问确定类型,勿默认只有三类)。
- Q1 类型(必问,除非已明说):营销活动方案 → references/frameworks/marketing_activity.md;经营数据总结(总经理/管理班子)→ gm_data_report.md;促销/产品培训 → promo_training.md;其他(用户自行描述,AI 现场拟结构,不套固定蓝图)
- Q2 主题与周期:活动名/节日/统计周期(如"国庆黄金周""Q3 总结")
- Q3 受众与场合:总经理汇报 / 运营团队 / 一线销售 / 全员培训
- Q4 酒店与品牌:店名/品牌(用于封面副题与用语语境)
- Q5 素材:可提供的真实数据、海报/照片(可"暂无,后补")
- Q6 数据模式(必选其一;本次已答过则沿用):
- 占位符模式:数字一律写作〔待填:指标·口径·周期〕,如〔待填:9月入住率〕;绝不臆造数字。
- 假设值模式:按行业常识填假设值,数值文本用品牌红 #a8282f 并加"(假设)"后缀,醒目提醒替换。
- Q7 篇幅与详略:如"12–15 页""高层只看结论""要可落地执行细节"
- Q8 是否先出大纲确认:默认先生成大纲→用户确认→再展开全文;可改"直接出完整草稿"。

Step C2 定结构(按框架或现场拟大纲)

  • 命中 references/frameworks/ 蓝图 → 读取对应文件按其"逐页蓝图"规划(可增删页)。
  • 自定义类型 → 用"结论先行 + 金字塔"现场拟大纲(封面 → 摘要/总述 → 分章[章节页+内容页] → 收尾页),先让用户确认目录再展开。
  • 每页明确给出:CN 标题、EN 副题、版式标签、内容要点、数据占位或假设值、可视化建议。
  • 大纲必须同时规划"章节分组"(成片含目录页与章节页,见下方《Mode 0 固定版式规则》):把内容页划分为 3–5 个章节,每章给出编号(01/02/…)、CN 章节名(≤6 字)、PART 名(PART ONE/TWO/…)与所含内容页序号。

Mode 0 固定版式规则(2026-09-03 修订 · 不可违反)

> 由用户实测反馈固化,适用 beautify_content_json.py 生成的所有 Mode 0 品牌成片。

Rule M1 — 成片固定结构页(非可选):
成片页面顺序固定为:封面 → 公司介绍 / 公司实力 / 技术资质 三页固定内容(Rule 1 样式,由 assets/PPT模版-简版.py 的 create_slide_02/03/04 复刻)→ 目录页(Rule 2 样式:红顶条 + CONTENTS 88pt 白字 + 章节横排,章节数 3–5 均匀分布)→ 每章节[章节页(Rule 3 样式) + 其内容页] → 封底(Rule 4 样式:THANKS 80pt + 居中 Logo)。
- 章节定义来自 content.json 的 structure.chapters(见 C3 契约);缺失时退回"纯内容页模式"并提示补结构。
- 未经用户明确要求,不得省略任何结构页。

Rule M2 — 文案溢出另起一页(禁止超出页面范围):
- 所有版式(two_col/bullets/kpi_cards+bullets 等)渲染前必须逐条目精确估算占高(按字号×行距×栏宽折算行数,保守取值),单页容量不足时自动另起一页生成续页:续页标题加"(续)"、EN 副题加" - Cont.",页眉样式与母页一致。
- 双栏版式左右条目按行配对(第 i 左 ↔ 第 i 右),行高取两侧较高者,避免跨栏错位。
- 生成后强制执行边界自检:任何形状(背景图/装饰线除外)不得超出页面边界;自检不过不得交付。

Rule M3 — content.json 结构契约(V2):

&quot;structure&quot;: {
  &quot;company_intro&quot;: true,
  &quot;back_cover&quot;: true,
  &quot;chapters&quot;: [
    {&quot;num&quot;: &quot;01&quot;, &quot;part&quot;: &quot;PART ONE&quot;, &quot;cn&quot;: &quot;策略与目标&quot;, &quot;pages&quot;: [1, 2, 3]}
  ]
}

pages 为 slides[] 的 1 基序号;未分组的内容页会自动追加在所有章节之后(兜底防遗漏)。

Step C3 逐页创作 → 生成"素版内容草稿 PPTX"

  1. 按 C2 规划逐页写内容(遵循蓝图与 metrics_glossary.md 的口径/占位规范)。
  2. 内容整理成与 scripts/build_content_draft.py 一致的 JSON 契约:
    - 顶层 title/subtitle(封面文案);structure(章节结构,见 Rule M3,必填);slides[] 每页一个对象:
    • type:&quot;content&quot;:title(CN) en(EN副题) summary(结论句,可空) bullets[]、cards[](数据卡 label/value)、table{headers[],rows[][]}、timeline[]{date,title,desc}、image_note(图片占位)、layout(版式标签)
    • type:&quot;section&quot;:章节页 label(PART ONE) cn en(仅素版草稿使用;品牌成片的章节页由 structure.chapters 驱动)
    • 版式标签 layout 与美化能力对应:kpi_cards(≥3 数据卡)、table、timeline(多时间节点→美化自动触发 Rule 12)、two_col(双栏)、bullets、image
  3. 用户给了图片素材 → 存到 assets/images/source_images/,页内用 image_note 写 [图片占位:文件名],美化阶段替换为真实图片。
  4. 运行(若内容极简也可按同一契约手工写,仍建议走脚本保持一致):
    bash /Users/zkt/.workbuddy/binaries/python/envs/default/bin/python3 \ scripts/build_content_draft.py &lt;内容.json&gt; &lt;草稿输出.pptx&gt;
  5. 素版要求:白底、微软雅黑黑字、无阴影/描边/装饰、不放成图图表(美化阶段按数据重建原生图表);页数 = 最终页数(含封面文案页)。

Step C4 用户校对(软性必须,勿跳过)

  • 用 present_files 打开草稿 PPTX,请用户:补真实数字 / 改文案 / 增删页 / 或回复"直接美化"。
  • 用户确认后进 C5;若用户就此打住(只要内容草稿),流程在 C4 结束,草稿即交付物。

Step C5 自动美化(Mode 0 专用渲染器)

  • 把 Mode 0 的 content.json(含 structure)交给 scripts/beautify_content_json.py 直接渲染为品牌成片:
    bash /Users/zkt/.workbuddy/binaries/python/envs/default/bin/python3 \ scripts/beautify_content_json.py &lt;content.json&gt; &lt;output.pptx&gt;
  • 成片结构按 Rule M1 注入固定结构页:公司介绍×3 → 目录 → 章节页+内容页 → 封底;内容页正文不改一字。
  • 溢出按 Rule M2 自动分页:条目精确估高 + 续页机制 + 生成后边界自检,任何形状不得超出页面范围。
  • 封面/封底背景与 Logo、内页页眉 CN+EN、Logo 位置、配色、字体按模板替换;
  • 草稿里的 layout/image_note 只是给美化阶段的提示:数据卡→KPI 高亮卡;表格→居中样式表;多时间节点→时间轴(Rule 12);双栏→左右分区(左右条目按行配对渲染);图片占位→嵌 assets/images/source_images/ 对应原图(按比例不拉伸,Rule 10)。渲染后删除这些提示标注本身。
  • 模板图片(cover_bg/logo、inner_logo、公司页图标 icon_dev/icon_finance/icon_team/logo_bottom/circle_bg/bottom_bar、end_bg/logo)由 generate_ppt.py 的 ensure_images_downloaded() 管理;如 CDN 因 403 需浏览器 UA,可手动用 curl -A 下载到 assets/images/。
  • 脚本输出后执行重叠自检(忽略背景底/卡片容器与其内部文字、公司实力页文字压圆装饰等模板预期层叠)+ 边界自检,全部通过后再交付。
  • Step 6 上报:按 Step C0 身份结果执行(ZKT 员工自动执行,其余跳过)。
  • 交付:品牌化 PPTX;如需 PDF,向用户确认后转换交付(符合用户 PDF 交付偏好)。

内容红线(写内容时严禁)

  • 不编造"看起来像真"的数字:占位符模式必须留〔待填〕;假设值模式必须标红 + (假设)。
  • 金额/客单/价格敏感数字宁可占位也不猜。
  • 结论句尽量"数据依据 + 业务原因 + 建议动作"三段式,便于总经理类受众直接决策。

<!-- ===================== MODE 0 ADDED (2026-09-03) END ===================== -->

Workflow

> ⚠️ The workflow has 6 steps. For ZKT employees, all 6 steps MUST be completed. Step 6 uses an anonymous random ID — no real user identity is collected or transmitted.

Step 1: Analyze Source PPTX

Extract all content from the source PPTX file:

from pptx import Presentation
from pptx.enum.shapes import MSO_SHAPE_TYPE

prs = Presentation(source_pptx_path)
for i, slide in enumerate(prs.slides):
    for shape in slide.shapes:
        # Extract text, tables, images
        if shape.has_text_frame: ...
        if shape.has_table: ...
        if shape.shape_type == MSO_SHAPE_TYPE.PICTURE: ...

Key extraction targets:
- Page titles and body text
- Table data (headers, rows, totals)
- KPI numbers (PV, UV, GMV, sales, members)
- Trend data (time series for charts)
- Images (preserve non-data images; extract data from chart/table screenshots)

Step 2: Ensure Template Images (V2 Auto-Download)

IMPORTANT (V2 Fix): Template images (cover, back cover, logos) must come from
the skill's IMAGE_URLS dictionary (public URL links), NOT from the source PPT.
The source PPT may contain different images (e.g., hotel photos vs. template design
backgrounds), which would produce incorrect cover/back cover visuals.

generate_ppt.py now includes a built-in ensure_images_downloaded() function
that automatically checks assets/images/ and downloads missing images from
IMAGE_URLS URLs. This runs before any PPT generation, so you should NOT
manually extract images from the source PPT to fill assets/images/
.

If you need to add source-specific images (e.g., marketing plan photos), extract
them separately with names that don't collide with template image names:

# Only extract source-specific images (NOT cover_bg, cover_logo, etc.)
def extract_source_images(shapes, output_dir, slide_idx):
    for shape in shapes:
        if shape.shape_type == MSO_SHAPE_TYPE.PICTURE:
            img = shape.image
            # Use source-specific naming to avoid collision with template images
            filename = f&quot;source_{slide_idx}_{shape.name}.{img.ext}&quot;
            with open(f&#x27;{output_dir}/{filename}&#x27;, &#x27;wb&#x27;) as f:
                f.write(img.blob)

Template images (managed by IMAGE_URLS, auto-downloaded):
- cover_bg.png — cover background (red theme design)
- cover_logo.png — cover logo
- back_bg.jpg — back cover background
- back_logo.png — back cover logo
- inner_logo.png — inner page logo (top-right)
- Additional: icon_dev, icon_finance, icon_team, logo_bottom, circle_bg,
bottom_bar, icon_a, icon_b, icon_c

Step 3: Generate Template PPTX

If the template PPTX doesn't exist, generate it from the template Python script:

python3 assets/PPT模版-简版.py

This produces PPT模版-简版.pptx with 25 pre-styled slides including cover,
company intro pages (2-4), table of contents, section dividers, and content
page layouts.

V2 Fix: The template script now uses cross-platform relative paths
(assets/PPT模版-简版.pptx) instead of Windows-only absolute paths, and
downloads images to assets/images/ (same directory as generate_ppt.py)
instead of a temp directory.

Step 4: Run the Generation Script

Execute the bundled generation script with source, template, and output paths:

python3 scripts/generate_ppt.py \
    &lt;source.pptx&gt; \
    &lt;template.pptx&gt; \
    &lt;output.pptx&gt; \
    [--template-py assets/PPT模版-简版.py]

The script:
1. Auto-downloads missing template images from IMAGE_URLS (V2 new —
prevents using source PPT images as substitutes)
2. Loads the template PPTX (25 slides)
3. Modifies cover, TOC, section dividers with source content
4. Rebuilds content slides with styled tables, native charts, data highlights
5. Preserves template images (cover bg, logos, back cover)
6. Adds new slides as needed (e.g., incentive plan)
7. Saves the output PPTX

Step 5: Verify Output (With Overlap Self-Check)

MANDATORY: After generating the PPTX, you MUST perform an overlap self-check
on ALL slides. If any overlap is detected, fix the layout and regenerate.

Check the generated PPTX:

from pptx import Presentation
prs = Presentation(output_path)
for i, slide in enumerate(prs.slides):
    charts = sum(1 for s in slide.shapes if s.has_chart)
    tables = sum(1 for s in slide.shapes if s.has_table)
    pics = sum(1 for s in slide.shapes if s.shape_type == 13)
    print(f&quot;Slide {i+1}: charts={charts} tables={tables} pics={pics}&quot;)

Mandatory Overlap Self-Check (NON-NEGOTIABLE)

Every generated PPT MUST pass a bounding-box overlap check on all slides.
Add the following check_no_overlap() function to your generation script
and call it for every slide after generating:

def check_no_overlap(slide, slide_idx):
    &quot;&quot;&quot;检测幻灯片中所有形状/文本框是否有重叠&quot;&quot;&quot;
    shapes_info = []
    for shape in slide.shapes:
        try:
            l, t, w, h = shape.left, shape.top, shape.width, shape.height
        except Exception:
            continue
        if w &lt;= 0 or h &lt;= 0:
            continue
        shapes_info.append({
            &quot;name&quot;: shape.name,
            &quot;left&quot;: l, &quot;top&quot;: t, &quot;right&quot;: l + w, &quot;bottom&quot;: t + h,
            &quot;shape&quot;: shape
        })

    overlaps = []
    n = len(shapes_info)
    for i in range(n):
        for j in range(i + 1, n):
            a = shapes_info[i]
            b = shapes_info[j]
            a_overlaps_b = (
                a[&quot;left&quot;] &lt; b[&quot;right&quot;] and a[&quot;right&quot;] &gt; b[&quot;left&quot;] and
                a[&quot;top&quot;] &lt; b[&quot;bottom&quot;] and a[&quot;bottom&quot;] &gt; b[&quot;top&quot;]
            )
            if a_overlaps_b:
                overlap_w = min(a[&quot;right&quot;], b[&quot;right&quot;]) - max(a[&quot;left&quot;], b[&quot;left&quot;])
                overlap_h = min(a[&quot;bottom&quot;], b[&quot;bottom&quot;]) - max(a[&quot;top&quot;], b[&quot;top&quot;])
                # Ignore trivial overlaps (&lt; 50000 EMU ≈ 0.05 inch)
                if overlap_w &lt; 50000 or overlap_h &lt; 50000:
                    continue
                has_text_a = a[&quot;shape&quot;].has_text_frame
                has_text_b = b[&quot;shape&quot;].has_text_frame
                if has_text_a and has_text_b:
                    overlaps.append({
                        &quot;slide&quot;: slide_idx + 1,
                        &quot;shape_a&quot;: a[&quot;name&quot;], &quot;shape_b&quot;: b[&quot;name&quot;],
                        &quot;text_a&quot;: a[&quot;shape&quot;].text_frame.text.strip()[:30],
                        &quot;text_b&quot;: b[&quot;shape&quot;].text_frame.text.strip()[:30],
                    })

    if overlaps:
        print(f&quot;  ⚠️  Page {slide_idx + 1}: {len(overlaps)} overlap(s) detected!&quot;)
        for o in overlaps:
            print(f&quot;    - &#x27;{o[&#x27;text_a&#x27;]}&#x27; vs &#x27;{o[&#x27;text_b&#x27;]}&#x27;&quot;)
        return False
    else:
        print(f&quot;  ✅ Page {slide_idx + 1} — no overlaps&quot;)
        return True

def run_overlap_check(prs):
    &quot;&quot;&quot;对所有页面执行重叠自检,返回是否全部通过&quot;&quot;&quot;
    all_clean = True
    for i, slide in enumerate(prs.slides):
        if not check_no_overlap(slide, i):
            all_clean = False
    return all_clean

If overlaps are detected:
1. Identify the two overlapping elements and their y coordinates
2. Adjust vertical spacing by increasing gaps between zones
3. Re-run the generation script
4. Re-run the overlap check
5. Repeat until ALL pages pass — do NOT deliver a PPT with overlaps

Step 6: Run Auxiliary Report Script (Conditional — ZKT Employees Only, Auto-Execute)

> ⚠️ This step is ONLY executed if the user identified as a 直客通 (ZKT) employee in the Pre-Workflow check. The user's "Yes" answer in the Pre-Workflow already serves as consent — DO NOT ask for confirmation again. Execute the script directly.
>
> If the user is NOT a ZKT employee, SKIP this step entirely — do not run the script, do not ask about it.
>
> Privacy guarantee: The auxiliary script generates and uses a random anonymous ID (format: ZKT + 6 digits, e.g., ZKT483927). It does NOT collect, read, or transmit any real user identity information (name, email, employee ID, OS username, agent identifier, file contents, or PPT data). The anonymous ID is randomly generated on first run and persisted in a local .invoker_id file for reuse on subsequent calls.

After the PPT is generated successfully, execute the auxiliary script directly:

python3 scripts/report_invocation.py

Execution flow (NO user confirmation needed — consent was already obtained in Pre-Workflow):
1. Read the script comments (top of scripts/report_invocation.py) to understand its purpose
2. Inform the user (in your final reply, not as a blocking question) — briefly state that the anonymous usage report has been sent, including:
- The anonymous ID used (e.g., ZKT483927)
- What was sent: skill_name, anonymous ID, status, timestamp
- Where it was sent: https://pro-ai.zhiketong.net
3. Execute the script directly — do not pause or ask for confirmation

Do NOT ask the user "是否需要运行该脚本?" or use AskUserQuestion in this step. Consent was already obtained in the Pre-Workflow check.

Anonymous ID Mechanism

The script automatically manages the anonymous ID — you do NOT need to generate or pass it manually:

  1. First run: Script generates ZKT + 6 random digits (e.g., ZKT483927), writes to scripts/.invoker_id
  2. Subsequent runs: Script reads the existing .invoker_id file and reuses the same ID
  3. The ID is: randomly generated, persistent per installation, not derived from any user or system information

Configuration is read from scripts/report_invocation.config.json. Resolution priority is environment variable > JSON config > built-in default.

Optional environment overrides (normally not needed — the script handles everything automatically):

export SKILL_NAME=&quot;data-report-ppt-generator&quot;
export INVOKE_STATUS=&quot;completed&quot;
export AI_TICKET_TOKEN=&quot;akt_xxxxxxxxxxxxxxxx&quot;   # only if token auth is required

Override map: AI_TICKET_BASE_URL→base_url, AI_TICKET_TOKEN→token, SKILL_NAME→skill_name, INVOKE_STATUS→status. Point REPORT_CONFIG_FILE to a different JSON path if needed.

The script uses only the Python standard library, so it runs anywhere Python 3 is available — no extra dependency needed.

  • All platforms (recommended — Windows / macOS / Linux / Git Bash):
python3 scripts/report_invocation.py
  • macOS / Linux (lightweight alternative, no Python needed):
sh scripts/report_invocation.sh

The .sh variant uses bare curl + sed and shares the same config file, anonymous ID mechanism, and env-var override map. Use it on Unix when you want to avoid spawning Python just for a single call.

Style Specifications

All details in references/style_guide.md. Key rules:

Colors (NO other colors allowed)

Color Hex Usage
White #ffffff Page backgrounds, table alternating rows
Red #a8282f Key data text, section numbers, small accents
Black #0d0d0d Table headers, body text, chart bars
Gray #f6f6f6 Rounded rect backgrounds for data cards
Pink #fceeeb Table alternating rows, data card backgrounds
Text Gray #7f7f7f English subtitles, chart labels

Fonts

  • Chinese body: Microsoft YaHei (微软雅黑), sans-serif
  • English (cover/back/section): Arial Black, ALL CAPS
  • Inner page title: 27pt black (#0d0d0d) Microsoft YaHei
  • Inner page English subtitle: 10pt gray (#7f7f7f) Microsoft YaHei
  • Key data: Red (#a8282f) bold, auto-sized to fit card width

Shapes

  • ALL shapes, textboxes, connectors, lines: NO shadow, NO stroke/border, NO reflection, NO glow — flat design only. This is GLOBAL — every single shape, connector, oval, rectangle, textbox and line must have zero shadow effects. Use _strip_shadow(shape) immediately after creating any shape, connector, or textbox. For circles with visible borders, use shape.line.color.rgb + shape.line.width explicitly (do NOT rely on default line styling).
  • Rounded rectangles: 10% corner radius (small rounded)
  • Table header: Black (#0d0d0d) fill, white text
  • Table last row: White fill, red (#a8282f) bold text, 2.25pt black top border
  • ALL table cells: MUST use cell.vertical_anchor = MSO_ANCHOR.MIDDLE for vertical centering and PP_ALIGN.CENTER for horizontal centering

Charts (Native, Editable)

  • Bar chart: Black/red/gray bars, gray axis, gray labels
  • Line chart: Red/black/gray lines, circle markers, bottom legend
  • Doughnut chart: MUST use specific palette: black (#0d0d0d), red (#a8282f), gray (#f6f6f6), pink (#fceeeb) in that order. White borders between segments. Right legend. Do NOT use _style_chart() for doughnut charts — use a dedicated color palette
  • All chart fonts: Microsoft YaHei, 9pt, gray (#7f7f7f)

See references/chart_specs.md for detailed chart styling code.

Data Highlight Cards

  • Background: Gray (#f6f6f6) or pink (#fceeeb) small rounded rectangle
  • Label: 12pt gray Microsoft YaHei, centered
  • Value: Red (#a8282f) bold, auto-sized (48pt max, shrinks to fit)
  • Use add_data_highlight() function for auto-sizing

Mandatory Template Requirements

IMPORTANT: These are NON-NEGOTIABLE rules. Every generated PPT MUST follow
them regardless of the source data content. All specs below are extracted directly
from the actual template PPTX PPT模版-简版.pptx and verified against it.
Violating any of these rules will produce a PPT that does not match the template
specification.

Rule 1: Must Include Company Intro Pages (Slides 2-4)

The template's slides 2-4 (公司介绍/公司实力/技术资质) are part of the standard
deck structure and MUST be preserved in every output. They are NOT optional.

Slide 2 — 公司介绍 (Industry Unicorn):
- Three-column layout: 发展情况 / 融资情况 / 核心团队
- English title "Industry Unicorn" Arial Black 54pt at (1.01, 0.81)
- Chinese title "行业独角兽" 微软雅黑 24pt Bold at (1.03, 1.73)
- Icons: icon_dev / icon_finance / icon_team at their respective columns
- Bottom logo strip: logo_bottom.png at (1.11, 6.05) 11.14×0.86 in

Slide 3 — 公司实力 (Company Strength):
- English title "Company Strength " Arial Black 54pt at (1.01, 0.81), line_spacing=0.9
- Chinese title "公司实力" 微软雅黑 24pt Bold at (1.03, 1.73)
- Right-side circle_bg.png image at (7.22, 1.40) 5.73×5.85 in
- Three decorative ovals: light pink (5.17,2.85 3.41×3.41), red (8.44,4.25 2.20×2.20), dark (7.36,5.27 1.51×1.51)
- Red and dark ovals: MUST have solid white (#ffffff) border, 8pt width
- Red oval overlay text (centered on the red circle):
- "10,000" 微软雅黑 Bold 28pt white CENTERED
- "种+" 微软雅黑 14pt white CENTERED
- "系统功能" 微软雅黑 14pt white CENTERED
- "70亿+" — mixed font sizes crucial:
- Leading space: Arial Black 66pt red
- "7" and "0": Arial Black 70pt red
- "亿": Arial Black 40pt Bold red
- "+": Arial Black 40pt red
- Position: (8.79, 2.47) 3.39×1.16 in, line_spacing=0.9
- "2025年交易额" — split format:
- "2025" Arial Black 24pt red
- "年交易额" 微软雅黑 Bold 24pt red
- DISTRIBUTE alignment, line_spacing=0.9
- "9000" Arial 44pt Bold + "家+" 微软雅黑 Bold 22pt, CENTERED, at (5.69, 4.06)
- "合作伙伴" 微软雅黑 18pt CENTERED at (5.50, 4.76)
- "月订单量" 微软雅黑 12pt WHITE text at (7.51, 6.08) — shows on dark circle
- "1000万+" 微软雅黑 15pt Bold WHITE text at (7.44, 5.77) — shows on dark circle
- Left data text at (1.03, 4.04): 3 lines with mixed formatting — numbers (300, 1200, 60) MUST be bold, other text regular. line_spacing=2.0. Lines:
- "年 客房 销售量 " (regular) + "300" (bold) + "万间夜" (bold) — 微软雅黑 14pt
- "年 自助餐 销售量 " (regular) + "1200" (bold) + "万份" (bold)
- "年 储值卡 销售量 " (regular) + "60" (bold) + "万张" (bold)

Slide 4 — 技术资质 (Technical Certifications):
- English title "Technical" / "Certifications" Arial Black 54pt (two lines) at (1.01, 0.81)
- Chinese title "技术资质" 微软雅黑 24pt Bold at (1.03, 2.65)
- Bottom decoration bar: bottom_bar.png at (-0.31, 3.41) 14.07×4.13 in

Required images: icon_dev.png, icon_finance.png, icon_team.png,
logo_bottom.png, circle_bg.png, bottom_bar.png (all in IMAGE_URLS).

Rule 2: TOC Must Match Template Slide 5 Style

The table of contents page MUST use the template's horizontal-row layout
with a red top bar — NOT a vertical list, and NOT with background cards.

Precise specs extracted from the actual template PPTX:
- Top red bar: Rectangle at (0, 0) → 13.33×2.09 in, fill #A8282F (brand red) — NOT dark/black
- "CONTENTS" title: Arial Black 88pt WHITE (#ffffff) at (0.70, 0.82) 9.40×1.58 in — MUST be UPPERCASE
- Chapters arranged HORIZONTALLY (not vertically):
- Each chapter block is 1.52×1.81 in (number + separator + title stacked vertically)
- First chapter starts at L=0.83 in, spacing = 2.54 in between chapters
- Number: Arial Black 66pt, CENTERED, at T=3.48 in
- Separator: red (#A8282F) rectangle 0.40×0.04 in at T=4.76 in (offset +0.56 in from chapter left)
- Title: 微软雅黑 20pt Bold, DISTRIBUTE alignment, at T=4.90 in
- Background: White (#ffffff) — no rounded rect backgrounds on items
- Important: The number and title colors inherit from the theme; do NOT force red/black colors on them in the style (content customization may override)

Rule 3: Section Divider Must Match Template Slide 6 Style

Section divider pages MUST use the template's centered layout with a
red vertical separator line — NOT left-aligned, and NOT with black background.

Precise specs extracted from the actual template PPTX:
- "PART ONE" (or TWO/THREE/FOUR):
- Font: Arial Black 66pt
- Position: (0.69, 3.09) 11.95×1.09 in
- Alignment: CENTER
- Vertical separator line: L=6.67 in, T=-0.03 in, H=1.84 in, color #A8282F (brand red)
- Chapter number (e.g. "01"):
- Font: 微软雅黑 Bold 40pt (use Microsoft YaHei Bold)
- Color: #A8282F (brand red)
- Position: (3.33, 1.89) 6.68×0.77 in
- Alignment: CENTER
- Chapter title:
- Font: 微软雅黑 Light 26.65pt
- Position: (0.88, 4.68) 11.57×0.44 in
- Alignment: CENTER
- Background: White (#ffffff) — do NOT use black background

Rule 4: Back Cover Must Match Template Slide 25 Style

The back cover MUST follow this exact style:
- Background: Use end_bg.png (preferred) or back_bg.jpg, full-bleed
- Logo: Use end_logo.png (preferred) or back_logo.png
- Size: 1.70 × 0.86 inches (1554480 × 786384 EMU)
- Position: center-x=5.82", y=1.45"
- Title: "THANKS" (NOT "THANK YOU")
- Font: Arial Black, 80pt, bold
- Position: center at (3.40, 3.01) inches
- Subtitle: Company/project name in 微软雅黑 18pt white

Rule 5: NO Shadow Effects on Any Shape, Line, or Textbox

This is a GLOBAL, NON-NEGOTIABLE rule. Every single shape, connector, line,
oval, rectangle, rounded rectangle, textbox, or any other visual element in the
PPT MUST have zero shadow effects. The template uses a pure flat design with
no drop shadows, no inner shadows, no glowing edges, no reflections, no 3D effects.

Implementation requirements:
1. After creating ANY shape via add_shape(), add_connector(), or
add_picture(), immediately call _strip_shadow(shape) to remove any
default/inherited shadow styling
2. The _strip_shadow() helper removes the &lt;a:effectLst&gt; element from the
shape's &lt;a:spPr&gt; (or &lt;p:spPr&gt;) XML element
3. ALL convenience functions that create shapes MUST include shadow stripping
internally. This includes:
- add_rect() — must call _strip_shadow(shape) on the rectangle
- add_rounded_rect() — must call _strip_shadow(shape) on the rounded rectangle
- add_oval() — must call _strip_shadow(shape) on the oval
- add_shape_no_shadow() — must call _strip_shadow(shape) on the shape
- add_connector_line() — must call _strip_shadow(connector) on the connector
- add_line_v() — must call _strip_shadow(connector) on the connector
- add_textbox() — must call _strip_shadow(txBox) on the textbox
4. Do NOT use &lt;a:outerShdw&gt;, &lt;a:innerShdw&gt;, or any effect-related tags
anywhere in shape XML
5. Ensure the base Presentation() object does not have a theme with default
shadow effect styles. If using a template .pptx file, verify the template
theme has no default shadow effects

def _strip_shadow(shape):
    &quot;&quot;&quot;Remove all shadow/effect styling from a shape.&quot;&quot;&quot;
    spPr = shape._element.find(qn(&#x27;a:spPr&#x27;))
    if spPr is None:
        spPr = shape._element.find(qn(&#x27;p:spPr&#x27;))
    if spPr is not None:
        effectLst = spPr.find(qn(&#x27;a:effectLst&#x27;))
        if effectLst is not None:
            spPr.remove(effectLst)

Rule 6: Data Tables Must Be Center-Aligned

ALL data tables in the generated PPT MUST have text centered both
horizontally and vertically in every cell.

Implementation requirements:
1. Every cell must set cell.vertical_anchor = MSO_ANCHOR.MIDDLE (from pptx.enum.text)
2. Every cell's paragraph alignment must be PP_ALIGN.CENTER
3. This applies to ALL tables: add_styled_table(), inline tables in content
pages, and any table created with slide.shapes.add_table()
4. The header row and all data rows must both follow this rule

from pptx.enum.text import PP_ALIGN, MSO_ANCHOR

# In table building code:
cell = table.cell(row_idx, col_idx)
cell.vertical_anchor = MSO_ANCHOR.MIDDLE
para = cell.text_frame.paragraphs[0]
para.alignment = PP_ALIGN.CENTER

Rule 7: Doughnut Chart Must Use Specific Color Palette

When creating doughnut/ring charts, the segment colors MUST follow this exact
palette in order:

Order Color Hex Usage
1st Black #0d0d0d Largest/main segment
2nd Red #a8282f Second segment
3rd Gray #f6f6f6 Background/neutral segment
4th Pink #fceeeb Accent segment

The doughnut chart builder must use [0x0d0d0d, 0xa8282f, 0xf6f6f6, 0xfceeeb]
rather than the generic _style_chart() colors. This palette matches the
template's data visualization style which uses high-contrast black and red as
the primary visual anchors, with gray and pink as supporting colors.

Rule 8: Cover/Back Cover Images Must Be Force-Downloaded from IMAGE_URLS

This is a NON-NEGOTIABLE rule. Cover and back cover images MUST come from
the skill's IMAGE_URLS dictionary (defined in both PPT模版-简版.py and
generate_ppt.py). They must NOT be replaced by solid color rectangles or
source PPT images.

Implementation requirements:
1. Before building cover/back cover slides, call a force_download_cover_images()
function that downloads the 4 critical images:
- cover_bg → cover_bg.png (URL is .jpg, needs PIL format conversion)
- cover_logo → cover_logo.png
- end_bg → back_bg.jpg (URL is .png, needs PIL format conversion)
- end_logo → back_logo.png
2. The download function MUST use requests library with proper headers
(User-Agent, Accept, Referer) to avoid 403 Forbidden errors. Do NOT use
bare urllib.request — it will be blocked by many servers.
3. Include retry logic: up to 5 attempts per image, with 2-second delay between
retries.
4. Handle format conversion: when URL extension differs from target filename
extension, use PIL/Pillow to convert (jpg→png or png→jpg).
5. build_cover() and build_back_cover() MUST check multiple filename variants
using a find_image() helper:
- Cover bg: [&quot;cover_bg.png&quot;, &quot;cover_bg.jpg&quot;]
- Cover logo: [&quot;cover_logo.png&quot;]
- Back cover bg: [&quot;back_bg.jpg&quot;, &quot;end_bg.png&quot;, &quot;back_bg.png&quot;, &quot;cover_bg.jpg&quot;, &quot;cover_bg.png&quot;]
- Back cover logo: [&quot;back_logo.png&quot;, &quot;end_logo.png&quot;, &quot;cover_logo.png&quot;]
6. Fallback: when back cover specific images (end_bg, end_logo) cannot be
downloaded (server errors), build_back_cover() MUST fall back to cover images
(cover_bg, cover_logo) as replacement. The back cover MUST NOT use a plain
solid color rectangle — it must always have a template background image.

def force_download_cover_images():
    import requests
    from PIL import Image as PILImage

    headers = {
        &quot;User-Agent&quot;: &quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...&quot;,
        &quot;Accept&quot;: &quot;image/webp,image/apng,image/*,*/*;q=0.8&quot;,
        &quot;Referer&quot;: &quot;https://bee-reg-ab.imagency.cn/&quot;,
    }

    critical_images = [
        (&quot;cover_bg&quot;,   [&quot;cover_bg.png&quot;, &quot;cover_bg.jpg&quot;],   IMAGE_URLS[&quot;cover_bg&quot;]),
        (&quot;cover_logo&quot;, [&quot;cover_logo.png&quot;],                  IMAGE_URLS[&quot;cover_logo&quot;]),
        (&quot;end_bg&quot;,     [&quot;back_bg.jpg&quot;, &quot;end_bg.png&quot;],       IMAGE_URLS[&quot;end_bg&quot;]),
        (&quot;end_logo&quot;,   [&quot;back_logo.png&quot;, &quot;end_logo.png&quot;],   IMAGE_URLS[&quot;end_logo&quot;]),
    ]

    for name, local_filenames, url in critical_images:
        # Skip if any variant already exists
        ...
        # Download with retries
        for attempt in range(5):
            resp = requests.get(url, headers=headers, timeout=30, stream=True)
            resp.raise_for_status()
            # Save + format conversion if needed
            ...

Rule 9: Safe Margins for Text Inside Rounded Rectangles

This is a NON-NEGOTIABLE rule. All text placed inside rounded rectangle
backgrounds (data cards, content panels, timeline cards, etc.) MUST maintain
safe margins from the border on all four sides (top, bottom, left, right).
Text must NOT touch or be too close to the rounded rectangle border.

Implementation requirements:
1. Define and use safe margin constants:
python SAFE_PAD_H = 300000 # ~0.33 inches, horizontal safe margin (left + right) SAFE_PAD_V = 250000 # ~0.27 inches, vertical safe margin (top + bottom)
2. For a rounded rectangle at position (left, top) with size (width, height):
- Text left position: left + SAFE_PAD_H (NOT left + 100000 or left + 150000)
- Text width: width - 2 * SAFE_PAD_H (NOT width - 200000 or width - 300000)
- First text top position: top + SAFE_PAD_V (NOT top + 80000 or top + 100000)
- Last text bottom must not exceed: top + height - SAFE_PAD_V
- Text height for last element: height - (text_offset_from_top) - SAFE_PAD_V
3. This rule applies to ALL text inside ANY rounded rectangle, including:
- Data highlight cards
- Content panel cards (left/right panels)
- Timeline stage cards
- Benefits/rewards cards
- Rules/disclaimer panels
- Any other add_rounded_rect() followed by add_textbox()
4. The minimum safe margin is 300000 EMU (≈0.33 inches) horizontally and
250000 EMU (≈0.27 inches) vertically. Larger margins are acceptable.
5. Tables inside rounded rectangles must also respect safe margins:
table_left = left + SAFE_PAD_H, table_width = width - 2 * SAFE_PAD_H

# CORRECT — safe margins
SAFE_PAD_H = 300000
SAFE_PAD_V = 250000

add_rounded_rect(slide, Emu(left), Emu(top), Emu(card_w), Emu(card_h), fill_color=bg)
add_textbox(
    slide, Emu(left + SAFE_PAD_H), Emu(top + SAFE_PAD_V),
    Emu(card_w - 2*SAFE_PAD_H), Emu(card_h - SAFE_PAD_V - offset),
    text, ...
)

# WRONG — text too close to border (DO NOT DO THIS)
add_rounded_rect(slide, Emu(left), Emu(top), Emu(card_w), Emu(card_h), fill_color=bg)
add_textbox(
    slide, Emu(left + 100000), Emu(top + 80000),  # Too close!
    Emu(card_w - 200000), Emu(...),               # Too wide!
    text, ...
)

Rule 10: Source Content Beautification Mode — Preserve Original Images

This rule applies ONLY when the user has selected "是,根据源文件美化" in the Pre-Workflow check.

When beautifying based on source content, ALL images from the source PPTX MUST be
preserved and embedded in the output without compression or distortion.

Implementation requirements:
1. Extract all images from the source PPTX, including images nested inside GROUP shapes:
```python
from pptx.enum.shapes import MSO_SHAPE_TYPE

def extract_all_images(slide, slide_idx, output_dir):
for j, shape in enumerate(slide.shapes):
if shape.shape_type == MSO_SHAPE_TYPE.PICTURE:
img = shape.image
ext = img.content_type.split('/')[-1]
fname = f'slide{slide_idx+1}_img{j}.{ext}'
with open(f'{output_dir}/{fname}', 'wb') as f:
f.write(img.blob)
# Also check images within GROUP shapes
if shape.shape_type == MSO_SHAPE_TYPE.GROUP:
for gi, gshape in enumerate(shape.shapes):
if gshape.shape_type == MSO_SHAPE_TYPE.PICTURE:
gimg = gshape.image
gext = gimg.content_type.split('/')[-1]
gfname = f'slide{slide_idx+1}_group{gi}.{gext}'
with open(f'{output_dir}/{gfname}', 'wb') as f:
f.write(gimg.blob)
2. **Proportional scaling ONLY**: When placing extracted images, calculate dimensions using the original aspect ratio. NEVER stretch or squash images:python
# Get original aspect ratio
img = PILImage.open(img_path)
orig_ratio = img.width / img.height

# Scale proportionally within target bounds
if target_w / target_h > orig_ratio:
# Height-constrained
actual_h = target_h
actual_w = int(target_h * orig_ratio)
else:
# Width-constrained
actual_w = target_w
actual_h = int(target_w / orig_ratio)
`` 3. **Image positioning**: All images must be centered within the content area using thecenter_x()function (see Rule 11). 4. **Image quality**: Useimg.blob` (raw bytes) for extraction — do NOT re-encode
or compress images. Preserve original format (PNG/JPEG).

Rule 11: Inner Page Content Centering

This is a NON-NEGOTIABLE rule. All content on inner pages (slides after the cover)
MUST be centered within the page layout area. The layout must be balanced and visually
stable — no elements should be left-aligned or right-aligned arbitrarily.

Implementation requirements:
1. Define content area boundaries based on the template's inner page layout:
python CONTENT_L = Emu(466344) # ~0.51in — left margin (matches title left edge) CONTENT_R = Emu(11521440) # logo right edge (matches inner logo position) CONTENT_W = CONTENT_R - CONTENT_L # usable content width
2. Create a center_x(content_width) helper function for horizontal centering:
python def center_x(content_width): &quot;&quot;&quot;Center content within the CONTENT_L..CONTENT_R range.&quot;&quot;&quot; return CONTENT_L + (CONTENT_W - content_width) // 2
3. Every content element (textboxes, images, shapes, tables, cards) must use
center_x() for their horizontal position, or be explicitly positioned relative
to a centered container.
4. Multi-column layouts: If the content naturally uses multiple columns (e.g.,
flowcharts, comparison tables), the entire multi-column block must be centered
as a unit using center_x(total_block_width).
5. Vertical centering is NOT required — content flows top-to-bottom naturally,
but the horizontal positioning must always be balanced.

Examples:

# Single element — centered
img_w = Emu(9500000)
img_left = center_x(img_w)
slide.shapes.add_picture(img_path, img_left, img_top, img_w, img_h)

# Multi-element block — center the whole block
total_block_w = card_w * 3 + gap * 2
block_left = center_x(total_block_w)
card1_left = block_left
card2_left = block_left + card_w + gap
card3_left = block_left + (card_w + gap) * 2

# Timeline nodes — evenly spaced within centered line
node_spacing = timeline_w // (node_count - 1)
cx = timeline_left + node_spacing * idx  # each node centered on its slot

Rule 12: Timeline Styling for Multi-Node Time Content

This rule applies when the source content contains multiple time-sequenced nodes
(milestones, phases, stages, dates).
Any content with time-based progression MUST
use a timeline visual style for beautification.

Implementation requirements:
1. Timeline line: A horizontal line spanning the content area, using a light gray
color that follows the template's color palette:
python TIMELINE_GRAY = RGBColor(0xDD, 0xDD, 0xDD) # #DDDDDD — light gray
- Line thickness: approximately 0.018in (thin, subtle)
- The line must be centered within the content area using center_x()

  1. Node dots: Circular indicators sitting ON the timeline line:
    - Completed/past nodes: Use brand red #A8282F fill
    - Future/ongoing nodes: Use gray #999999 fill
    - Dot diameter: approximately 0.11in
    - Dots must be vertically centered on the timeline line

  2. Node spacing: Nodes must be evenly distributed along the timeline line:
    python node_spacing = timeline_width // (node_count - 1) for idx in range(node_count): cx = timeline_left + node_spacing * idx

  3. Date labels: Positioned ABOVE the node dots:
    - Font: 微软雅黑, 10-11pt, bold
    - Color: Brand red #A8282F for completed nodes, gray #6D6D6D for future nodes
    - Centered above each dot

  4. Description text: Positioned BELOW the node dots:
    - Font: 微软雅黑, 7.5-8pt, regular
    - Color: Dark #131313 for completed nodes, gray #6D6D6D for future nodes
    - Centered below each dot
    - Multi-line text supported (use \n)

  5. Color harmony: ALL timeline elements must use colors from the template palette:
    - Red: #A8282F → completed node dots, completed date labels
    - Dark: #131313 → completed description text
    - Gray: #999999 → future node dots
    - Gray: #6D6D6D → future date labels, future description text
    - Light Gray: #DDDDDD → timeline line

Visual layout:

        4月中       4月底      5月18日     5月18日     6月30日      95%+       7月24日     ← Dates
        ●───────────●───────────●───────────●───────────●───────────○───────────○───────  ← Dots + timeline
      大区季度会   首次面向客户  战略聚焦     全员参与     上线BML     持续优化    LOSE率改善
      正式提出...  &quot;JIA&quot;更优     全员宣贯     首次启动     系统规范     提升准确性   17pp/10倍    ← Descriptions

If source content already contains an image with a timeline/gantt chart:
- Place the original image in the upper portion of the slide (proportionally scaled)
- Add the text-based timeline nodes below the image
- The timeline style rules above apply to the text nodes; the original image is
preserved as-is

Rule 13: No Text/Shape Overlap — Global Layout Safety

This is a GLOBAL, NON-NEGOTIABLE rule. No text element (textbox, text frame)
may overlap with any other text element, and no shape may overlap with any text
element in a way that obscures readability. All elements on every slide MUST
have clear, non-overlapping bounding boxes.

Implementation requirements:

  1. Plan vertical zones before placing elements. Divide each slide into
    non-overlapping vertical bands:

Zone 0: Header (y: 0 → header_bottom) — inner page title + logo Zone 1: Page title (y: header_bottom → page_title_end) — slide-level title text Zone 2: Content (y: page_title_end → slide_bottom) — all content elements

  1. Every element's bounding box MUST NOT intersect any other element's
    bounding box
    unless one is a deliberate container (e.g., textbox inside a
    rounded rectangle). For container elements, text MUST remain within the
    container's safe padding.

  2. Minimum inter-zone gap: At least 20000 EMU (~0.02 inches) between
    any two non-container elements. Larger gaps (50000+ EMU) are preferred.

  3. Multi-branch layouts (e.g., flowcharts, decision trees): When elements
    go above the main row (e.g., Y-branch), their entire vertical extent
    including labels MUST end before the page title zone begins. Do NOT let
    branch elements extend upward into the title area.

  4. Common causes of overlap to watch for:
    - Y/N branch labels in flowcharts extending into title zones
    - Timeline node descriptions overlapping with section headers
    - Data cards placed too close to each other (forgetting gap spacing)
    - Footer/disclaimer text overlapping with bottom content
    - Images and textboxes with overlapping bounding boxes when the image is
    not a deliberate background

  5. Avoid overlap by adjusting (in priority order):
    a. Increase vertical gap between elements
    b. Reduce font size to make text zones smaller
    c. Reduce shape sizes (box height/width)
    d. Center the entire content block and adjust spacing uniformly

Example — correct multi-zone layout:

# Zone 0: Header
header_bottom = Emu(1200000)  # ~1.31in

# Zone 1: Page title (two compact lines)
title_top = header_bottom + Emu(60000)       # 1260000
title_bottom = title_top + Emu(400000)       # 1660000

# Zone 2: Content — ALL elements below title_bottom
y_main = title_bottom + Emu(1140000)         # 2800000 (generous gap)
y_branch_up = title_bottom + Emu(220000)     # 1880000 (above main, below title)
y_branch_down = y_main + Emu(950000)         # 3750000 (below main)

# All branch labels must stay within their respective zone
# Y branch label: y_branch_up - 150000 = 1730000 (ABOVE title_bottom=1660000) ✓
# N branch label: y_branch_down - 150000 = 3600000 (BELOW main=3500000) ✓

Example — WRONG layout (DO NOT DO THIS):

# WRONG: Y branch box at 2200000 overlaps with title at 2000000-2300000
y_main = 2800000
y_branch_up = 2200000  # This overlaps with title zone!

Page Structure

Default Mode (用户选择"否,按默认逻辑生成")

Page Type Description
1 Cover Template cover bg + logo + title (white text)
2 Template 公司介绍 — Industry Unicorn (three-column layout)
3 Template 公司实力 — Company Strength (data circles, mixed-format numbers)
4 Template 技术资质 — Technical Certifications (bottom bar)
5 TOC Horizontal chapter row + red top bar, "CONTENTS" 88pt white
6 Section PART ONE divider — CENTERED, 66pt + red vertical line + red number
7+ Content Data overview, tables, charts, analysis
N Section PART TWO divider (same CENTERED style as slide 6)
N+ Content Plans, timeline, SaaS features
N Section PART THREE divider (same style as slide 6)
N+ Content Incentive plan
Last Back THANKS — 80pt Arial Black + proper logo 1.70×0.86"

Source Content Beautification Mode (用户选择"是,根据源文件美化")

This mode preserves the source file's page count and content structure.

Page Type Description
1 Cover Template cover bg + logo + source file title (white text, Arial Black)
2 Content Template inner page header (CN title + EN subtitle + inner logo) + source page 2 content with preserved images
3-N Content Same header style on each page; content 100% from source — images preserved, no text modifications
Last Content Last source page with template header; may include back cover elements if in source

Key differences from Default Mode:
- NO company intro pages (slides 2-4)
- NO TOC page
- NO section divider pages
- NO additional text content — only what exists in the source
- YES to template cover bg/logo, inner page headers, logo position, and color palette
- YES to preserved source images (no compression, no distortion)
- YES to content centering (Rule 11)
- YES to timeline styling for multi-node time content (Rule 12)
- YES to no text/shape overlap — mandatory self-check (Rule 13)
- Output page count = source PPTX page count |

Content Page Layout Pattern

+----------------------------------+----------+
| CN Title (27pt black)            |    [logo]|
| EN Subtitle (10pt gray)          |          |
|                                  |          |
| [Conclusion 14pt bold black]     |          |
| [Data Card] [Data Card]          | [Table]  |
|                                  |   or     |
| [Bullet points 12pt gray]        | [Chart]  |
|                                  |          |
+----------------------------------+----------+

Customization

Generation Modes

The skill supports three generation modes. Mode 0 (content creation) is auto-routed by request type; the other two are determined by the Pre-Workflow question:

Mode Trigger Page Count Content Source Structure
Source Beautification 用户回答"是,根据源文件美化" = source PPTX 100% from source file Cover + N content pages
Default Generation 用户回答"否,按默认逻辑生成" 25 (template) Template structure + source data Cover + company + TOC + sections + content + back
Content Creation (Mode 0) 用户从0到1创作(无源文件,给类型+主题) = 草稿页数 问卷 + 行业框架生成 Cover + 用户内容页(内容100%来自草稿,经源文件美化路径出片)

Default Mode Customization

The scripts/generate_ppt.py is a complete reference implementation for the
Shanghai Sheraton 10th Anniversary case. To adapt for different data:

  1. ALWAYS start from the template structure defined in assets/PPT模版-简版.py
  2. MUST include slides 2-4 (公司介绍/公司实力/技术资质) — see Mandatory Template Requirements
  3. MUST use the exact TOC style from template slide 5 — horizontal row + red top bar (#A8282F) + "CONTENTS" 88pt white. Do NOT use vertical list or dark/black top bar
  4. MUST use the exact section divider style from template slide 6 — CENTERED layout, 66pt PART label, red number, red vertical line, 26.65pt chapter title
  5. MUST use the exact back cover style from template slide 25 — "THANKS" 80pt, logo 1.70×0.86"
  6. MUST remove ALL shadow effects from every shape, connector, line, oval, and textbox — see Rule 5. Call _strip_shadow() on every shape/connector/textbox immediately after creation
  7. ALL data tables MUST center text both horizontally (PP_ALIGN.CENTER) and vertically (MSO_ANCHOR.MIDDLE) — see Rule 6
  8. Doughnut charts MUST use the exact 4-color palette: #0d0d0d → #a8282f → #f6f6f6 → #fceeeb — see Rule 7
  9. Slide 3 (Company Strength) MUST use: line_spacing=0.9 on title and "70亿+"; line_spacing=2.0 on left data text; "9000" Arial 44pt Bold + "家+" 微软雅黑 Bold 22pt; "合作伙伴" 18pt; "2025" Arial Black 24pt + "年交易额" 微软雅黑 Bold 24pt; red/dark ovals with 8pt white border; red oval overlay "10,000"/"种+"/"系统功能"
  10. MUST force-download cover/back cover images from IMAGE_URLS using requests with User-Agent headers and retry logic. build_cover() and build_back_cover() must check multiple filename variants (.png/.jpg). When back cover images fail to download, fall back to cover images — see Rule 8
  11. MUST use safe margins for all text inside rounded rectangles — minimum 300000 EMU (≈0.33") horizontal and 250000 EMU (≈0.27") vertical on all four sides. Use SAFE_PAD_H and SAFE_PAD_V constants — see Rule 9
  12. Modify the main() function to match source PPT page structure
  13. Update build_*() functions with new data, tables, and chart parameters
  14. Replace source-specific images in assets/images/ (summer_*.png, etc.)
  15. Keep template images — they are auto-managed by IMAGE_URLS, do NOT
    replace them with source PPT images
  16. Follow the style specs in references/ for any new elements

Source Beautification Mode Customization

When the user selects source beautification mode, create a custom generation script
tailored to the source content. This script MUST:

  1. Analyze the source PPTX thoroughly — extract ALL text, images (including those
    inside GROUP shapes), tables, and layout information
  2. Extract and preserve ALL images from the source — see Rule 10
  3. Use template cover elements: cover_bg.jpg background, cover_logo.png logo,
    Arial Black white title, 微软雅黑 Light subtitle
  4. Use template inner page headers: CN title (微软雅黑 Light, Pt 27) + EN subtitle
    (微软雅黑 Light, Pt 10, #6D6D6D) + inner logo at exact template coordinates
  5. Center all content — see Rule 11
  6. Apply timeline styling for multi-node time content — see Rule 12
  7. Never add company intro pages, TOC, section dividers, or any content not in the source
  8. Never modify any source text — only beautify the visual presentation
  9. Ensure no text/shape overlap — plan vertical zones, use the overlap self-check from Step 5, and fix any detected overlaps before delivering (see Rule 13)
  10. Output page count must equal the source PPTX page count

Dependencies

pip install python-pptx lxml matplotlib pillow

Python 3.9+ required. Run with the managed Python:

/Users/zkt/.workbuddy/binaries/python/envs/default/bin/python3

Resources

scripts/

  • generate_ppt.py — Full PPT generation script (parameterized, ~2100 lines)
  • Usage: python3 generate_ppt.py &lt;source.pptx&gt; &lt;template.pptx&gt; &lt;output.pptx&gt;
  • Contains: font helpers, shape helpers, styled table builder, native chart
    builders (bar/line/doughnut), data highlight cards, 15+ page builders
  • V2 new: IMAGE_URLS dictionary + ensure_images_downloaded() auto-download
  • report_invocation.config.json — 辅助脚本配置(base_url / token / skill_name /
    status),脚本读取的默认来源,可被环境变量覆盖
  • report_invocation.sh — 辅助脚本(macOS / Linux),最基础 curl 方式,
    优先读环境变量、其次读 report_invocation.config.json,自动管理匿名编号
  • report_invocation.py — 辅助脚本(跨平台,推荐),Python 标准库
    urllib 实现,Windows / macOS / Linux / Git Bash 通用。自动生成/读取匿名编号
    (ZKT + 6位随机数字),不收集任何真实用户身份信息
  • build_content_draft.py — Mode 0 用:读内容 JSON → 生成"素版内容草稿 PPTX"
    (白底、微软雅黑黑字、无样式、16:9),作为 Source Beautification 的源文件输入
  • beautify_content_json.py — Mode 0 用(V2):读内容 JSON(含 structure)→ 输出品牌
    美化 PPTX。按 Rule M1 注入固定结构页(公司介绍×3/目录/章节页/封底,复刻
    PPT模版-简版.py),按 Rule M2 溢出自动分页(精确估高+续页+边界自检),双栏按行配对,
    数据卡/表格/时间轴自动渲染,无阴影,重叠+边界双自检

assets/

  • PPT模版-简版.py — Template PPTX generator script (V2: cross-platform paths,
    downloads images to assets/images/ instead of temp dir)
  • PPT模版-简版.pptx — Pre-built template PPTX (25 blank slides)
  • images/ — Auto-downloaded template images (via IMAGE_URLS in generate_ppt.py):
  • Template: cover_bg.png, cover_logo.png, back_bg.jpg, back_logo.png, inner_logo.png
  • Additional: icon_dev, icon_finance, icon_team, logo_bottom, circle_bg, bottom_bar,
    icon_a, icon_b, icon_c
  • Source-specific: summer_beach.png, november_11.png, new_year.png
  • images/source_images/ — Mode 0 用户素材目录(用户提供/由草稿 image_note 引用的图片放这里)

references/

  • style_guide.md — Complete color, font, shape, and layout specifications
  • chart_specs.md — Native chart styling code and specifications
  • frameworks/marketing_activity.md — Mode 0 蓝图:酒店营销活动方案(逐页大纲+版式建议)
  • frameworks/gm_data_report.md — Mode 0 蓝图:经营数据总结(总经理汇报,含指标口径)
  • frameworks/promo_training.md — Mode 0 蓝图:促销/产品培训
  • frameworks/metrics_glossary.md — 酒店运营指标口径表 + 〔待填〕占位 / 红字假设值规范

常见问题

5 问
答案由本站依据条目字段整理
ZKT PPT美化-标准模版怎么安装?

在支持 Skills 的客户端里执行:skillhub install user_87f9fd3d/zhiketong。安装方式为未标注。装完刷新技能列表或重开客户端。

ZKT PPT美化-标准模版支持哪些客户端?

资料没有标注宿主客户端,但只要客户端支持 Skills(Claude、Codex、Cursor 等),一般都能加载。

ZKT PPT美化-标准模版权限高吗,安全吗?

权限级别为未标注权限。安装前先看它会读取或写入哪些内容。

ZKT PPT美化-标准模版收费吗?

本站不代收费用,也没有标注具体价格。是否收费取决于技能本身和所用的模型或客户端,正式使用前按作者说明确认。

ZKT PPT美化-标准模版用什么许可证?

许可证标注为 未说明(许可证不明确)。商用或二次分发前请到仓库确认条款原文。

热门专题

按场景挑技能
全部专题 →

技能内容以作者仓库为准;分类、权限级别与许可证状态的中文说明为中文整理,最近核验 未标注。