📅 2018年10月20日
告别加班:用 Python 自动化处理 Excel 报表的进阶实战(附源码)
如果你是一名财务、运营或者 HR,你是否经历过这样的绝望:每个月末,都要从十几个不同的系统里导出数据,然后手动复制粘贴到一张总表里,最后还要用 VLOOKUP 核对数据。
这种重复性的“体力活”不仅枯燥,而且极易出错。今天,我将带你用 Python 的 pandas 和 openpyxl 库,把这些需要 3 小时的工作压缩到 30 秒。
为什么选择 Python 而不是 VBA?
虽然 Excel 自带的 VBA 也能实现自动化,但 Python 有几个无法比拟的优势:
- 处理大数据量: VBA 在处理超过 10 万行数据时会卡死,而 Python 可以轻松处理百万级数据。
- 生态丰富: 你可以轻松对接数据库、API 甚至网页爬虫。
- 代码易维护: Python 的代码结构比 VBA 清晰得多,方便团队协作。
第一步:环境准备
首先,你需要安装以下库:
pip install pandas openpyxl xlsxwriter
第二步:实战案例——合并多个分公司的销售报表
假设你有一个文件夹 sales_data,里面存放着北京、上海、广州三个分公司每月的销售 Excel 文件。我们需要把它们合并成一张总表,并计算每个产品的总销售额。
1. 读取所有文件
我们使用 glob 模块来批量获取文件路径:
import pandas as pd
import glob
import os
# 获取文件夹下所有 .xlsx 文件
file_list = glob.glob('sales_data/*.xlsx')
all_data = []
for file in file_list:
# 读取每个文件,假设数据在第一个 Sheet
df = pd.read_excel(file, engine='openpyxl')
# 添加一列标记数据来源(哪个分公司)
df['source_file'] = os.path.basename(file)
all_data.append(df)
# 合并所有数据
combined_df = pd.concat(all_data, ignore_index=True)
2. 数据清洗与计算
原始数据往往很脏,比如日期格式不统一、有空值等。
# 删除完全为空的行
combined_df.dropna(how='all', inplace=True)
# 确保销售额是数字类型
combined_df['销售额'] = pd.to_numeric(combined_df['销售额'], errors='coerce')
# 计算每个产品的总销售额
summary = combined_df.groupby(['产品名称', 'source_file'])['销售额'].sum().reset_index()
3. 导出带格式的专业报表
仅仅导出数据是不够的,老板通常喜欢看带有颜色标记和汇总行的表格。这里我们用 xlsxwriter 引擎来美化输出。
output_file = '月度销售汇总.xlsx'
writer = pd.ExcelWriter(output_file, engine='xlsxwriter')
summary.to_excel(writer, index=False, sheet_name='汇总数据')
# 获取 workbook 和 worksheet 对象
workbook = writer.book
worksheet = writer.sheets['汇总数据']
# 定义格式
header_format = workbook.add_format({
'bold': True,
'text_wrap': True,
'valign': 'top',
'fg_color': '#D7E4BC',
'border': 1
})
# 应用表头格式
for col_num, value in enumerate(summary.columns.values):
worksheet.write(0, col_num, value, header_format)
# 自动调整列宽
worksheet.set_column('A:A', 20)
worksheet.set_column('B:B', 15)
worksheet.set_column('C:C', 15)
writer.close()
print(f"报表已生成:{output_file}")
进阶技巧:如何处理复杂的 VLOOKUP 逻辑?
在 Excel 中,我们常用 VLOOKUP 匹配信息。在 Python 中,这叫做 merge。
# 假设你还有一个产品单价表 product_prices.xlsx
prices_df = pd.read_excel('product_prices.xlsx')
# 将单价表合并到销售表中
final_df = pd.merge(combined_df, prices_df, on='产品名称', how='left')
# 计算利润
final_df['利润'] = final_df['销售额'] - (final_df['销售数量'] * final_df['成本价'])
避坑指南:新手常犯的错误
- 忽略数据类型: Excel 里的数字可能被识别成字符串,导致无法求和。务必使用
pd.to_numeric进行转换。 - 内存溢出: 如果文件非常大(几个 G),不要一次性
read_excel。可以考虑使用chunksize分块读取,或者改用polars库。 - 路径问题: 在 Windows 和 Mac 上,文件路径的分隔符不同。建议使用
os.path.join来处理路径,保证代码跨平台运行。
结语
自动化不是为了让你失业,而是为了让你从繁琐的复制粘贴中解放出来,去思考更有价值的数据洞察。
当你第一次运行脚本,看着屏幕在 1 秒钟内吐出那张你以前要做半天的表格时,那种成就感是无与伦比的。
📂 源码获取: 你可以在我的 GitHub 仓库找到完整的示例代码和数据模板。如果你在处理 Excel 时遇到了什么奇葩问题,欢迎在评论区提问!