news 2026/9/4 19:36:27

Python办公自动化实战:批量处理Excel、Word与PPT

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python办公自动化实战:批量处理Excel、Word与PPT

你是不是也遇到过这样的场景:月底要汇总几十张 Excel 报表,复制粘贴到手指发酸;领导临时让你把一份 Word 通知批量改成 20 个不同部门;又或者每周都要做一份格式一模一样的 PPT 周报,光是调字体和占位符就耗掉半天。

其实这些活,Python 都能做,而且做起来很快。我之前也是从“只会打开 Excel 手动操作”的阶段过来的,直到有一天被一堆重复性的文档整理工作压到崩溃,才开始认真用 Python 写脚本。今天这篇文章,我把自己实际用过的 Python 操作 Excel、Word、PPT 的思路整理成了一套完整教程,不是只贴接口文档,而是带你从背景概念、环境搭建、实战代码到最终运行效果完整走一遍。

本文适合下面几类读者:

  • 工作里经常和 Office 三件套打交道,想提升效率的职场人;
  • 刚刚学完 Python 基础,想知道一行行代码到底能解决什么实际问题的同学;
  • 被 Excel 函数、Word 宏、PPT 模板折磨过,想换一种更可控的自动化方案的开发者。

读完之后,你可以掌握:用 Python 实现对 Excel 的批量读写与统计、对 Word 文档的批量生成与内容替换、对 PPT 的自动化创建与版式修改,并学会封装脚本的方法。


1. Python 办公自动化到底能帮你做什么

先不急着写代码,我们来理清一个概念。

所谓的“Python 办公自动化”,指的是使用 Python 作为控制工具,操作常见的办公文件格式,比如 Excel 工作簿、Word 文档、PPT 演示文稿,把原来需要在 Office 软件里手动完成的重复操作通过代码自动执行。它不是说让你用 Python 写一个 Office 软件,只是通过代码完成“读写内容、调整格式、批量生成、汇总计算”这一类文档处理动作。

1.1 办公自动化的常见应用场景

我身边比较常见的场景大致有下面几类:

首先是批量格式整理。比如几十个 Excel 表都设置了不同字体、列宽、边框,而汇总方要求统一格式。这种情况下,手动打开每一份文件再调整,不仅慢还容易漏。用 Python 遍历文件,统一设置样式,几秒就能完成。

其次是数据汇总与统计。这也是最刚需的场景。各分店发来销售明细表,需要合并到一张总表里,并且按产品类别或门店名称汇总求和,Python 里的 pandas 处理这种二维表是最顺手的。

然后是批量生成文档。比如给不同客户生成不同合同模板、给不同员工生成录用通知书。这类工作往往是同一个 Word 模板,只有称呼、项目名称、金额、日期等少数字段不一样。用 Python 读取外部数据源,然后循环替换模板里的占位符,就可以批量输出 Word 文件。

还有数据看板与汇报材料生成。从 Excel 读取统计数据后,直接在 PPT 中生成可视化图表页面,或者把关键数据填入固定版式的 PPT 模板页,省掉手工复制数据、重新做图表的时间。

1.2 常用工具库梳理

Python 能处理 Office 文件,依赖的是社区提供的大量第三方库。不同文件类型有对应的核心库:

文件类型主要操作库能做什么
Excelopenpyxl / pandas / xlsxwriter读写 xlsx、批量汇总、格式设置、图表生成,xlsxwriter 适合大量写操作
Wordpython-docx读取 docx 文本、创建段落、设置字体、插入图片和表格,还可以处理模板占位符替换
PPTpython-pptx打开已有 pptx 模板、添加幻灯片、写入文本、设置版式、插入图片和图表
CSVcsv / pandas读写逗号分隔或自定义分隔符的文本表格数据
PDFpdfplumber / PyPDF2(新版推荐 pypdf)读取 PDF 文字、合并拆分 PDF、提取表格

注意一个版本问题:老代码里常见的xlrd在新版本中已经不再支持 xlsx 格式,只支持 .xls,所以现在读取 .xlsx 建议使用openpyxlpandas格式读写由后端解析引擎完成。

1.3 没有基础能学会吗

我能理解有些读者看到“编程”两个字就头大,但实际上,办公自动化脚本的门槛并不高。你不需要啃很深的数据结构和算法,只需要掌握最基本的语法:变量、列表、字典、for 循环、if 条件、函数定义,然后学会把 Office 操作的 API 按照官网示例“抄下来改一改”。

我把这篇文章写成了一套“照着做”的教程。遇到不懂的地方,你动手跑一遍,多看打印输出,慢慢就能建立起“文件对象—读取方式—写入操作”的完整心智模型。


2. 环境准备与基础配置

工欲善其事,必先利其器。在写自动化脚本之前,先要把 Python 环境和依赖库准备到位。

2.1 安装 Python 解释器

如果你的电脑里还没有 Python,可以先到 Python 官网下载安装包。如果你的操作系统在 Windows 上用,安装时记得勾选最下方的“Add Python to PATH”,这样在命令行中直接输入python才能找到解释器。

