1. 什么是 python-pptx? #
- python-pptx 是 Python 中常用的 PowerPoint 读写库(当前主流版本 1.0.x),专门处理
.pptx 格式。
- 通过代码创建、读取、修改 PPT,无需安装 Microsoft PowerPoint。
- 典型场景:批量生成周报/报告、按模板填充数据、把分析结果自动转成幻灯片。
- 只支持
.pptx(Office 2007+),不支持旧版 .ppt。
- 核心公式:Presentation → Slide → Shape → 保存。
2. 核心概念 #
| 对象 |
含义 |
常用操作 |
| Presentation |
整个 PPT 文件 |
Presentation()、save() |
| Slide |
一张幻灯片 |
slides.add_slide(layout) |
| Layout |
幻灯片版式 |
slide_layouts[0] 标题页、[1] 标题+内容 |
| Shape |
幻灯片上的元素 |
标题、文本框、图片、表格 |
- 占位符(Placeholder):版式预留的位置,如
slide.shapes.title、slide.placeholders[1]。
- 布局编号因模板而异;常用:
0 封面、1 标题+正文、6 空白。
- 尺寸单位用
Inches()、Pt(),从 pptx.util 导入。
3. 环境准备 #
- 安装
python-pptx 即可;插入图片时系统通常已有 Pillow,也可一并安装。
- 推荐 Python 3.9 及以上版本。
3.1 安装 #
py -m pip install python-pptx pillow
- 下载慢:
py -m pip install python-pptx pillow -i https://pypi.tuna.tsinghua.edu.cn/simple
3.2 验证安装 #
from pptx import Presentation
doc = Presentation()
doc.add_slide(doc.slide_layouts[0])
doc.save("test.pptx")
print("已创建 test.pptx,安装成功")
4. 创建与读取 PPT #
Presentation() 创建空白 PPT;Presentation("a.pptx") 打开已有文件。
prs.slides.add_slide(layout) 按版式添加幻灯片。
slide.shapes.title.text 设置标题;slide.placeholders[1] 常用来填副标题或正文区。
- 读取时用
for slide in prs.slides 遍历,slide.shapes.title.text 取标题。
from pptx import Presentation
prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[0])
slide.shapes.title.text = "Python 自动化 PPT"
slide.placeholders[1].text = "基于 python-pptx"
slide2 = prs.slides.add_slide(prs.slide_layouts[1])
slide2.shapes.title.text = "项目概述"
slide2.placeholders[1].text = "第一条要点\n第二条要点"
prs.save("demo.pptx")
print(f"已保存 demo.pptx,共 {len(prs.slides)} 页")
prs2 = Presentation("demo.pptx")
for i, s in enumerate(prs2.slides, 1):
title = s.shapes.title.text if s.shapes.title else "(无标题)"
print(f"第 {i} 页:{title}")
5. 文本格式 #
- 版式
1 的正文区:slide.placeholders[1].text_frame 操作多段文字。
- 自定义文本框:
slide.shapes.add_textbox(left, top, width, height)。
- 字体大小用
Pt(),颜色用 RGBColor(r, g, b),对齐用 PP_ALIGN.CENTER 等。
- 项目符号:给段落设
level(0 一级,1 二级)。
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.enum.text import PP_ALIGN
from pptx.dml.color import RGBColor
prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[6])
box = slide.shapes.add_textbox(Inches(1), Inches(1), Inches(8), Inches(3))
tf = box.text_frame
p1 = tf.paragraphs[0]
p1.text = "报告标题"
p1.alignment = PP_ALIGN.CENTER
p1.runs[0].font.size = Pt(28)
p1.runs[0].font.bold = True
p1.runs[0].font.color.rgb = RGBColor(0, 102, 204)
p2 = tf.add_paragraph()
p2.text = "正文内容"
p2.level = 0
p3 = tf.add_paragraph()
p3.text = "二级要点"
p3.level = 1
prs.save("text_format.pptx")
print("已保存 text_format.pptx")
6. 插入图片 #
slide.shapes.add_picture(路径, left, top, width=...) 插入本地图片。
- 只支持本地路径,网络图片需先下载。
- 只设
width 时高度按比例缩放;路径不存在会报错,插入前用 os.path.exists 检查。
import os
from pptx import Presentation
from pptx.util import Inches
prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[6])
img_path = "logo.png"
if os.path.exists(img_path):
slide.shapes.add_picture(img_path, Inches(1), Inches(1), width=Inches(4))
else:
slide.shapes.add_textbox(Inches(1), Inches(1), Inches(4), Inches(1)).text = "请放置 logo.png"
prs.save("image.pptx")
print("已保存 image.pptx")
7. 表格 #
slide.shapes.add_table(rows, cols, left, top, width, height) 创建表格。
table.cell(row, col).text = "值" 写入单元格(索引从 0 开始)。
- 复杂样式(表头配色等)可以写,但日常批量报告填数据即可。
from pptx import Presentation
from pptx.util import Inches
rows = [
["产品", "Q1", "Q2", "Q3"],
["A", "120", "150", "180"],
["B", "90", "110", "140"],
]
prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[6])
table_shape = slide.shapes.add_table(
len(rows), len(rows[0]), Inches(0.5), Inches(1.5), Inches(9), Inches(3)
)
table = table_shape.table
for r, row in enumerate(rows):
for c, val in enumerate(row):
table.cell(r, c).text = val
prs.save("table.pptx")
print("已保存 table.pptx")
8. 实战:批量生成报告 #
- 项目中最常见的模式:循环数据 → 每份数据生成一个 PPT 或追加幻灯片。
- 复杂图表建议用 matplotlib 生成图片再插入,比原生 Chart API 更灵活。
- python-pptx 不支持删除幻灯片;要删减页面需重新组装新 Presentation。
from pptx import Presentation
def build_report(title: str, bullets: list[str], table_rows: list[list], output: str):
"""根据数据生成含封面、摘要、表格的报告 PPT。"""
prs = Presentation()
s0 = prs.slides.add_slide(prs.slide_layouts[0])
s0.shapes.title.text = title
s0.placeholders[1].text = "自动生成"
s1 = prs.slides.add_slide(prs.slide_layouts[1])
s1.shapes.title.text = "摘要"
tf = s1.placeholders[1].text_frame
tf.text = bullets[0]
for b in bullets[1:]:
tf.add_paragraph().text = b
from pptx.util import Inches
s2 = prs.slides.add_slide(prs.slide_layouts[6])
t = s2.shapes.add_table(
len(table_rows), len(table_rows[0]),
Inches(0.5), Inches(1.5), Inches(9), Inches(3)
).table
for r, row in enumerate(table_rows):
for c, val in enumerate(row):
t.cell(r, c).text = str(val)
prs.save(output)
reports = [
{
"title": "华东区 Q1 报告",
"bullets": ["营收增长 12%", "新客户 320 家"],
"table": [["指标", "数值"], ["营收", "1200万"], ["客户", "320"]],
"file": "report_east.pptx",
},
{
"title": "华南区 Q1 报告",
"bullets": ["营收增长 8%", "新客户 210 家"],
"table": [["指标", "数值"], ["营收", "980万"], ["客户", "210"]],
"file": "report_south.pptx",
},
]
for r in reports:
build_report(r["title"], r["bullets"], r["table"], r["file"])
print("已生成:", r["file"])
9. 常见问题 #
9.1 无法删除幻灯片 #
- python-pptx 没有删除单页的 API。
- 需要删减时,新建 Presentation,只 add 需要的页。
9.2 布局编号对不上 #
- 不同模板的
slide_layouts 编号可能不同。
- 可先
print(layout.name) 确认;不确定时用空白布局(6)手动排版。
9.3 图表与复杂排版 #
- 内置 Chart API 功能有限,复杂图表用 matplotlib 出图再
add_picture。
- 精细动画、母版编辑等高级功能 python-pptx 不支持,需手工在 PowerPoint 里做。
9.4 字体与路径 #
- 指定字体需在系统中已安装,否则回退为默认字体。
- 路径推荐
pathlib.Path 或 os.path.join,避免硬编码反斜杠。
10. API 速查 #
- 下面汇总 python-pptx 1.0.x 日常最常用的写法。
| 操作 |
写法 |
| 创建 PPT |
prs = Presentation() |
| 打开 PPT |
prs = Presentation("a.pptx") |
| 添加幻灯片 |
prs.slides.add_slide(prs.slide_layouts[1]) |
| 设标题 |
slide.shapes.title.text = "标题" |
| 设正文占位符 |
slide.placeholders[1].text = "内容" |
| 添加文本框 |
slide.shapes.add_textbox(Inches(1), Inches(1), Inches(8), Inches(2)) |
| 插入图片 |
slide.shapes.add_picture("a.png", Inches(1), Inches(1), width=Inches(4)) |
| 添加表格 |
slide.shapes.add_table(rows, cols, ...) |
| 写单元格 |
table.cell(0, 0).text = "值" |
| 保存 |
prs.save("out.pptx") |
| 字体大小 |
run.font.size = Pt(24) |
| 字体颜色 |
run.font.color.rgb = RGBColor(255, 0, 0) |