乐于分享
好东西不私藏

领导扔给我300个Excel让我下班前合并完,我用10行代码搞定了

领导扔给我300个Excel让我下班前合并完,我用10行代码搞定了

周五下午四点,领导丢过来一个文件夹:「这里面是各个分公司的销售报表,你帮我合并到一个表里,下班前给我。」打开一看——300 多个 Excel 文件,每个里面四五个 sheet。如果一个个打开复制粘贴,周末肯定没了。最后我用几行 Python 代码十分钟搞定。今天把这段代码分享出来,下次你遇到类似的活直接拿去用。

那天下午四点十分,我点开那个文件夹数了一下。317 个文件。其中大概十几个文件后缀还不一样——有的是.xls,有的是.xlsx,有的是.csv。文件名也没有统一规范:「深圳分公司-销售报表(修订版).xlsx」「北京-销售数据-最终版.csv」「上海-别删-这是最新的.xls」。

我不知道你看到这种文件命名方式什么感受。我看到「修订版」「最终版」「别删这是最新的」同时出现在一个文件夹里的时候,血压已经上来了。

领导在钉钉上又弹了一条消息:「尽量下班前给我。」

我回:「好。」

然后关掉钉钉,打开终端。

第零步:先把环境搭好

如果你电脑上还没有 Python,去 python.org 下载安装。安装的时候注意勾选「Add Python to PATH」——这步漏了后面命令会报错。

装好之后打开终端(Windows 按 Win+R 输入 cmd,Mac 打开「终端」),装两个库:

pip install pandas openpyxl

看到 Successfully installed 就说明装好了。

然后把领导给你的那一堆 Excel 文件全部扔到一个文件夹里。比如在桌面新建一个叫 excel_work 的文件夹,把所有文件拖进去。等会在代码里把路径指到这个文件夹就行。

第一步:先把所有文件的路径拿到手

Python 有个内置模块叫glob,专门干这个。一行代码就能把一个文件夹里所有 Excel 文件的路径列出来。

import globfiles = glob.glob(「销售报表/*.xls*」)print(f「找到 {len(files)} 个文件」)

它会输出:找到 317 个文件。比你手动数快 317 倍。

第二步:全部读进来,拼成一个大表

pandas库里有个函数叫read_excel,读一个文件。你把 317 个文件路径全丢给它,它一个个读完拼到一起。

import pandas as pdall_data = []for f in files:    df = pd.read_excel(f)    all_data.append(df)result = pd.concat(all_data, ignore_index=True)print(f「合并完成,共 {len(result)} 行」)

第一次跑这三行代码的时候,我盯着屏幕看了大概五秒。317 个文件,合并完大概 3 万多行,花了不到十秒。如果手动干,打开第一个文件的时间都不止十秒。

但事情没这么简单。跑完第一遍发现报错了。

有些文件里面的表头不一样——深圳分公司用的是「销售额」,北京用的是「销售金额」,上海那家直接写了英文「Revenue」。表头不统一,拼出来的表一列变三列。

第三步:统一表头再合并

这就需要在读每个文件的时候先检查一下列名,不一样的就统一。

import pandas as pdimport globfiles = glob.glob(「销售报表/*.xls*」)all_data = []for f in files:    df = pd.read_excel(f)    # 统一列名:不管原文件叫什么,全改成标准名称    df.columns = df.columns.str.replace(「销售额|销售金额|Revenue」, 「销售额」, regex=True)    all_data.append(df)result = pd.concat(all_data, ignore_index=True)result.to_excel(「合并完成.xlsx」, index=False)print(f「合并完成,共 {len(result)} 行,已保存」)

第四步:有些文件不是 Excel 格式

还有几个.csv文件藏在里面。read_excel读不了 csv,得用read_csv

改一下,先判断文件后缀:

for f in files:    if f.endswith('.csv'):        df = pd.read_csv(f)    else:        df = pd.read_excel(f)    df.columns = df.columns.str.replace(「销售额|销售金额|Revenue」, 「销售额」, regex=True)    all_data.append(df)

完整代码

上面几步拼起来,就是最终的版本。我把它整理好放在这里,下次你遇到直接复制,改三个地方就行——文件夹路径、想要统一的列名、输出的文件名。

import pandas as pdimport glob# 1. 找到所有表格文件files = glob.glob(「你的文件夹路径/*.xls*」) + glob.glob(「你的文件夹路径/*.csv」)# 2. 逐个读取,统一列名,拼在一起all_data = []for f in files:    # 根据后缀选择读取方式    if f.endswith('.csv'):        df = pd.read_csv(f)    else:        df = pd.read_excel(f)    # 统一列名——把你要统一的列名映射写在这里    df.columns = df.columns.str.replace(「销售额|销售金额|Revenue」, 「销售额」, regex=True)    all_data.append(df)# 3. 合并 + 保存result = pd.concat(all_data, ignore_index=True)result.to_excel(「合并完成.xlsx」, index=False)print(f「搞定!共合并 {len(files)} 个文件,{len(result)} 行数据」)

不只合并——学会了这个模式,能干的活多了去了

怎么运行这段代码? 把上面的完整代码复制,打开记事本粘贴进去,保存为 merge_excel.py(注意后缀是 .py 不是 .txt)。然后把文件放到你的 excel_work 文件夹旁边,在终端里 cd 到那个目录,执行:

python merge_excel.py

看到「搞定!共合并 317 个文件,38241 行数据」就说明跑完了。

你掌握了「批量读取 → 处理 → 合并」这个模式之后,能干的活多了去了。举几个我自己用过的例子:

批量提取关键信息: 文件夹里一百多个合同 Excel,只要提取每个文件的「合同金额」和「签约日期」这两列。

for f in files:    df = pd.read_excel(f)    # 只取需要的两列    info = df[[「合同金额」, 「签约日期」]].iloc[0]    all_data.append(info)

批量筛选: 把每个分公司报表里「销售额超过 10 万」的行挑出来,单独存一个文件。

result = result[result[「销售额」] > 100000]

批量改格式: 把所有文件的日期列统一成同一个格式,把金额列全部保留两位小数。

df[「日期」] = pd.to_datetime(df[「日期」]).dt.strftime(「%Y-%m-%d」)df[「销售额」] = df[「销售额」].round(2)

那天下午四点四十,我把合并好的 Excel 发给了领导。

他回:「这么快?」

我说:「嗯,写了个脚本。」

他说:「好。」

他没问我写的什么脚本。我也没解释。但那天我五点半准时下班了。经过了楼下的柠檬茶店,要了一杯冰的。坐在店门口的椅子上,看了会儿天。周五下午五点半,天还没黑,风是凉的。在那一刻我觉得,会一点自动化真挺好的。

你被 Excel 折磨过吗?有没有什么自己摸索出来的骚操作?评论区教教大家。