安装完成后打开命令行(Windows 下是 CMD 或 PowerShell,macOS / Linux 下是终端),输入下面命令验证:

python --version

如果输出类似Python 3.13.x的信息,说明安装成功。

有些朋友电脑上安装过 Anaconda,那里面自带了 Python 和常用的数据分析库,也可以用。

2.2 安装第三方依赖库

本文的示例需要用到这三个核心库:

  • openpyxl:处理 Excel .xlsx 文件;
  • python-docx:处理 Word .docx 文档;
  • python-pptx:处理 PowerPoint .pptx 文件。

使用 pip 安装,这里建议使用国内镜像加速下载:

pip install openpyxl python-docx python-pptx -i https://pypi.tuna.tsinghua.edu.cn/simple

如果想做复杂的数据统计,还可以再安装 pandas:

pip install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple

如果你的项目要通过 pip 管理依赖,也可以把库名记录到 requirements.txt 中:

openpyxl==3.1.5 python-docx==1.1.2 python-pptx==1.0.2 pandas==2.2.3

然后统一执行:

pip install -r requirements.txt

这里的版本号只是举例,实际安装时请以你自己环境中的最新兼容版本为准。依赖版本更新较快,安装时报错时优先检查版本兼容性和网络源是否可用。

2.3 建议使用的开发环境

命令行直接写小脚本没有问题,但如果你要调试批量处理代码,个人还是推荐用一个开发工具,这样能看到变量的实时变化,比如:

  • VS Code + Python 插件;
  • PyCharm Community Edition;
  • Jupyter Notebook(适合练习语法和逐步分析数据表内容)。

我平时最常用的是 VS Code,轻量且免费。创建项目后,建议保持这样的目录结构:

office_auto/ ├── data/ # 存放原始 Excel、Word、PPT 文件 ├── output/ # 存放脚本生成的结果文件 ├── templates/ # 存放模板文件 ├── scripts/ # 存放 Python 脚本 └── requirements.txt # 依赖列表

统一把输入文件和输出路径分开管理,后面写脚本时不容易因路径问题混淆。


3. Python 操作 Excel:从打开工作簿到批量汇总统计

Excel 是办公自动化里应用最广的领域。接下来我们先用 openpyxl 从最基础的操作讲起,然后通过一个多文件汇总的案例,把日常办公的真实场景体现出来。

3.1 openpyxl 基础概念

openpyxl 操作 Excel 时分三个层次:

  • Workbook:工作簿,对应一个 .xlsx 文件;
  • Worksheet:工作表,也就是 Excel 底部一个个 Sheet 标签页;
  • Cell:单元格,由行号和列号决定,比如 A1、C3。

常见的打开方式有两种。一种是读取现有文件:

from openpyxl import load_workbook wb = load_workbook("data/sales.xlsx") ws = wb.active # 获取当前活动工作表 print(ws["A1"].value) # 读取 A1 单元格内容

如果打开时源 Excel 带格式,并且你没有修改格式的需求,可以加data_only=True读取公式计算后的值:

wb = load_workbook("data/sales.xlsx", data_only=True)

另一种方式是新创建一个文件:

from openpyxl import Workbook wb = Workbook() ws = wb.active ws.title = "汇总表" ws["A1"] = "门店名称" ws["A2"] = "华东一店" wb.save("output/新建文件.xlsx")

这里的save()代表保存到磁盘,如果目标文件已存在,会被覆盖。写代码时注意,对已有的文件做修改后也必须执行save(),否则不会生效。

3.2 需求描述:多 Excel 合并统计

为了贴近实际场景,我这里设计一个案例:

假设你是一家连锁零售公司的运营助理,公司在华东区有 5 家门店。每个月,每家门店会发来一份销售明细表,列结构统一为:门店名称、商品类别、销售额、销售日期。你的任务是:把这 5 张表合并到一张总表,并统计每个商品类别的总销售额,把结果写入一个新的 Excel 文件。

为了演示方便,我们先写一个脚本自动生成 5 份模拟数据,保存在data/sales/目录下:

# 文件路径:scripts/gen_sales_data.py import os from openpyxl import Workbook os.makedirs("../data/sales", exist_ok=True) stores = ["华东一店", "华东二店", "华东三店", "华东四店", "华东五店"] categories = ["手机", "电脑", "家电", "配件"] samples = [ ["华东一店", "手机", 35000, "2025-12-01"], ["华东一店", "电脑", 78000, "2025-12-02"], ["华东一店", "家电", 21000, "2025-12-03"], ["华东二店", "手机", 22000, "2025-12-01"], ["华东二店", "配件", 8500, "2025-12-02"], ["华东三店", "电脑", 56000, "2025-12-01"], ["华东三店", "家电", 12000, "2025-12-02"], ["华东四店", "手机", 18200, "2025-12-01"], ["华东四店", "电脑", 43000, "2025-12-02"], ["华东五店", "家电", 9900, "2025-12-01"], ] for idx, store in enumerate(stores, start=1): wb = Workbook() ws = wb.active ws.title = "销售明细" ws.append(["门店名称", "商品类别", "销售额", "销售日期"]) for row in samples: if row[0] == store: ws.append(row) elif idx == 3 and row[0] == "华东三店": # 给其中一份文件加几行示例数据 pass # 为了让示例文件空一点,这里直接每个文件写 5 行统一数据,最后保留完整测试数据 # 重新按门店循环写入 ws.delete_rows(1, ws.max_row) header = ["门店名称", "商品类别", "销售额", "销售日期"] ws.append(header) for row in samples: ws.append(row) wb.save(f"../data/sales/{store}_销售明细.xlsx") print("模拟数据生成完成")

