
PPT 持续生成:在 CI/CD 管线中实现演示自动化
将 PPT 生成集成到 CI/CD 管线中,实现数据变更自动触发演示文稿更新。从 GitHub Actions 到 Jenkins 的完整实施方案。
核心结论
将 PPT 生成集成到 CI/CD 管线中,可以实现"数据更新 → 自动生成演示文稿 → 自动分发"的完整自动化链路。这在需要频繁更新数据的报告场景(周报、月报、数据看板)中特别有价值。通过 GitHub Actions 或 Jenkins 配合 OmyPPT API,几行 YAML 配置就能实现完整的 PPT 持续生成流程。
深度分析
为什么要把 PPT 生成放进 CI/CD
考虑以下场景:
你负责维护一份每周更新的销售报告 PPT。每周一早上,你需要:
- 从 CRM 系统导出最新数据
- 更新 Excel 数据源
- 打开 PPT,手动更新图表和数据
- 检查格式是否被破坏
- 保存并分享给团队
这个过程每周重复,每次耗时 30-60 分钟。如果忘记更新,团队看到的就是过期数据。
把这个流程放进 CI/CD 后:
- 数据文件推送到 Git 仓库(或定时从 CRM 拉取)
- CI/CD 管线自动触发
- 调用 OmyPPT API 从最新数据生成 PPT
- 自动提交生成的 PPTX 到仓库(或上传到共享存储)
- 通过 Slack/邮件通知团队
全程自动,无需人工干预。
GitHub Actions 实现
基本配置:
# .github/workflows/generate-ppt.yml
name: Generate Presentation
on:
push:
paths:
- 'data/**' # 数据文件变更时触发
- 'sources/**' # 源文档变更时触发
schedule:
- cron: '0 8 * * 1' # 每周一早上 8 点
workflow_dispatch: # 手动触发
jobs:
generate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: pip install omyppt-sdk
- name: Generate Presentation
env:
OMYPPT_API_KEY: ${{ secrets.OMYPPT_API_KEY }}
OMYPPT_BRAND_ID: ${{ vars.OMYPPT_BRAND_ID }}
run: |
python scripts/generate_report.py \
--source data/latest_report.pdf \
--brand $OMYPPT_BRAND_ID \
--output output/report.pptx
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: presentation
path: output/report.pptx
- name: Commit to repo
run: |
git config user.name "PPT Bot"
git config user.email "bot@example.com"
git add output/report.pptx
git commit -m "chore: update presentation [skip ci]"
git push
- name: Notify Slack
if: success()
uses: slackapi/slack-github-action@v1
with:
payload: |
{
"text": "📊 周报 PPT 已更新: ${{ github.event.head_commit.url }}"
}
生成脚本:
# scripts/generate_report.py
import argparse
from pathlib import Path
from omyppt import OmyPPT
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--source", required=True)
parser.add_argument("--brand", default=None)
parser.add_argument("--output", required=True)
args = parser.parse_args()
client = OmyPPT() # 从环境变量读取 API Key
# 生成
result = client.generate(
source=args.source,
brand_id=args.brand,
format="ppt169"
)
# 下载
output_path = Path(args.output)
output_path.parent.mkdir(parents=True, exist_ok=True)
result.download(str(output_path))
print(f"✅ 生成完成: {result.page_count} 页")
print(f"📁 文件位置: {output_path}")
# 质量检查
if result.quality_report.score < 80:
print(f"⚠️ 质量评分较低: {result.quality_report.score}/100")
if __name__ == "__main__":
main()
多报告批量生成
# .github/workflows/generate-all-reports.yml
name: Generate All Reports
on:
schedule:
- cron: '0 6 1 * *' # 每月 1 号早上 6 点
jobs:
generate:
runs-on: ubuntu-latest
strategy:
matrix:
report:
- name: "sales"
source: "data/sales_report.pdf"
- name: "marketing"
source: "data/marketing_report.pdf"
- name: "engineering"
source: "data/engineering_report.pdf"
steps:
- uses: actions/checkout@v4
- name: Generate ${{ matrix.report.name }}
run: |
pip install omyppt-sdk
python scripts/generate_report.py \
--source ${{ matrix.report.source }} \
--output output/${{ matrix.report.name }}.pptx
env:
OMYPPT_API_KEY: ${{ secrets.OMYPPT_API_KEY }}
- name: Upload
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.report.name }}
path: output/${{ matrix.report.name }}.pptx
Jenkins 实现
// Jenkinsfile
pipeline {
agent any
triggers {
cron('H 8 * * 1') // 每周一早上 8 点
pollSCM('H/15 * * * *') // 每 15 分钟检查代码变更
}
environment {
OMYPPT_API_KEY = credentials('omyppt-api-key')
}
stages {
stage('Setup') {
steps {
sh 'pip install omyppt-sdk'
}
}
stage('Generate') {
steps {
sh '''
python scripts/generate_report.py \
--source data/latest.pdf \
--output output/report.pptx
'''
}
}
stage('Quality Check') {
steps {
script {
def score = sh(
script: 'python scripts/check_quality.py output/report.pptx',
returnStdout: true
).trim().toInteger()
if (score < 80) {
unstable "质量评分低于阈值: ${score}/100"
}
}
}
}
stage('Deploy') {
steps {
// 上传到共享存储
sh 'aws s3 cp output/report.pptx s3://reports-bucket/latest/'
// 通知团队
slackSend(
message: "📊 周报 PPT 已更新",
color: "good"
)
}
}
}
post {
failure {
slackSend(
message: "❌ PPT 生成失败: ${env.BUILD_URL}",
color: "danger"
)
}
}
}
数据驱动的自动化报告
更高级的场景是从数据库或 API 直接获取数据,自动生成报告:
# .github/workflows/data-driven-report.yml
name: Data-Driven Report
on:
schedule:
- cron: '0 9 * * 1' # 每周一早上 9 点
jobs:
generate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# 第一步:从数据库/API 获取最新数据
- name: Fetch latest data
run: |
python scripts/fetch_data.py \
--api-endpoint ${{ secrets.DATA_API_URL }} \
--output data/latest.json
# 第二步:将数据转换为 Markdown 报告
- name: Prepare source document
run: |
python scripts/data_to_md.py \
--input data/latest.json \
--output data/latest_report.md
# 第三步:生成 PPT
- name: Generate presentation
run: |
pip install omyppt-sdk
python scripts/generate_report.py \
--source data/latest_report.md \
--output output/weekly_report.pptx
env:
OMYPPT_API_KEY: ${{ secrets.OMYPPT_API_KEY }}
# 第四步:分发
- name: Distribute
run: |
# 上传到云存储
aws s3 cp output/weekly_report.pptx s3://reports/
# 发送邮件通知
python scripts/notify.py \
--subject "周报已更新" \
--recipients "team@company.com" \
--link "https://reports.company.com/weekly_report.pptx"
质量门控集成
在 CI/CD 中加入质量门控,确保只有合格的 PPT 才会被分发:
# scripts/quality_gate.py
import sys
from omyppt import OmyPPT
def check_quality(output_path: str, min_score: int = 80) -> bool:
"""质量门控检查。"""
client = OmyPPT()
report = client.analyze(output_path)
checks = {
"score": report.score >= min_score,
"completeness": report.completeness >= 0.9,
"consistency": report.consistency >= 0.95,
"no_critical_issues": not report.has_critical_issues
}
all_passed = all(checks.values())
print(f"质量评分: {report.score}/100")
print(f"内容完整性: {report.completeness:.0%}")
print(f"视觉一致性: {report.consistency:.0%}")
print(f"无严重问题: {not report.has_critical_issues}")
if not all_passed:
print("❌ 质量门控未通过")
for check, passed in checks.items():
if not passed:
print(f" - {check}: FAILED")
else:
print("✅ 质量门控通过")
return all_passed
if __name__ == "__main__":
passed = check_quality(sys.argv[1])
sys.exit(0 if passed else 1)
实用建议
管线设计原则
- 幂等性:相同输入应产生相同输出,避免随机性
- 增量生成:只重新生成有变更的部分
- 失败安全:生成失败时不影响现有报告
- 版本管理:生成的 PPT 纳入版本控制
成本控制
- 设置 API 调用预算上限
- 避免不必要的触发(只在数据变更时生成)
- 缓存生成结果,相同输入不重复生成
常见问题
CI/CD 中的生成时间会不会太长?
10-20 页的演示文稿生成时间约 30-60 秒,完全在 CI/CD 可接受范围内。如果页面数超过 50 页,建议拆分为多个并行的生成任务。
如何处理 API 限流?
在管线中加入重试机制和速率限制。OmyPPT SDK 内置了自动重试,你也可以在 CI/CD 层面通过 retry 步骤实现。
安全性怎么保障?
API Key 存储在 CI/CD 的加密密钥管理中(GitHub Secrets / Jenkins Credentials),不会出现在代码或日志中。
写在最后
PPT 不应该是手动更新的文件,而应该是自动生成的输出。将 PPT 生成集成到 CI/CD 管线中,让你的演示文稿永远是最新的——数据更新,PPT 自动更新。
开始构建你的 PPT 持续生成管线。获取 API Key。
