在实际工作中,经常会遇到这样的场景:
- 📁 一个文件夹中有多个 Excel
- 👤 每个人员不完全一致
- 📊 需要汇总每个人的合计
- 🧾 同时保留每个文件的明细(用逗号隔开)
- ❗ 缺失月份自动补 0
本文分享一段 纯 Python + Pandas 的通用脚本
一、原始 Excel 结构说明
假设文件夹中有多个 Excel,如:
text
2024-01.xlsx
2024-02.xlsx
2024-03.xlsx
每个 Excel 结构类似:
- 第 3 行是表头
- 第 4 行开始是数据
| 姓名 | 数据1 | 数据2 | 数据3 |
|---|---|---|---|
| 张三 | 200 | 500 | 100 |
| 李四 | 150 | 0 | 80 |
⚠️ 注意:
- 有的月份 可能缺人
- 有的补贴列 可能不存在
- 空值、文本会被当作 0 处理
二、实现目标
最终生成一个汇总 Excel:
| 姓名 | 数据1合计 | 数据2合计 | 数据3合计 | 数据1明细 | 数据2明细 | 数据3明细 |
|---|---|---|---|---|---|---|
| 张三 | 600 | 1500 | 300 | 200,200,200 | 500,500,500 | 100,100,100 |
| 李四 | 300 | 800 | 160 | 150,150,0 | 300,500,0 | 80,80,0 |
✅ 每个人每个文件都有一条记录
✅ 不存在的自动补 0
三、核心思路
1️⃣ 把每个 Excel 当成一个"月份"
python
excel_files = sorted([
f for f in os.listdir(folder_path)
if f.endswith((".xlsx", ".xls"))
])
2️⃣ 用两个字典存数据
python
# 合计数据
sum_data = defaultdict(lambda: {
"数据1": 0,
"数据2": 0,
"数据3": 0
})
# 明细数据(按月份追加)
detail_data = defaultdict(lambda: {
"数据1": [],
"数据2": [],
"数据3": []
})
3️⃣ 逐月读取 + 自动补齐人员
关键逻辑:
python
# 本月出现的人
current_names = set(df["姓名"].tolist())
# 历史 + 本月所有人
all_names = set(sum_data.keys()) | current_names
对 所有人 都写入当月数据:
- 有数据 → 用真实值
- 没数据 → 自动补 0
python
value = df.loc[df["姓名"] == name, col].values[0] if name in current_names else 0
4️⃣ 明细用列表存,最后用逗号拼接
python
detail_data[name][col].append(str(int(value)))
最终:
python
",".join(detail_data[name]["数据1"])
四、完整代码(可直接运行)
python
import os
import pandas as pd
from collections import defaultdict
folder_path = r"C:\Users\75951\Desktop\合计"
name_col = "姓名"
subsidy_cols = ["数据1", "数据2", "数据3"]
excel_files = sorted([
f for f in os.listdir(folder_path)
if f.endswith((".xlsx", ".xls"))
])
sum_data = defaultdict(lambda: {c: 0 for c in subsidy_cols})
detail_data = defaultdict(lambda: {c: [] for c in subsidy_cols})
for file in excel_files:
df = pd.read_excel(os.path.join(folder_path, file), header=2)
if name_col not in df.columns:
df = pd.DataFrame(columns=[name_col] + subsidy_cols)
else:
df = df[[c for c in [name_col] + subsidy_cols if c in df.columns]]
df = df[df[name_col].notna()]
for c in subsidy_cols:
if c in df.columns:
df[c] = pd.to_numeric(df[c], errors="coerce").fillna(0)
current_names = set(df[name_col].tolist())
all_names = set(sum_data.keys()) | current_names
for name in all_names:
for col in subsidy_cols:
value = df.loc[df[name_col] == name, col].values[0] if name in current_names and col in df.columns else 0
sum_data[name][col] += value
detail_data[name][col].append(str(int(value)))
rows = []
for name in sorted(sum_data.keys()):
rows.append({
"姓名": name,
"数据1合计": sum_data[name]["数据1"],
"数据2合计": sum_data[name]["数据2"],
"数据3合计": sum_data[name]["数据3"],
"数据1明细": ",".join(detail_data[name]["数据1"]),
"数据2明细": ",".join(detail_data[name]["数据2"]),
"数据3明细": ",".join(detail_data[name]["数据3"]),
})
result = pd.DataFrame(rows)
output_path = os.path.join(folder_path, "output\\汇总_加明细.xlsx")
result.to_excel(output_path, index=False)
print("汇总完成:", output_path)
五、适用场景
- 月度 / 季度 / 年度统计
- Excel 自动化
- 人员不固定的数据合并
- 需要 "合计 + 明细" 的场景
六、总结
✅ 自动识别人员
✅ 自动补齐缺失月份
✅ 自动处理空值
✅ 一次输出合计 + 明细
非常适合 Excel 数量多、规则统一的统计场景。