上面的脚本逻辑其实有一点重复:先写入再删除,只是为了展示delete_rows的使用方式。如果你自己写生成脚本,可以更简洁:

for store in stores: wb = Workbook() ws = wb.active ws.append(["门店名称", "商品类别", "销售额", "销售日期"]) for row in samples: ws.append(row) wb.save(f"../data/sales/{store}_销售明细.xlsx")

无论如何,最终我们应该得到 5 个结构一致的数据文件。这非常重要——只有当输入文件的列结构一致时,合并脚本才不需要做额外字段映射。

3.3 编写 Excel 汇总脚本

真正干活的脚本,可以拆成三步:

  1. 遍历目标目录下所有 .xlsx 文件;
  2. 用 openpyxl 逐个读取 Sheet 中从第 2 行开始的数据;
  3. 把数据添加到总表,然后使用字典按“商品类别”累加销售额。

完整代码如下:

# 文件路径:scripts/merge_sales.py import os import glob from openpyxl import load_workbook, Workbook SALES_DIR = "../data/sales" OUTPUT_DIR = "../output" def get_all_sales_files(): pattern = os.path.join(SALES_DIR, "*.xlsx") return glob.glob(pattern) def merge_sales(): os.makedirs(OUTPUT_DIR, exist_ok=True) all_rows = [] category_sum = {} files = get_all_sales_files() for file_path in files: wb = load_workbook(file_path, data_only=True) ws = wb.active # 从第二行开始读取,跳过表头 for row in ws.iter_rows(min_row=2, values_only=True): store_name, category, amount, date_text = row if category is None: continue all_rows.append([store_name, category, amount, date_text]) # 统计商品类别销售额 category_sum[category] = category_sum.get(category, 0) + amount wb.close() # 写入合并明细 wb_out = Workbook() ws_detail = wb_out.active ws_detail.title = "合并明细" ws_detail.append(["门店名称", "商品类别", "销售额", "销售日期"]) for row in all_rows: ws_detail.append(row) # 写入统计结果 ws_summary = wb_out.create_sheet("分类统计") ws_summary.append(["商品类别", "总销售额"]) for category, total in category_sum.items(): ws_summary.append([category, total]) output_path = os.path.join(OUTPUT_DIR, "汇总统计.xlsx") wb_out.save(output_path) print(f"合并完成,共读取 {len(files)} 个文件,总行数 {len(all_rows)} 行") print(f"结果已保存到:{output_path}") if __name__ == "__main__": merge_sales()

代码里用到了iter_rows(min_row=2, values_only=True),这里的values_only=True会直接返回每个单元格的值,而不返回单元格对象,遍历更高效。

读取时还有一个细节值得注意:data_only=True只适用于文件里的公式已经被 Excel 计算过并缓存了结果的情况。如果源文件是代码生成的,且单元格是直接写入的数值,那无论是否加data_only都能读到数值。

执行脚本:

cd scripts python merge_sales.py

运行预期:

合并完成,共读取 5 个文件,总行数 50 行 结果已保存到:../output/汇总统计.xlsx

打开生成的汇总文件,你会看到两个工作表:“合并明细”里是所有门店数据按顺序追加的完整表,“分类统计”里已经有按手机、电脑、家电、配件分组求和后的结果了。

3.4 Excel 自动化进阶提示

上面只是入门级汇总,实际工作中的 Excel 自动化还会涉及很多场景,常用的处理方向大概是下面这几个:

  • 单元格格式设置:字体、颜色、对齐方式、边框,可以使用openpyxl.styles.Font / Alignment / Border
  • 合并单元格与冻结窗格ws.merge_cells("A1:C1")ws.freeze_panes = "A2"
  • 条件判断与公式写入:可以直接把 Excel 公式字符串赋给单元格,比如ws["C2"] = "=A2+B2"
  • 图表插入openpyxl.chart.BarChart可以把分类汇总结果直接做成柱状图。
  • 超大批量文件处理:如果文件非常多,建议用 pandas 批量读取并拼接,内存管理比手工循环更高效。

如果你连一个 Excel 都不需要保留格式,只做数据提取,pandas 一行读取就够:

import pandas as pd df = pd.read_excel("../data/sales/华东一店_销售明细.xlsx") print(df.head())

然后所有分组聚合逻辑都可以基于 DataFrame 完成:

summary = df.groupby("商品类别")["销售额"].sum().reset_index() summary.to_excel("../output/pandas_summary.xlsx", index=False)

具体选 openpyxl 还是 pandas,取决于你的目标:如果重点是保留原格式修改和样式设置,选 openpyxl;如果重点是数据整理和统计分析,pandas 更顺手。


