ARTICLE · 1002626
Python 办公:一个 Excel 按部门拆成 100 个文件
Python 办公:一个 Excel 按部门拆成 100 个文件
Python 办公:一个 Excel 按部门拆成 100 个文件
总部一张总表 3 万行,要按「部门」拆成 100 份发给各分公司。
手动筛选另存?100 次复制粘贴,一下午没了。用 pandas,30 秒。

一、思路
1. 读总表。 2. 按拆分列(比如「部门」)做 groupby。3. 每个分组 to_excel写成独立文件。4. 文件名用分组值,注意清理非法字符。
二、核心代码
import pandas as pd
import re
df = pd.read_excel("总表.xlsx")
col = "部门"
# 文件名非法字符清洗
defsafe(name):
return re.sub(r'[\\/:*?"<>|]', "_", str(name))
os.makedirs("拆分结果", exist_ok=True)
for name, sub in df.groupby(col, sort=False):
path = f"拆分结果/{safe(name)}.xlsx"
sub.to_excel(path, index=False)
print(f"{name} -> {len(sub)} 行")
print("完成,共拆出", df[col].nunique(), "个文件")三、常见坑
• 非法文件名:部门名里带 /*会直接报错,必须清洗(见上)。• 空值分组: groupby默认丢弃 NaN,导致少一个文件。要保留就先df[col] = df[col].fillna("未填写")。• 拆出的表样式丢失: to_excel只写数据不写格式,要保留模板样式得用openpyxl往模板里塞。• 文件太多太慢:上万个小文件建议先按首字母归到子文件夹。
四、进阶:每个部门单独发邮件版
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
mail_map = pd.read_excel("部门邮箱.xlsx").set_index("部门")["邮箱"].to_dict()
# 拆完直接附带附件发送,见第 05 篇《定时自动发邮件报表》五、进阶:按行数拆(每 500 行一个文件)
for i, chunk inenumerate(range(0, len(df), 500), 1):
df.iloc[chunk:chunk+500].to_excel(f"拆分结果/part_{i:03d}.xlsx", index=False)小结
拆分是合并的逆操作,记住一句 groupby(col) + 循环 to_excel 就够用 80% 的场景。剩下的 20% 是文件名清洗和空值处理。