一、Excel 自动化,真正值钱的不是会不会读表,而是能不能少做重复劳动
办公自动化里,Excel 几乎是绕不过去的一座山。
名单在 Excel 里。 销售表在 Excel 里。 库存表在 Excel 里。 日报、周报、月报在 Excel 里。 财务明细、人事台账、项目跟踪表,也经常都在 Excel 里。
很多人学 Python 办公自动化,最先感受到价值的地方,往往就来自 Excel。
因为现实里最痛苦的工作,常常不是不会做,而是:
每天都要做 每周都要做 每月都要做 而且步骤几乎一样
比如:
把几十个门店的 Excel 汇总成一张总表 按条件筛出重点客户 自动补一列统计结果 给每行算销售额、利润率、完成率 按部门拆成多个文件 自动生成新表 修改标题、样式、列宽 再导出给别人
这些工作,如果只做一次,人还能忍。 但一旦变成高频重复任务,Python 的优势就会非常明显。
所以这一章的重点不是“Excel 能不能处理”,而是:
怎么把 Excel 这类高频、重复、规则明确的操作,变成可复用脚本。
二、处理 Excel,通常会接触两条路线
Python 处理 Excel,最常见的两条路线分别是:
一条偏数据处理 一条偏表格操作
先说结论:
如果你主要想做数据读取、筛选、统计、合并、清洗,通常优先想到 pandas。 如果你主要想做单元格级别的操作,比如改格式、调列宽、设字体、插入工作表、改表头,通常优先想到 openpyxl。
这两个库不是竞争关系,而是经常配合使用。
你可以这样记:
Pandas 更像表格里的“数据分析师” openpyxl 更像表格里的“排版与细节编辑员”
很多真实项目里,做法往往是:
先用 Pandas 处理数据 再用 openpyxl 微调表格样式和结构
这套组合特别常见,也特别实用。
三、先安装会用到的库
如果你的环境里还没装,可以先安装:
python -m pip install pandas openpyxl
其中:
pandas 用来高效处理表格数据openpyxl 用来读写 .xlsx 文件,并操作工作簿、工作表、单元格
为什么装 openpyxl。
因为 Pandas 在读写 Excel 时,很多情况下本身也要借助它。 尤其是 .xlsx 文件,这是非常常见的依赖组合。
四、第一步先学会读 Excel,这是一切自动化的入口
如果连 Excel 数据都接不进来,后面所有自动化都无从谈起。
最常见的读取方式是:
import pandas as pddf = pd.read_excel("销售数据.xlsx")print(df.head())
这行代码就能把 Excel 第一张工作表读成 DataFrame。
你接下来就可以像处理普通 Pandas 表格一样:
筛选 排序 分组 新增列 导出结果
如果文件里有多个工作表,可以指定表名:
import pandas as pddf = pd.read_excel("销售数据.xlsx", sheet_name="1月销售")print(df.head())
也可以按工作表索引读取:
df = pd.read_excel("销售数据.xlsx", sheet_name=0)
这里 0 表示第一张工作表。
如果你想一次读取所有工作表:
import pandas as pdall_sheets = pd.read_excel("销售数据.xlsx", sheet_name=None)print(type(all_sheets))print(all_sheets.keys())
这时返回的通常是一个字典。 键是工作表名,值是对应的 DataFrame。
这在月报、台账、对账表里特别有用,因为很多 Excel 文件本来就不是一张表,而是很多张。
五、为什么读取 Excel 后,第一件事通常不是处理,而是先看结构
这是非常重要的习惯。
真实工作里的 Excel,很少像教材那样干净。 经常会出现:
表头不在第一行 有合并单元格 有空行 列名不规范 有备注行 有小计、合计行 日期格式混乱 数字列被读成字符串
所以你在处理前,最好先看几眼:
print(df.head())print(df.info())print(df.columns)
这样你至少能先知道:
列名是不是你想象的那样 哪些列有空值 哪些列类型不对 数据是不是从正确位置读进来了
这一步如果偷懒,后面往往会花更多时间排错。
六、如果表头不在第一行,该怎么读
这是办公 Excel 很常见的情况。
比如有些表前面两三行是标题、说明、日期,真正的字段名从第 4 行才开始。 这时可以用 header 参数指定:
import pandas as pddf = pd.read_excel("销售数据.xlsx", header=2)print(df.head())
这里 header=2 表示:
把 Excel 的第 3 行当作列名 因为索引从 0 开始算
如果前面有完全不需要的说明行,也可以先跳过:
df = pd.read_excel("销售数据.xlsx", skiprows=2)
或者同时配合:
df = pd.read_excel("销售数据.xlsx", header=1, skiprows=1)
这类参数在真实办公表格里非常有用。 因为很多表不是为程序准备的,而是为人看的,格式往往不够规整。
七、只读自己关心的列,往往会更高效
有时 Excel 表很大,但你只关心其中几列。 这时没必要整张表都读进来。
比如只读“门店、商品、销量、单价”:
import pandas as pddf = pd.read_excel("销售数据.xlsx", usecols=["门店", "商品", "销量", "单价"])print(df.head())
也可以按列范围读:
df = pd.read_excel("销售数据.xlsx", usecols="A:D")
这种做法的好处有两个:
第一,更快 第二,更清晰
因为你一开始就把无关信息排除掉了。 后面的分析逻辑也会更干净。
八、最常见的自动化场景之一:批量合并多个 Excel 文件
这几乎是办公自动化里的经典题。
比如一个文件夹里有很多门店日报:
北京店.xlsx 上海店.xlsx 广州店.xlsx 深圳店.xlsx
你想把它们合并成一张总表。
最常见的写法是:
import pandas as pdfrom pathlib import Pathfolder = Path("日报")all_data = []for file in folder.glob("*.xlsx"): df = pd.read_excel(file) df["来源文件"] = file.name all_data.append(df)result = pd.concat(all_data, ignore_index=True)print(result.head())
这里有几个关键点。
folder.glob("*.xlsx")表示找出该文件夹下所有 Excel 文件
每读一张表,就加一列 来源文件这样后面你还能追溯数据来自哪个文件
pd.concat()把所有 DataFrame 纵向拼接起来
ignore_index=True表示重新生成连续索引
这段代码的价值非常大。 因为很多人工要做的“复制粘贴汇总”,本质上都能归到这个模式里。
九、合并多个文件时,最容易遇到的问题是什么
不是代码不会写,而是文件不整齐。
比如:
有的表列名叫“销售额”,有的叫“金额” 有的列顺序不同 有的表多一列 有的表少一列 有的表混着合计行 有的文件不是你要的数据表
所以批量合并 Excel 时,真正成熟一点的做法通常是:
先统一列名 再清洗格式 最后再拼接
比如先重命名列:
df = df.rename(columns={"金额": "销售额"})
或者只保留标准列:
df = df[["门店", "商品", "销量", "单价", "销售额"]]
这类动作虽然不炫,但非常实战。 因为办公室里最烦的,不是技术难,而是“表不统一”。
十、第二个高频场景:批量新增计算列
很多 Excel 表里,原始字段有了,但业务指标没有。 这时 Python 就特别适合统一补上。
比如补销售额:
import pandas as pddf = pd.read_excel("销售数据.xlsx")df["销售额"] = df["销量"] * df["单价"]print(df.head())
再比如补完成率:
df["完成率"] = df["实际完成"] / df["目标值"]
再比如补利润:
df["利润"] = df["销售额"] - df["成本"]
或者根据条件生成标记列:
df["是否达标"] = df["销售额"] >= 1000
这类批量计算的价值在于:
你不再需要在 Excel 里一列列写公式、拖拽、复制 也不用担心某几行漏掉、公式错位 规则统一后,所有数据都按同一标准算
办公自动化最怕的就是“人手拖公式”这种容易失误的动作。 而 Python 特别适合把它标准化。
十一、第三个高频场景:按条件筛出结果并导出新表
比如你有一大张客户名单,只想筛出高销售额客户:
import pandas as pddf = pd.read_excel("客户数据.xlsx")vip_df = df[df["销售额"] > 5000]vip_df.to_excel("高销售额客户.xlsx", index=False)
再比如筛出即将到期的合同:
df = pd.read_excel("合同台账.xlsx")result = df[df["剩余天数"] <= 30]result.to_excel("即将到期合同.xlsx", index=False)
或者筛出某个部门:
df = pd.read_excel("员工名单.xlsx")hr_df = df[df["部门"] == "人事部"]hr_df.to_excel("人事部名单.xlsx", index=False)
这类脚本之所以值钱,是因为它能把“每次都要手动筛一遍”的操作,变成一次写好、反复复用的工具。
十二、第四个高频场景:按某个字段拆分成多个 Excel 文件
这个场景也特别常见。
比如一张总表里有所有门店的数据,你想按门店分别导出:
北京.xlsx 上海.xlsx 广州.xlsx
可以这样做:
import pandas as pdfrom pathlib import Pathdf = pd.read_excel("总销售表.xlsx")output_folder = Path("按门店拆分")output_folder.mkdir(exist_ok=True)for store, group in df.groupby("门店"): output_file = output_folder / f"{store}.xlsx" group.to_excel(output_file, index=False)
这里的逻辑特别清楚:
按“门店”分组 每组单独拿出来 导出成一个同名 Excel 文件
这个模式在很多办公场景里都非常好用,比如:
按部门拆名单 按城市拆客户表 按项目拆台账 按月份拆报表 按负责人拆任务清单
它解决的是“一个总表要拆成很多分表”的问题,这在实际办公里出现频率非常高。
十三、第五个高频场景:批量汇总到多个工作表
有时你不是想拆成多个文件,而是想放到同一个 Excel 的不同工作表里。 比如:
总表一个 sheet 北京一个 sheet 上海一个 sheet 广州一个 sheet
这时可以用 ExcelWriter:
import pandas as pddf = pd.read_excel("总销售表.xlsx")with pd.ExcelWriter("门店汇总.xlsx") as writer: df.to_excel(writer, sheet_name="总表", index=False)for store, group in df.groupby("门店"): group.to_excel(writer, sheet_name=store, index=False)
这样导出的一个 Excel 文件里,就会有多个工作表。
这在汇报场景里特别好用。 因为别人打开一个文件,就能同时看到总览和各分项,不需要翻很多个文件。
十四、如果只用 Pandas,能不能完成大部分表格处理
答案是,能完成相当大一部分。
只要你的需求主要集中在:
读表 筛表 算表 合并 拆分 汇总 导出
那么 Pandas 已经非常强了。
很多人做 Excel 自动化,卡的不是技术,而是总觉得“要不要学很复杂的 Excel 底层操作”。 其实先别急。
因为大多数日常办公表格问题,先用 Pandas 已经能解决很多。 只有当你开始涉及:
单元格样式 字体 颜色 边框 合并单元格 公式 列宽 工作表结构
这时才更需要 openpyxl。
所以你可以把 Pandas 理解成:
先把“数据问题”解决掉。
而 openpyxl 更像是:
再把“表格呈现问题”解决掉。
十五、接下来看看 openpyxl,它更像在操作“Excel 本身”
Pandas 更关注表格里的数据。 openpyxl 更关注 Excel 这个文件对象本身。
比如你想:
打开工作簿 选中某张工作表 读取某个单元格 修改某个单元格内容 设置字体加粗 调整列宽 插入新行 保存文件
这类动作,openpyxl 就更顺手。
最基础的读取方式:
from openpyxl import load_workbookwb = load_workbook("销售数据.xlsx")ws = wb["Sheet1"]print(ws["A1"].value)
这里:
wb 是工作簿ws 是工作表A1 是单元格坐标
这套思路跟 Pandas 很不一样。 它更像在直接操作 Excel 页面结构。
十六、用 openpyxl 读取和修改单元格
比如读取某个单元格:
from openpyxl import load_workbookwb = load_workbook("销售数据.xlsx")ws = wb["Sheet1"]print(ws["B2"].value)
修改某个单元格:
ws["C2"] = 999wb.save("销售数据_修改后.xlsx")
也可以按行列号访问:
print(ws.cell(row=2, column=3).value)ws.cell(row=2, column=3, value=999)
这在做固定模板表时特别有用。 因为很多办公表格,本来就有明确的单元格位置要求。
比如:
标题必须写在 A1 日期写在 F2 统计结果写在 B10 备注写在 A20
这类场景,Pandas 反而没那么顺,openpyxl 会更合适。
十七、遍历单元格,也是 openpyxl 的高频动作
有时你不是只改一个格子,而是要遍历整列、整行或整个区域。
比如读取第一列所有值:
from openpyxl import load_workbookwb = load_workbook("销售数据.xlsx")ws = wb["Sheet1"]for row in ws.iter_rows(min_row=2, max_col=1, max_row=ws.max_row):for cell in row: print(cell.value)
或者按行遍历几列数据:
for row in ws.iter_rows(min_row=2, values_only=True): print(row)
values_only=True 很方便,因为它直接返回值,不返回 Cell 对象。
这类操作适合什么场景。
比如:
检查模板内容 批量读取某列 查找空单元格 按固定行列位置抓数据
十八、设置样式,是 openpyxl 特别重要的一块
很多自动化办公,不只是“生成一个能看的表”,而是“生成一个像正式报表的表”。
比如标题要加粗 表头要居中 金额列要统一格式 重点数据要标红 列宽要调合适
这时就要用样式功能。
比如加粗标题:
from openpyxl import load_workbookfrom openpyxl.styles import Fontwb = load_workbook("销售数据.xlsx")ws = wb["Sheet1"]ws["A1"].font = Font(bold=True)wb.save("销售数据_加粗标题.xlsx")
设置字体颜色:
ws["A1"].font = Font(color="FF0000", bold=True)
设置居中:
from openpyxl.styles import Alignmentws["A1"].alignment = Alignment(horizontal="center")
这些功能在正式报表、模板导出里特别有用。 因为真实办公里,很多结果不是只给程序看,而是最终要给人看。
十九、调整列宽,是很实用但很容易被忽略的细节
如果你用程序导出 Excel,默认列宽有时不太好看。 内容可能显示不全,也可能特别挤。
这时可以手动调列宽:
from openpyxl import load_workbookwb = load_workbook("销售数据.xlsx")ws = wb["Sheet1"]ws.column_dimensions["A"].width = 20ws.column_dimensions["B"].width = 15wb.save("销售数据_调整列宽.xlsx")
如果你做的是自动生成报表,这种细节会明显影响最终观感。 所以别小看列宽、对齐、字体这些操作,它们往往决定了“像不像正式文件”。
二十、批量生成 Excel 报表,通常会怎么组合 Pandas 和 openpyxl
这是一条非常典型的实战路线。
第一步,用 Pandas 做数据处理:
读表 筛选 分组 计算 汇总 导出成 Excel
第二步,再用 openpyxl 做样式优化:
改表名 加标题 加粗表头 调列宽 改颜色 设边框 补说明
比如:
import pandas as pdsummary = df.groupby("门店", as_index=False)[["销量", "销售额"]].sum()summary.to_excel("门店汇总.xlsx", index=False)
然后再打开处理样式:
from openpyxl import load_workbookfrom openpyxl.styles import Fontwb = load_workbook("门店汇总.xlsx")ws = wb.activefor cell in ws[1]: cell.font = Font(bold=True)wb.save("门店汇总_美化.xlsx")
这种组合方式特别常见。 因为它把“数据处理”和“样式呈现”分开了,思路很清楚。
二十一、一个完整的小案例:自动生成门店销售汇总表
下面做一个稍完整一点的例子。
目标:
读取原始销售表 计算销售额 按门店汇总销量和销售额 导出成 Excel 把表头加粗
代码如下:
import pandas as pdfrom openpyxl import load_workbookfrom openpyxl.styles import Font# 读取原始数据df = pd.read_excel("销售数据.xlsx")# 新增销售额列df["销售额"] = df["销量"] * df["单价"]# 按门店汇总summary = df.groupby("门店", as_index=False)[["销量", "销售额"]].sum()# 导出结果output_file = "门店销售汇总.xlsx"summary.to_excel(output_file, index=False)# 美化表头wb = load_workbook(output_file)ws = wb.activefor cell in ws[1]: cell.font = Font(bold=True)wb.save(output_file)
这段代码不长,但已经很接近真实办公自动化脚本了。
它做到了:
自动读表 自动算指标 自动汇总 自动生成结果 自动加基础样式
很多办公室里的小工具,本质上就是这样一步步长出来的。
二十二、处理 Excel 时,最容易踩的几个坑
1. 列名和你以为的不一样
有时表头有空格、换行、隐藏字符。 所以读取后最好先打印 df.columns 看一眼。
2. 数字列被读成字符串
这会导致加减乘除出问题。 必要时要做类型转换。
比如:
df["销量"] = pd.to_numeric(df["销量"], errors="coerce")
3. 表里混着合计行、小计行
直接参与统计会污染结果。 这种行通常要先过滤掉。
4. 文件很多,但格式不完全统一
这在批量合并时最常见。 要先统一字段,再拼接。
5. 只会处理数据,不会处理样式
结果表能算出来,但给别人看时不够正式。 所以后面要慢慢补 openpyxl 的表格美化能力。
6. 直接覆盖原文件
如果脚本还没完全稳定,建议先输出到新文件,别一上来就覆盖原始数据。
二十三、什么时候优先用 Pandas,什么时候优先用 openpyxl
这个判断很实用。
优先用 Pandas 的情况:
要做筛选、排序、分组、统计 要处理大量表格数据 要合并或拆分多个文件 要新增计算列 要做批量数据清洗
优先用 openpyxl 的情况:
要改单元格 要设样式 要处理模板 要调列宽、字体、颜色 要插入行列 要做更细的工作簿级操作
很多时候其实不是二选一,而是:
先 Pandas 后 openpyxl
这是最顺手的一条路。
二十四、这一章最该带走的核心思路
不要把“批量处理 Excel”理解成某几个孤立命令。 它本质上是一种办公自动化流程能力。
你面对 Excel 时,要慢慢形成这样的思路:
先判断任务是“数据处理”还是“表格编辑” 如果是数据处理,优先想到 Pandas 如果是表格细节,优先想到 openpyxl 如果两者都有,就分两步做 先让结果对,再让表好看
这个思路一旦建立起来,你以后做 Excel 自动化就不会老在工具选择上绕来绕去。
二十五、本章要点整理
批量处理 Excel 是办公自动化中最常见、最有价值的场景之一。 处理 Excel 时,Pandas 更适合做数据读取、筛选、统计、合并、拆分和导出。 openpyxl 更适合做工作簿、工作表、单元格和样式层面的细节操作。 常见实战需求包括批量合并多个 Excel、自动新增计算列、按条件筛选导出、按字段拆分多个文件、生成多工作表汇总表。 真实办公表格往往不够规整,处理前要先查看结构、列名、数据类型和空值情况。 自动化处理 Excel 时,建议先用 Pandas 解决数据问题,再用 openpyxl 处理展示问题。 很多办公脚本的核心价值,不在技术复杂,而在于把重复流程固定下来并可反复复用。