4. Python 操作 Word:从模板占位符到批量生成合同

Word 自动化的思路和 Excel 很不一样。Excel 核心是数据表处理,Word 核心是段落与排版。python-docx 是一个操作 .docx 文档的库,它不能运行 Word VBA,也不能操作 .doc(老格式),但它能把文本写入段落、设置样式、插入表格和图片。

4.1 先理解 python-docx 文档模型

python-docx 的模型可以这样理解:

  • Document:代表一个 Word 文档,对应 .docx 文件;
  • Paragraph:段落对象,Word 中回车形成一段;
  • Run:段内具有相同样式的一段连续文本,同一个段落可以由多个 Run 组成;
  • Table:表格对象,类似 Excel 的工作表,通过行列访问单元格。

一个最小示例,创建一个文档并添加标题和段落:

from docx import Document doc = Document() doc.add_heading("部门会议通知", level=1) doc.add_paragraph("请各部门负责人准时参加。") doc.save("../output/通知示例.docx")

4.2 Word 文档中替换文本时要注意 Run 问题

在实践中,最容易让新手困惑的地方在于:docx 库不能直接像字符串替换那样把你想要的关键词精确替换,因为 Word 的正文会按格式拆分成多个 Run,例如字体不同、加粗位置不同都可能导致文本被拆开。如果你直接遍历paragraph.text判断包含关系,再把整个段落文本重新赋值,可能造成样式丢失。

一种可靠的做法是:读取某个文件前,先把模板中需要替换的文本用相同的字符样式书写,并使用占位符,比如{公司名称}{项目金额}{生效日期}。然后遍历段落中的runs,把包含占位符的 Run 做局部替换。

下面是一个更稳定的替换方案:

def replace_placeholder_in_paragraph(paragraph, old_text, new_text): if old_text not in paragraph.text: return False for run in paragraph.runs: if old_text in run.text: run.text = run.text.replace(old_text, new_text) return True # 如果占位符被拆到多个 run 中,说明模板制作需要优化 return False

这个方案能处理绝大多数情况,但前提是:模板制作用的是可以整体匹配的占位符,且没有把一个占位符拆散成多个 Run。如果遇到实在拆散的模板,更稳妥的办法是重构模板,把占位符所在的段落作为一个整体重新赋值。

4.3 需求描述:批量生成录用通知

假设你需要给 10 位新员工发送不同内容的录用通知书。每个人的姓名、岗位、薪资、入职日期不同,其余内容相同。

准备一个 Word 模板templates/offer_template.docx,内容如下:

录用通知书 尊敬的 {姓名} 先生/女士: 恭喜您通过面试,您已被我司录用。 具体信息如下: 岗位:{岗位} 试用期薪资:{薪资} 元/月 入职日期:{入职日期} 请您携带相关材料于入职当天上午 9:00 到公司办理手续。

然后编写以下脚本:

# 文件路径:scripts/batch_offer.py import os from docx import Document TEMPLATE_PATH = "../templates/offer_template.docx" OUTPUT_DIR = "../output/offers" employees = [ {"姓名": "张伟", "岗位": "Python 开发工程师", "薪资": "15000", "入职日期": "2025-03-03"}, {"姓名": "李娜", "岗位": "测试工程师", "薪资": "12000", "入职日期": "2025-03-05"}, {"姓名": "王强", "岗位": "产品经理", "薪资": "18000", "入职日期": "2025-03-10"}, {"姓名": "赵敏", "岗位": "运维工程师", "薪资": "13500", "入职日期": "2025-03-12"}, {"姓名": "陈晨", "岗位": "前端开发工程师", "薪资": "14000", "入职日期": "2025-03-15"}, ] def replace_placeholder(paragraph, old_text, new_text): for run in paragraph.runs: if old_text in run.text: run.text = run.text.replace(old_text, new_text) def generate_offer(employee_info): os.makedirs(OUTPUT_DIR, exist_ok=True) doc = Document(TEMPLATE_PATH) for paragraph in doc.paragraphs: replacements = { "{姓名}": employee_info["姓名"], "{岗位}": employee_info["岗位"], "{薪资}": employee_info["薪资"], "{入职日期}": employee_info["入职日期"], } for key, value in replacements.items(): replace_placeholder(paragraph, key, value) output_path = os.path.join(OUTPUT_DIR, f"{employee_info['姓名']}_录用通知.docx") doc.save(output_path) print(f"已生成:{output_path}") if __name__ == "__main__": for emp in employees: generate_offer(emp)

脚本流程很清楚:加载模板文档,遍历所有段落在每个段落内完成四组占位符替换,最后保存新文件。对于 10 个员工,只要循环 10 次即可。

运行:

python batch_offer.py

output/offers/目录可以看到已经生成 5 份录用通知。用 Word 打开查看,正文中的占位符都被替换成了员工的实际信息。

这里值得提醒:模板文件的命名、存储路径以及文本里的花括号都需要保持统一,否则脚本可能找不到需要替换的文本。处理前建议先备份原始模板文件。

4.4 Word 中操作表格

Office Word 实际工作中经常还要操作表格。在 python-docx 中,可以通过doc.tables访问文档中的所有表格:

