夜雨聆风学习资料网

ARTICLE · 1126233

用 Python 自动处理 Excel:告别人工复制粘贴

用 Python 自动处理 Excel:告别人工复制粘贴

每个月底,你都要经历一次这种折磨

每个月 1 号早上,12 个 Excel 文件准时躺在你的邮箱里:销售_01月.xlsx、销售_02月.xlsx……一直到销售_12月.xlsx。每个文件结构一模一样,都是订单明细。你的工作是把它们合并成一张总表,按产品和地区汇总,再拆出华东区的明细给区域经理。

手工做这件事的流程你是知道的:打开第一个文件,复制,粘贴到总表;打开第二个,复制,滚动到底部,粘贴……十二个文件下来,一个多小时没了,还不能保证没粘错行。上个月你就把 3 月的数据粘进了 2 月的区域,被老板叫去聊了十分钟。

今天这篇,我们把这个流程写成一个 Python 脚本。以后每月 1 号,你只需要双击运行,10 秒钟后喝着咖啡等结果。而且脚本月月能跑,一次编写,永久受益。

先造 12 个假文件

为了让代码可以直接运行,我们先用 Python 造 12 个月度销售文件,存到一个文件夹里。真实场景中,这一步就是"把 12 个文件放进同一个文件夹":

import pandas as pd      import numpy as npimport osnp.random.seed(42)os.makedirs('月度数据', exist_ok=True) # 建一个文件夹放 Excelproducts = ['笔记本电脑', '无线鼠标', '机械键盘', '显示器', '扩展坞']regions = ['华东', '华北', '华南']for month in range(1, 13):    n = np.random.randint(40, 80)  # 每月订单数量不等,模拟真实情况    d = pd.DataFrame({        '订单号': [f'{month:02d}{i:04d}' for i in range(n)],        '产品': np.random.choice(products, n),        '地区': np.random.choice(regions, n),        '数量': np.random.randint(1, 10, n),        '单价': np.random.choice([5499, 129, 399, 1299, 259], n),        '销售员': np.random.choice(['张伟', '李娜', '王强', '刘芳'], n)    })    d['金额'] = d['数量'] * d['单价']    d.to_excel(f'月度数据/销售_{month:02d}月.xlsx', index=False)print('12 个文件已生成')

批量读取:glob 找文件,循环读进来

核心是三个工具的配合:glob 负责把文件夹里所有符合条件的文件找出来,read_excel 负责读,concat 负责拼:

import globimport os# 找到文件夹里所有以"销售_"开头的 Excel 文件files = glob.glob('月度数据/销售_*.xlsx')print(f'找到 {len(files)} 个文件')frames = []for f in files:    month = os.path.basename(f)[3:5]  # 从文件名"销售_01月.xlsx"里切出"01"    d = pd.read_excel(f)    d['月份'] = int(month)            # 加一列标记数据来自哪个月    frames.append(d)all_data = pd.concat(frames, ignore_index=True)print(all_data.shape)  # 大约 (690, 8):近 700 行明细合并完毕    

有两处细节值得留意。一是星号 * 是通配符,销售_*.xlsx 表示"销售_开头、任意内容结尾的 Excel 文件",以后新增月份不用改代码。二是我们顺手从文件名里提取了月份存进新的一列,不然合并完就分不清每行数据是哪个月的了。

汇总:老本行 groupby

合并完得到 all_data,接下来就是前几篇练熟的 groupby 和透视表:

# 按产品汇总总销量和总金额summary = all_data.groupby('产品').agg(    总数量=('数量', 'sum'),    总金额=('金额', 'sum')).sort_values('总金额', ascending=False)# 按月看销售趋势monthly = all_data.groupby('月份')['金额'].sum()# 地区 × 月份 的透视表region = all_data.pivot_table(    index='地区', columns='月份', values='金额', aggfunc='sum')print(summary) 

拆分:一行条件筛选

老板要华东区的明细?一行条件筛选的事:

east = all_data[all_data['地区'] == '华东']print(f'华东区共 {len(east)} 条订单')

要拆三个地区,循环一下就行,后面我们会把它们写进同一个文件的不同 sheet。

写回 Excel:一个文件,多个 sheet

最后一步,把汇总结果写回一个漂亮的 Excel,不同内容放不同 sheet。这需要 ExcelWriter:

with pd.ExcelWriter('年度汇总报告.xlsx', engine='openpyxl') as writer:    summary.to_excel(writer, sheet_name='产品汇总')    monthly.to_excel(writer, sheet_name='月度趋势')    region.to_excel(writer, sheet_name='地区透视')    east.to_excel(writer, sheet_name='华东明细', index=False)    

with 语句结束时会自动保存文件,不用担心忘记关闭。运行完打开"年度汇总报告.xlsx",你会看到 4 个 sheet:产品汇总、月度趋势、地区透视、华东明细,整整齐齐。

如果想给每个地区都出一个明细 sheet,把最后一行换成循环:

with pd.ExcelWriter('年度汇总报告_分地区.xlsx', engine='openpyxl') as writer:    summary.to_excel(writer, sheet_name='产品汇总')    for r in regions:        sub = all_data[all_data['地区'] == r]        sub.to_excel(writer, sheet_name=f'{r}明细', index=False)   

如果运行时提示缺少 openpyxl,在终端执行 pip install openpyxl 装一下就好,它是 pandas 读写新版 Excel 文件依赖的引擎。

这套脚本的价值在哪里

我们算笔账:手工合并 12 个文件,算上手滑返工,大约 80 分钟;这个脚本跑完大约 10 秒。更重要的是它不会累、不会粘错行,下个月把新文件丢进文件夹再跑一遍就行。你省下的不只是时间,还有"反复核对有没有粘错"的心力。

这就是编程对职场人的真实意义:不是写多么高大上的程序,而是把重复劳动压缩成一次运行。

小结

这一篇我们完整走了一个办公自动化流程:glob 批量找文件,循环 read_excel 逐个读取并用文件名补充月份信息,concat 合并成总表,groupby 和 pivot_table 汇总,条件筛选拆分,最后用 ExcelWriter 把结果写进一个多 sheet 的 Excel 报告。

小练习:在本篇脚本的基础上加一个 sheet,内容是"每个销售员的月度销售金额"透视表(行是销售员,列是月份)。提示:和"地区透视"的做法几乎一样,只是换个 index。

下一篇预告

数据处理完了,图也画好了,可老板真正想要的其实是一句话:"所以,结论是什么?"下一篇我们聊点技术之外的东西。第 16 篇《数据分析报告怎么写:从数字到结论》,教你怎么把一堆表格和图表,变成一份让老板愿意看、看得懂、能拍板的报告。


本篇完整代码已经打包好,关注公众号,后台回复关键词【代码】即可领取。觉得有用就点个关注,我们下一篇见!

相关学习资料