Python自动化办公实战:openpyxl、python-docx与python-pptx高效处理Excel、Word和PPT

发布时间:2026/10/29 0:43:54
Python自动化办公实战:openpyxl、python-docx与python-pptx高效处理Excel、Word和PPT 简介这份Python自动化办公教程面向希望用编程替代重复手工操作的职场人与初学者系统讲解如何借助Python提升日常办公效率。内容覆盖Python基础语法与变量、条件循环等入门知识并逐章展开Excel读写与样式图表处理、Word文档生成、PDF合并拆分、邮件收发解析、数据库增删改查、网络请求与爬虫、文件及进程线程管理等实用模块每章配有习题与实操案例便于边学边练。资源包为1个docx文档约1.84MB按章节组织目录结构清晰可直接作为学习笔记或教学讲义使用。目前已有1146人学习适合需要系统掌握办公自动化技能、希望减少手动操作繁琐度的读者参考。1. 从一份 64 页的教程说起Python 自动化办公到底能替你省下多少手工活月底最后一天财务催工资条、行政催复工证明、业务催周报 PPT三件事挤在一起每件都是复制粘贴改格式。这份《Python 自动化办公教程》就是冲着这类场景来的64 页正文加 60 多个编号示例覆盖 openpyxl 操作 Excel、python-docx 处理 Word 与 PDF、python-pptx 生成 PPT 三大块每个知识点后面都跟着可直接运行的示例代码。它适合两类人一类是天天跟表格文档打交道、想把手动流程换成脚本的办公岗另一类是想找一个完整练手项目、把库的 API 摸熟的 Python 初学者。教程不教你 Python 语法默认你能看懂 for 循环和函数调用重心全在“库怎么用、对象怎么取、样式怎么改”这些实操细节上。2. openpyxl 的三层对象模型Workbook、Worksheet、Cell 怎么对应到真实表格openpyxl 是这份教程的第一章也是整套自动化办公的地基。很多人第一次用会卡在一个认知上代码里的对象和 Excel 界面上的东西不是一一对应的。教程开篇就把这层关系拆清楚了——Workbook 是工作簿对应一个 .xlsx 文件Worksheet 是工作表对应底部标签页Cell 是单元格对应 A1、B2 这种坐标。三层对象各有各的属性和方法取数据的路径永远是“先拿 Workbook再拿 Worksheet最后拿 Cell”顺序错了就拿不到值。2.1 安装与加载load_workbook 的 filename 参数是唯一必传项环境准备只有一条命令但版本问题值得提前说一句。openpyxl 只支持 Excel 2010 之后的 .xlsx 格式遇到 .xls 老文件得先另存或换库这是教程里明确写了的边界。pip install openpyxl装完之后创建和加载走两条不同的路新建用Workbook()打开已有文件用load_workbook()。后者参数不少但只有 filename 是必传的可以传路径字符串也可以传一个已打开的文件对象。操作完记得save()否则所有修改只存在内存里关掉进程就没了。import openpyxl # 新建一个工作簿内存中创建尚未落盘 wb_new openpyxl.Workbook() # 加载本地已有工作簿filename 为必传参数 wb openpyxl.load_workbook(excelTest.xlsx) # 所有写操作完成后必须保存否则修改丢失 wb.save(workbook_test.xlsx)这里有个新手常忽略的点save()的路径如果和原文件相同等于原地覆盖没有撤销。我一般会先存成带时间戳的副本确认结果对了再替换原文件这个习惯后面会反复用到。2.2 读取的四种姿势整表遍历、整行整列、切片、坐标直取教程在读取部分给了十几个示例归纳下来是四种取数方式选哪种取决于你要处理的数据形状。第一种是坐标直取适合已知位置的单点读取。ws[A1]返回 Cell 对象.value才是值ws.cell(row1, column2)是另一种写法行列都用数字适合循环里拼坐标。import openpyxl wb openpyxl.load_workbook(excelTest.xlsx) ws wb.active # 获取当前激活的工作表 # 坐标直取拿到 Cell 对象再取 value c ws[B1] print(c.row, c.column, c.value) # 行号、列号、值 print(c.coordinate) # 坐标字符串如 B1 # 行列数字写法适合在循环中动态定位 print(ws.cell(row1, column2).value)第二种是整表遍历用ws.rows按行拿每行是一个元组里面是 Cell 对象。这是最通用的读法适合不知道数据边界、需要全量扫描的场景。第三种是整行整列ws[C]拿 C 列全部ws[6]拿第 6 行返回的都是元组。第四种是切片ws[2:4]拿第 2 到第 4 行注意切片是左闭右开还是左闭右闭openpyxl 这里是包含结束行的跟 Python 列表切片不一样这个差异坑过不少人。# 整表按行遍历逐格打印 for row in ws.rows: for cell in row: print(cell.value, end\t) print() # 整列读取 for cell in ws[C]: print(cell.value, end\t) # 切片读取第 2 到第 4 行含第 4 行 for row in ws[2:4]: for cell in row: print(cell.value, end\t) print()如果数据量大iter_rows()比ws.rows更可控它支持 min_row、max_row、min_col、max_col 四个参数可以只读某个矩形区域避免把整张表拉进内存。教程里专门有一个示例讲这个实际项目里处理几万行的报表时这个参数组合是必用的。2.3 写入与样式append 批量写、字体行高列宽、合并单元格写入部分教程给了三种方式list 写入、range 写入、cell() 方法写入。最省事的是append()传一个可迭代对象它自动往下一行追加适合从数据库或列表里批量灌数据。# 逐行追加每次调用写一行 ws.append([姓名, 部门, 加班时长]) ws.append([张三, 技术部, 12]) ws.append([李四, 市场部, 8])样式修改是这份教程比较细的地方。字体用Font行高列宽用row_dimensions和column_dimensions合并单元格用merge_cells()拆分用unmerge_cells()。公式也可以直接写进单元格值以等号开头openpyxl 存的是公式字符串打开 Excel 时才计算。from openpyxl.styles import Font # 修改 A1 字体加粗、字号 14、红色 ws[A1].font Font(boldTrue, size14, colorFF0000) # 设置行高和列宽 ws.row_dimensions[1].height 30 ws.column_dimensions[A].width 20 # 合并 A1 到 C1写入标题 ws.merge_cells(A1:C1) ws[A1] 月度加班统计表 # 在单元格写入公式 ws[D2] C2*1.5参数说明上Font的 color 用十六进制 RGB 字符串不带井号行高单位是磅列宽单位是字符宽度这两个单位不一样调的时候别按同一个比例缩放。合并单元格有个隐藏坑合并后只有左上角那个格子保留值其余格子的值会被清掉如果先写值再合并数据就丢了正确顺序是先合并再写值。2.4 图表与三个实操案例工资条、加班统计、身份证提取教程第一章末尾放了三个实操案例是整章最值得照着敲的部分。生成工资条考的是循环加样式复制每人间隔插空行统计加班时间考的是按部门聚合加公式计算提取身份证年月日考的是字符串切片加日期格式化。图表部分覆盖饼图、条形图、气泡图、散点图四种核心套路是先准备数据区域再建图表对象设置类型和引用范围最后add_chart()挂到工作表上。from openpyxl.chart import BarChart, Reference # 数据区域假设 B1:C5 是类别和数值 chart BarChart() chart.type col chart.title 部门加班时长 # 引用数据min_col2 表示取第二列数值 data Reference(ws, min_col2, min_row1, max_row5) cats Reference(ws, min_col1, min_row2, max_row5) chart.add_data(data, titles_from_dataTrue) chart.set_categories(cats) # 挂到当前工作表锚定在 E2 位置 ws.add_chart(chart, E2)Reference的 min_row 和 max_row 决定取数范围titles_from_dataTrue表示第一行当图例标题。图表位置用锚点字符串控制写 “E2” 就贴在 E2 左上角。这部分代码跑通一次后面换数据源只改 Reference 的范围就行。3. python-docx 与 PDF 处理从生成文档到合并拆分加密第二章从 Excel 转到 Word 和 PDF。python-docx 的对象模型比 openpyxl 多一层Document 是文档Paragraph 是段落Run 是段落里格式一致的一段文字。理解 Run 是这章的关键因为字体、字号、加粗这些样式都挂在 Run 上不是挂在 Paragraph 上。很多人设置段落字体没生效就是因为改错了层级。3.1 文档结构Document、Paragraph、Run 的层级关系新建文档用Document()打开已有文档用Document(xxx.docx)。加标题用add_heading()加段落用add_paragraph()加列表和引用也是add_paragraph()配合 style 参数。图片用add_picture()表格用add_table()这两个方法都返回对象可以继续往里填内容。from docx import Document from docx.shared import Pt, Inches doc Document() # 加标题level 控制层级 doc.add_heading(月度工作报告, level1) # 加段落 p doc.add_paragraph(本月完成情况如下) # 加列表项style 指定列表样式 doc.add_paragraph(完成 A 项目验收, styleList Bullet) doc.add_paragraph(完成 B 项目立项, styleList Bullet) # 加图片指定宽度 doc.add_picture(chart.png, widthInches(5)) # 加表格2 行 3 列 table doc.add_table(rows2, cols3) table.cell(0, 0).text 项目 table.cell(0, 1).text 进度 table.cell(0, 2).text 负责人 doc.save(report.docx)样式设置要落到 Run 上。p.add_run(文字)返回一个 Run 对象然后设run.font.size、run.font.bold、run.font.name。中文字体还有个额外坑python-docx 设font.name只对西文生效中文要额外设run._element.rPr.rFonts.set(qn(w:eastAsia), 宋体)这个写法教程里没展开但实际做中文报告绕不开。from docx.oxml.ns import qn p doc.add_paragraph() run p.add_run(这段文字是加粗的宋体小四) run.font.bold True run.font.size Pt(12) run.font.name 宋体 # 中文字体必须单独设置 eastAsia 属性 run._element.rPr.rFonts.set(qn(w:eastAsia), 宋体)3.2 PDF 四件套转换、读取、合并、拆分、加密PDF 部分教程给了五个示例Word 转 PDF、读取内容、合并、拆分、加密。Word 转 PDF 依赖本机装了 Office 或 LibreOfficepython-docx 本身不做转换常见做法是调docx2pdf或走 COM 接口教程里用的是后者思路。读取内容用 PyPDF2 的PdfReader逐页extract_text()。合并用PdfWriter逐个add_page()拆分就是按页范围分别写出去加密用encrypt()设密码。from PyPDF2 import PdfReader, PdfWriter # 合并两个 PDF writer PdfWriter() for f in [a.pdf, b.pdf]: reader PdfReader(f) for page in reader.pages: writer.add_page(page) with open(merged.pdf, wb) as out: writer.write(out) # 拆分只取第一个文件的前两页 reader PdfReader(a.pdf) writer PdfWriter() for page in reader.pages[:2]: writer.add_page(page) with open(split.pdf, wb) as out: writer.write(out) # 加密 writer.encrypt(mypassword)参数上encrypt()传用户密码打开文件时就要输。合并时注意页面顺序按循环顺序来想调整顺序就调整文件列表或页索引。拆分时reader.pages[:2]是切片取前两页这个切片是标准 Python 语义左闭右开跟 openpyxl 的切片行为不同两个库混用时容易记混。3.3 两个生成类案例罚单通知书与复工证明这章的两个实操案例都是“模板填充”思路先建一个带占位符的文档再用循环把数据逐条替换进去每条数据生成一份新文档。罚单通知书考的是表格填充加金额格式化复工证明考的是日期处理和落款排版。这类批量生成在行政、人事场景里复用率极高把模板和字段列表拆开换一套数据就是另一个业务。from docx import Document records [ {name: 张三, date: 2024-03-01, dept: 技术部}, {name: 李四, date: 2024-03-02, dept: 市场部}, ] for r in records: doc Document(template.docx) # 遍历段落替换占位符 for p in doc.paragraphs: if {{name}} in p.text: for run in p.runs: run.text run.text.replace({{name}}, r[name]) run.text run.text.replace({{date}}, r[date]) run.text run.text.replace({{dept}}, r[dept]) doc.save(f证明_{r[name]}.docx)这里有个细节占位符如果被 Word 拆到多个 Run 里直接替换p.text不生效得逐个 Run 替换或者先合并 Run。上面代码按 Run 替换是稳妥写法但如果占位符本身被拆开比如{{na和me}}分在两个 Run还是会漏实际项目里我一般要求模板制作时占位符一次性输入、不中途改格式。4. python-pptx 生成演示文稿页面、文本框、图表四件套第三章讲 PPT篇幅比前两章短但覆盖了从建页到画图的完整链路。python-pptx 的对象模型是 Presentation → Slide → Shape 三层Presentation 是文件Slide 是单页Shape 是页面上的元素文本框、图片、表格、图表都算 Shape。新建用Presentation()加页用slides.add_slide(layout)layout 决定版式空白页用第 6 个版式索引。4.1 建页与占位符layout 索引决定页面骨架from pptx import Presentation from pptx.util import Inches, Pt prs Presentation() # 用第 6 个版式空白页新建一页 slide prs.slides.add_slide(prs.slide_layouts[6]) # 加文本框指定位置和大小 txBox slide.shapes.add_textbox(Inches(1), Inches(1), Inches(8), Inches(1)) tf txBox.text_frame tf.text 季度经营分析 # 段落级样式 p tf.paragraphs[0] p.font.size Pt(28) p.font.bold True prs.save(demo.pptx)add_textbox的四个参数依次是 left、top、width、height单位用Inches或Pt。文本框里的内容通过text_frame操作tf.text设第一段要加多段就tf.add_paragraph()。字体样式挂在 paragraph 或 run 上跟 Word 的逻辑类似。4.2 图片、表格与四类图表流程图、条形图、折线图、饼图图片用shapes.add_picture(path, left, top, width)表格用shapes.add_table(rows, cols, left, top, width, height)表格单元格通过table.cell(r, c).text填。图表部分教程给了流程图、条形图、折线图、饼图四种其中流程图是用形状拼的条形图和折线图用add_chart配合CategoryChartData。from pptx.chart.data import CategoryChartData from pptx.enum.chart import XL_CHART_TYPE # 准备图表数据 chart_data CategoryChartData() chart_data.categories [一季度, 二季度, 三季度, 四季度] chart_data.add_series(销售额, (120, 150, 130, 180)) # 插入条形图 slide.shapes.add_chart( XL_CHART_TYPE.COLUMN_CLUSTERED, Inches(1), Inches(2), Inches(8), Inches(4), chart_data )XL_CHART_TYPE是枚举条形图用COLUMN_CLUSTERED折线图用LINE饼图用PIE。add_series的第一个参数是系列名第二个是数值元组类别数量要和数值数量对齐不对齐会报错。图表样式颜色、图例位置可以通过返回的 chart 对象继续调教程里有一个示例专门讲样式设置。5. 避坑与排查五个真实翻车现场5.1 保存后文件打不开或数据丢失现象脚本跑完没报错打开生成的 xlsx 提示文件损坏或者内容全是空的。原因通常是save()路径写错、在with open里重复保存或者对同一个 Workbook 对象反复 save 到同一路径导致句柄冲突。解决保存前打印绝对路径确认保存后立刻用load_workbook()回读一次验证确认能打开再往下走。5.2 中文乱码或字体设置不生效现象Word 里设了字体打开还是默认宋体Excel 里中文显示成问号。原因python-docx 的font.name只管西文中文要走 eastAsia 属性Excel 乱码多半是读写时编码没对齐或者源文件本身是 CSV 被当 xlsx 打开。解决Word 按 3.1 节的写法补 eastAsiaExcel 确认文件后缀和实际格式一致CSV 用encodingutf-8-sig读。5.3 合并单元格后数据消失现象先写值再merge_cells()合并完只剩左上角的值其他全没了。原因openpyxl 合并时只保留左上角单元格其余值被清空这是设计行为不是 bug。解决先合并再写值或者合并前把要保留的值挪到左上角格子。5.4 切片范围差一行现象想读第 2 到第 4 行结果只读到 2、3 行或者多读了一行空行。原因openpyxl 的ws[2:4]包含结束行PyPDF2 的pages[:2]不包含结束索引两个库语义相反。解决openpyxl 切片按“含头含尾”记PyPDF2 按标准 Python 切片记混用时在代码里加注释标清楚。5.5 大批量写入内存爆掉或速度极慢现象几万行数据append()循环写内存一路涨最后卡死。原因openpyxl 默认把整个工作簿放在内存里行数一多就撑不住。解决改用write_onlyTrue模式创建 Workbook用ws.append()流式写写完save()内存占用能降一个量级读的时候用read_onlyTrue配iter_rows()。# 只写模式适合大数据量导出 wb openpyxl.Workbook(write_onlyTrue) ws wb.create_sheet() for row in big_data: ws.append(row) wb.save(big.xlsx)6. 把三个库串成一条流水线一个可复用的月度报表脚本单看每个库都不难真正省时间的是把它们串起来。我现在的习惯是Excel 做数据源和汇总Word 做正式文书PPT 做汇报材料一个脚本从头跑到尾。下面这个骨架是我反复改过几版的去掉业务字段后可以直接套。import openpyxl from docx import Document from pptx import Presentation from pptx.util import Inches from pptx.chart.data import CategoryChartData from pptx.enum.chart import XL_CHART_TYPE # 第一步从 Excel 读数据 wb openpyxl.load_workbook(source.xlsx, read_onlyTrue) ws wb.active rows [] for row in ws.iter_rows(min_row2, values_onlyTrue): if row[0] is None: continue rows.append({name: row[0], dept: row[1], hours: row[2]}) wb.close() # 第二步按部门聚合 summary {} for r in rows: summary[r[dept]] summary.get(r[dept], 0) r[hours] # 第三步生成 Word 汇总 doc Document() doc.add_heading(月度加班汇总, level1) for dept, hours in summary.items(): doc.add_paragraph(f{dept}{hours} 小时, styleList Bullet) doc.save(summary.docx) # 第四步生成 PPT 图表 prs Presentation() slide prs.slides.add_slide(prs.slide_layouts[6]) chart_data CategoryChartData() chart_data.categories list(summary.keys()) chart_data.add_series(加班时长, tuple(summary.values())) slide.shapes.add_chart( XL_CHART_TYPE.COLUMN_CLUSTERED, Inches(1), Inches(1), Inches(8), Inches(5), chart_data ) prs.save(summary.pptx)这段代码的关键在第一步的read_onlyTrue和values_onlyTrue前者让大文件不占内存后者让iter_rows直接返回值而不是 Cell 对象省掉一层.value。聚合用字典累加几行就够。Word 和 PPT 部分都是前面章节的最小组合没有新 API。验证方法我固定走三步先看文件能不能正常打开再抽查两三个数据点和源表对得上最后把生成的 PPT 图表和 Word 列表交叉核对一遍。这套流程跑顺之后原来一上午的活压缩到十分钟以内剩下的时间用来检查数据本身对不对而不是耗在复制粘贴上。从那以后我每次写批量生成脚本都强制先拿三条假数据跑一遍全流程确认输出文件能打开、字段没错位再换真实数据。这个习惯帮我挡掉过好几次“脚本跑完才发现模板占位符被 Word 拆成两半”的事故。希望这份教程的拆解能帮到你把重复劳动真正交给代码。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询