from docx import Document doc = Document("../output/offers/张伟_录用通知.docx") for table in doc.tables: for row in table.rows: for cell in row.cells: print(cell.text) cell.text = cell.text.replace("旧值", "新值") doc.save("替换表格内容.docx")

写新的表格同样也很方便:

doc = Document() table = doc.add_table(rows=2, cols=3) table.style = "Table Grid" # 加上表格线条 table.cell(0, 0).text = "姓名" table.cell(0, 1).text = "岗位" table.cell(0, 2).text = "入职日期" doc.save("../output/新表格.docx")

5. Python 操作 PPT:从空白演示文稿到页面批量生成

PPT 自动化用到的工具是 python-pptx。它的编程模型与 Word 类似,但也有自己的词汇:Presentation 对应一个 .pptx 文件,Slide 对应一页幻灯片,Shape 是页面上的形状,Placeholder 是占位符,Layout 是母版提供的版式。

5.1 python-pptx 的基本读取与写入

打开已有 PPT 模板并读取每页文本信息:

from pptx import Presentation prs = Presentation("../templates/weekly_report_template.pptx") for slide in prs.slides: print("---- 当前页 ----") for shape in slide.shapes: if shape.has_text_frame: for paragraph in shape.text_frame.paragraphs: text = "".join(run.text for run in paragraph.runs) if text.strip(): print(text)

创建一页完全空白的演示文稿,并写入标题与内容:

from pptx import Presentation from pptx.util import Inches, Pt from pptx.dml.color import RGBColor prs = Presentation() slide = prs.slides.add_slide(prs.slide_layouts[1]) # 标题和内容版式 slide.shapes.title.text = "Python 办公自动化实战" title_shape = slide.shapes.title body_shape = slide.placeholders[1] body_shape.text = "Excel / Word / PPT 三合一" prs.save("../output/pptx_demo.pptx")

看上去是不是很简单?真正复杂的点在于排版位置、字号、颜色和对齐方式,这些都涉及坐标和样式的设置。

5.2 需求描述:自动生成周报 PPT

假设有个产品运营岗位,每周要按同样的逻辑生成一份周报 PPT,包含 3 页内容:

  1. 封面页:标题“XX 产品运营周报”,副标题为当前日期;
  2. 数据页:本周新增用户数、活跃用户数、转化率三个关键指标;
  3. 图表页:新增用户数近 7 日趋势柱状图。

python-pptx 自带的图表插入接口可以很好地满足第三点;图表本身会嵌入 PPT,编辑时和手动插入的图表行为一致。

5.3 批量生成周报完整脚本

先制作一个周报数据 JSON 或 Python 字典:

report_data = { "title": "知识星球产品运营周报", "report_date": "第 10 周(2025-03-03 至 2025-03-09)", "metrics": [ {"name": "新增用户", "value": 22130}, {"name": "活跃用户", "value": 45678}, {"name": "付费转化率", "value": "8.6%"}, ], "trend_dates": ["周一", "周二", "周三", "周四", "周五", "周六", "周日"], "trend_values": [2500, 3200, 2900, 4100, 3800, 4600, 5300], }

完整脚本:

# 文件路径:scripts/build_ppt_report.py from pptx import Presentation from pptx.util import Inches, Pt from pptx.chart.data import CategoryChartData from pptx.enum.chart import XL_CHART_TYPE from pptx.dml.color import RGBColor report_data = { "title": "知识星球产品运营周报", "report_date": "第 10 周(2025-03-03 至 2025-03-09)", "metrics": [ {"name": "新增用户", "value": 22130}, {"name": "活跃用户", "value": 45678}, {"name": "付费转化率", "value": "8.6%"}, ], "trend_dates": ["周一", "周二", "周三", "周四", "周五", "周六", "周日"], "trend_values": [2500, 3200, 2900, 4100, 3800, 4600, 5300], } def add_report_cover(prs): slide = prs.slides.add_slide(prs.slide_layouts[0]) # 标题版式 slide.shapes.title.text = report_data["title"] slide.placeholders[1].text = report_data["report_date"] def add_metrics_slide(prs): slide = prs.slides.add_slide(prs.slide_layouts[1]) slide.shapes.title.text = "核心指标" body = slide.placeholders[1] text_frame = body.text_frame text_frame.clear() for idx, metric in enumerate(report_data["metrics"]): p = text_frame.paragraphs[0] if idx == 0 else text_frame.add_paragraph() p.text = f'{metric["name"]}:{metric["value"]}' p.font.size = Pt(28) p.font.color.rgb = RGBColor(0x2F, 0x54, 0x96) def add_trend_chart_slide(prs): slide = prs.slides.add_slide(prs.slide_layouts[5]) # 仅标题版式 slide.shapes.title.text = "近 7 日新增用户趋势" chart_data = CategoryChartData() chart_data.categories = report_data["trend_dates"] chart_data.add_series("新增用户", report_data["trend_values"]) graphic_frame = slide.shapes.add_chart( XL_CHART_TYPE.COLUMN_CLUSTERED, Inches(1), Inches(2), Inches(8), Inches(5), chart_data ) def main(): prs = Presentation() add_report_cover(prs) add_metrics_slide(prs) add_trend_chart_slide(prs) output_path = "../output/运营周报.pptx" prs.save(output_path) print(f"PPT 周报已生成:{output_path}") if __name__ == "__main__": main()

运行后生成的 PPT 页面有三张。第二页的核心指标虽然能显示数据,但目前是普通文本,如果你想要更醒目的数字卡片效果,你可以使用文本框+形状填充来绘制卡片。

5.4 python-pptx 效果优化点

如果你不只是做一个“能带文字的 PPT”,而是想做得更像人肉手工做的,后面几个方向值得搞一搞:

  • 使用现成模板,不新建空白 Presentation,而是Presentation("../templates/公司模板.pptx")
  • 设置字体、颜色、行距和对齐:paragraph.alignment = PP_ALIGN.CENTER
  • 不直接操作占位符 index,而是通过slide_layout.placeholders确认 placeholder 名称;
  • 利用add_picture()插入从 Excel 生成的图表或图片,比如把 pandas 生成的 matplotlib 统计图嵌入到 PPT 页;
  • 批量生成时先遍历模板页数,确认版式里 title 占位符存在,避免索引越界。

6. 综合实战:Excel 数据统计后导入 Word 报告并输出 PPT

有时候 Excel、Word、PPT 不能完全割裂开。工作中更常见的是一条链式的处理流程:数据在 Excel 里 → 整理成表格或图表 → 放进 Word 汇总报告 → 再提炼几页 PPT。

下面这个综合小项目,把 Excel 的统计结果写入一个 Word 报告文档,同时生成一页 PPT 概要页。这也是很多自动化场景的通用模板。

6.1 需求说明

output/汇总统计.xlsx里读取“分类统计”工作表,把分类名称和总销售额按表格形式写到 Word 报告里;然后把销售额最高的分类名称和数值写到 PPT 封面页下面的正文里。

6.2 核心代码:跨文件自动化串联

# 文件路径:scripts/pipeline_report.py import os from openpyxl import load_workbook from docx import Document from pptx import Presentation from pptx.util import Pt DATA_FILE = "../output/汇总统计.xlsx" WORD_OUTPUT = "../output/销售分析报告.docx" PPT_OUTPUT = "../output/销售概要.pptx" def read_summary(): wb = load_workbook(DATA_FILE, data_only=True) ws = wb["分类统计"] rows = [] for row in ws.iter_rows(min_row=2, values_only=True): if row[0]: rows.append(row) wb.close() return rows def write_word_report(summary_rows): doc = Document() doc.add_heading("月度销售分析报告", level=1) table = doc.add_table(rows=1, cols=2) table.style = "Table Grid" hdr = table.rows[0].cells hdr[0].text = "商品类别" hdr[1].text = "总销售额" for category, total in summary_rows: row_cells = table.add_row().cells row_cells[0].text = str(category) row_cells[1].text = str(total) doc.add_paragraph("") doc.add_paragraph("说明:以上数据来自各门店上报的销售明细合并结果。") doc.save(WORD_OUTPUT) print(f"Word 报告已生成:{WORD_OUTPUT}") def write_ppt_summary(summary_rows): top_category, top_total = max(summary_rows, key=lambda x: x[1] or 0) prs = Presentation() slide = prs.slides.add_slide(prs.slide_layouts[0]) slide.shapes.title.text = "销售简报" sub = slide.placeholders[1] sub.text = f"本月销售额最高的类别:{top_category},总销售额 {top_total} 元" prs.save(PPT_OUTPUT) print(f"PPT 概要已生成:{PPT_OUTPUT}") if __name__ == "__main__": rows = read_summary() write_word_report(rows) write_ppt_summary(rows)

执行脚本后,Excel → Word → PPT 的三步骤自动完成,中间不需要任何人工操作。

这个例子看起来简单,但它代表了一种非常实用的思维方式:先梳理业务流程,确定数据从哪里来、结果要到哪里去,再把每一步拆成一个函数,最后用主函数串联。真实的办公自动化项目基本都遵循这个套路。


7. 常见报错与问题排查

这部分是我在实际使用 Python 办公自动化过程中反复遇到的问题,整理成一个速查表,方便你在跑代码时快速定位。

问题现象常见原因解决思路
ModuleNotFoundError: No module named 'openpyxl'没有安装依赖库或装到了别的 Python 环境执行pip install openpyxl,用python -m pip检查当前环境
读取 Excel 时发现读不到公式结果文件从未用 Excel 打开过,公式没有缓存结果使用data_only=True之前,先确认源文件确实有被 Excel 计算过一次;不可靠时改用公式计算逻辑
生成的 Word 文档占位符没有被替换文字被拆在多个 Run 中重新整理模板,修改段落的 runs 或直接逐 Run 替换
运行脚本后找不到输出文件脚本当前工作目录与代码里的相对路径不一致使用绝对路径,或先os.chdir()切换到项目根目录;也可以基于__file__拼接路径
openpyxl 无法读取 .xls 老文件openpyxl 只支持 .xlsx先把 .xls 转换为 .xlsx,或用 pandas + xlrd(xlrd 仅支持 .xls 新版本)
python-docx 创建的文档打不开保存路径不存在,或文件正在被 Word 占用先确保目录已创建;关闭已打开的 Word 再重新运行
pptx 出现 placeholder index 越界模板版式没有对应的占位符位置改用placeholder.idx遍历,或先检查版式占位符存在性
批量处理文件时内存占用过高大量读取 Excel 后没有及时关闭工作簿读取完及时执行wb.close(),或按文件分批处理
中文文件名乱码脚本文件本身不是 UTF-8 编码用支持 UTF-8 编码的编辑器保存脚本;路径中包含中文时避免硬编码

额外的排查建议:

  • 修改代码时保留最小复现文件,日志里多打印文件路径当前工作表名称,这样可以快速定位是路径问题还是内容问题。
  • 第一次处理正式数据前,先用一两份模拟数据跑通流程,再批量执行。涉及正式合同、财务报表时,尤其建议在测试目录验证。

8. 格式与样式设置:Python 办公自动化的“面子工程”

代码能写入文本和数值之后,很多朋友会遇到下一个需求:“我想要生成的文件看起来像人做的,而不是像纯文本倒进去的。”

这类格式设置,在三个库里分别对应不同的对象:

8.1 Excel 单元格格式美化

openpyxl 中,设置字体、背景色和对齐方式常用到 styles 子模块:

from openpyxl.styles import Font, PatternFill, Alignment, Border, Side wb = Workbook() ws = wb.active # 标题行样式 font_title = Font(name="微软雅黑", size=12, bold=True, color="FFFFFF") fill_title = PatternFill(start_color="2F5496", end_color="2F5496", fill_type="solid") alignment_center = Alignment(horizontal="center", vertical="center") ws["A1"] = "商品类别" ws["A1"].font = font_title ws["A1"].fill = fill_title ws["A1"].alignment = alignment_center # 设置列宽 ws.column_dimensions["A"].width = 20 # 设置行高 ws.row_dimensions[1].height = 28 # 给边框 thin_border = Border( left=Side(style="thin"), right=Side(style="thin"), top=Side(style="thin"), bottom=Side(style="thin"), ) ws["A1"].border = thin_border

8.2 Word 文本样式

python-docx 中可以使用doc.stylesparagraph.style或直接运行字体设置:

from docx.shared import Pt, RGBColor doc = Document() p = doc.add_paragraph("这是一段红色加粗的示例文字。") run = p.runs[0] run.font.bold = True run.font.size = Pt(16) run.font.color.rgb = RGBColor(0xFF, 0x00, 0x00) run.font.name = "微软雅黑"

8.3 PPT 文本框样式

PPT 在生成幻灯片时,重点是掌握pt(磅)和Inches单位的换算使用。

from pptx.util import Inches, Pt from pptx.dml.color import RGBColor left = Inches(1) top = Inches(1.5) width = Inches(6) height = Inches(1) textbox = slide.shapes.add_textbox(left, top, width, height) tf = textbox.text_frame tf.text = "我是标题内容" p = tf.paragraphs[0] p.font.size = Pt(18) p.font.bold = True p.font.color.rgb = RGBColor(0x2F, 0x54, 0x96)

格式处理如果需求比较复杂,比如需要批量处理多个带样式文件的模板,建议把模板先人工做成标准样式,再由脚本对需要变化的字段做局部替换,这样比完全用代码从零设置格式稳定很多。


9. 工程化与扩展:如何提升办公自动化脚本的稳定性

做完一个真实业务之后,就有必要跳出“跟代码”的思维,想让自动化这套东西运到更稳、跑得时间更久,要有几个工程层面的调整。

9.1 用配置文件代替硬编码

我最早写脚本时,文件路径、替换文字等参数都直接写在代码里。这种脚本今天能用,明天换了路径就要改代码,一旦上线给同事用,就会变成“只有我能运行的程序”。

建议把路径和参数放到配置文件里,比如使用一个config.yaml

paths: data_dir: ./data/sales output_dir: ./output template_file: ./templates/offer_template.docx replace_fields: 公司名称: 示例科技有限公司 部门: 技术部

然后在脚本中读取配置文件:

import yaml def load_config(path="config.yaml"): with open(path, "r", encoding="utf-8") as f: return yaml.safe_load(f)

这样做的好处是:字段更新、目录变更都不需要修改代码逻辑。

9.2 日志输出与断点续跑

当文件数量达到几百上千时,脚本跑得再快也可能因为个别文件格式不合法而中断。这里有一个很实际的经验:

  • 单个文件处理先用try-except捕获异常,把失败文件名记录到日志;
  • 成功后把结果写到 “处理成功.txt”,失败写进 “失败清单.txt”;
  • 脚本运行结束后查看失败清单,再修问题重跑失败文件。

这样就不会因为遇到一个损坏文件而所有数据都要重来。

import logging logging.basicConfig( filename="../logs/auto.log", level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s", ) def process_one(file_path): try: # 业务处理逻辑 pass except Exception as exc: logging.error(f"处理失败:{file_path},原因:{exc}")

9.3 GUI 化或命令行化

如果脚本是给非技术人员使用的,可以考虑做一个简单的命令行交互或桌面小工具。用argparse可以在命令行接收参数:

import argparse parser = argparse.ArgumentParser(description="Excel 汇总工具") parser.add_argument("--data-dir", required=True, help="原始数据目录") parser.add_argument("--output", default="output/result.xlsx", help="输出文件路径") args = parser.parse_args() print(args.data_dir, args.output)

也可以使用 tkinter 做一个极简文件选择器,让同事点选目录就能运行。但如果仅给自己用,其实保持 Python 脚本命令行运行是最轻量的。

9.4 文件备份与二次确认

办公自动化操作真实数据时,最怕的是覆盖重要文件。有几个习惯值得从一开始就养成:

  • 正式执行前先备份原始文件目录;
  • 脚本中尽量避免覆盖源文件,尽可能把结果输出到output/目录;
  • 批量删除或写入前增加确认提示,比如输入yes才继续;
  • 对 Excel 的修改操作,建议先load_workbook后复制一份副本.xlsx再处理。

10. 总结与下一步学习建议

本文从一个相对完整的实践视角,带你走完了 Python 操作 Excel、Word、PPT 的核心链路。现在做个简单的梳理:

  • 在 Excel 方面,掌握了 openpyxl 的加载工作簿、读取单元格、写入数据、保存文件的完整流程,并通过多 Excel 合并统计样例,理解遍历文件、合并数据和分组统计的组合实现方式。
  • 在 Word 方面,掌握了 python-docx 的操作模型,学会了如何把模板 Word 文档中的占位符批量替换成不同人员的信息,也了解了处理表格文件的基础方法。
  • 在 PPT 方面,掌握了 python-pptx 的创建、写入文本、插入简单柱状图的流程,并尝试把真实数据变成可演示的周报页面。
  • 在工程层面,你能体会到脚本不应一次性写完就废弃,尽可能把路径抽成配置,加入日志、备份和异常处理,才能在真实工作中持续复用。

后面的学习建议,可以按几条路线往前走:

第一条,深入数据清洗与分析。如果你希望接手更复杂的 Excel 表格,建议多练 pandas 的 groupby、pivot_table、merge,这些函数解决复杂业务报表时非常高效。

第二条,深入 Word 与 PPT 模板制作。学习如何制作稳定、适配脚本替换的 Office 模板,合理设计段落样式、母版占位符,就能让最终产物有更好的视觉效果,也能减少脚本的临时处理逻辑。

第三条,学习定时调度。如果需要每天定时跑一次报表,可以先学习 Windows 任务计划程序或 Linux 上的 cron,把 Python 脚本配置为每日执行,实现零手工干预的自动化。

第四条,探索其他文件格式。CSV、JSON、PDF 都是办公数据流转的常见格式,遇到 PDF 抽取表格或批量合并场景时,可以补充了解 pdfplumber 等库。

动手建议也很简单:从你手头最重复、最无聊的那张 Excel 表开始,用 Python 写一个小脚本,尝试把第一版跑通。不用管代码写得是否优雅,只要运行成功一次,你后续的学习动力就会不一样。

如果本文中的示例代码对你的工作有帮助,可以对照实际文件结构适当修改直接使用。也建议你在本地准备一个练习文件夹,把代码亲手敲一遍、运行一遍,理解每一段代码为什么这么写。这样从“看得懂例子”到“自己写自动化工具”的过渡才真正完成。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/4 19:34:07

肖尔算法:量子计算如何实现大数分解的指数级加速

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/4 19:34:01

从情感计算到工程实践:构建与管理高质量伤感音乐合集

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/4 19:30:53

MATLAB路径规划实战:A*、PRM与RRT算法核心原理与工程应用对比

简介:本资源是一套面向计算机科学与技术等相关专业本科生的移动机器人路径规划MATLAB实践方案,适用于课程设计、期末大作业及算法综合实训等场景。聚焦A*、PRM与RRT三类经典路径规划算法,分别实现其改进版本——包括启发式优化的A 搜索、融合…

作者头像 李华
网站建设 2026/9/4 19:23:46

STM32F4驱动ADS8860:16位ADC数据采集的硬件设计与软件实现

简介:本资源是一套基于STM32F4系列微控制器与TI ADS8860高精度16位ADC的SPI通信完整工程实现,面向嵌入式开发者、高校电子类专业学生及工业数据采集系统设计人员,解决高速模拟信号数字化采集与MCU协同控制的核心问题。压缩包共26个文件&#…

作者头像 李华
网站建设 2026/9/4 19:16:47

Android健康管家系统开发:从传感器采集到数据可视化的完整实践

简介:本资源是一套完整的Android平台个人健康管理应用毕业设计解决方案,面向计算机、软件工程等专业本科生,解决毕业设计选题难、开发周期长、文档不规范等实际问题。项目包含253个文件,涵盖57个Java核心逻辑代码、79个XML界面与配…

作者头像 李华
网站建设 2026/9/4 19:14:58

300元自制25G网卡:FPGA开源方案实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华