Python自动化拆分Excel工作表的实战教学
1. 问题背景:为什么要把一个总表拆成多个工作簿
本文主题是 按条件将一个工作表拆分为多个工作簿。这个案例在办公自动化里非常实用,因为很多时候我们拿到的是一张“总表”,但实际分发时需要按产品、地区、门店、人员等字段拆成多份文件。
手工处理时,常见流程是先筛选,再复制,再新建工作簿,再粘贴,再保存。数据量少的时候还能忍,分类一多就很浪费时间。更麻烦的是,人工操作容易漏筛、漏复制、保存错文件名,最后还要反复返工。
这张图展示的是本文的核心目标:用 Python + Excel 自动化,把一个总表按分类条件拆分成多个独立工作簿。

从图中可以看出,左侧是一份完整的 总表.xlsx,右侧根据“类别”拆出了 背包.xlsx、行李箱.xlsx、钱包.xlsx 等多个工作簿。这个过程的本质不是简单复制文件,而是先识别每一行属于哪一类,再把同类数据分别写入对应的新工作簿。
原理说明:这类自动化任务的关键不在 Excel 表格本身,而在“分类规则”。只要分类字段确定,后面的处理就可以交给程序循环完成。
2. 场景说明:哪些业务适合按条件拆分
这个案例适合处理“同一张表,需要分发给不同对象”的场景。比如销售总表按产品拆分给产品负责人,门店数据按门店拆分给店长,区域业绩按地区拆分给区域经理,员工绩效按人员拆分给个人或主管。
这张图展示的是按不同字段分发数据的典型应用场景。

从图中能看出,同一张销售总表可以按照不同维度拆分:按产品输出 背包.xlsx,按地区输出 华北.xlsx,按门店输出 门店A.xlsx,按人员输出 张三.xlsx。这说明拆分逻辑并不局限于“产品名称”,只要是表格中的某一列,都可以作为拆分条件。
推荐做法:实际工作中不要一上来就写死“按产品拆分”,而是先确认业务真正要按哪一列拆分。字段选错了,脚本跑得再快也没有意义。
我认为这类需求最适合用 Python 处理,因为它有三个明显优势:第一,批量生成文件稳定;第二,文件命名规则清晰;第三,后续可以继续加日志、校验、异常处理,沉淀成可复用的小工具。
3. 核心原理:用字典完成分类分组
这节真正要吃透的是 dict()。如果只看代码,很容易觉得这只是一个普通字典;但放到 Excel 拆分场景里看,字典就是“分类容器”。它负责把同一个类别的数据行集中放到一起。
这张图展示的是字典分类的核心思路:key 是分类值,value 是该分类下的数据列表。

从图中可以看出,源数据表中的每一行都会根据“类别”字段流向对应的分组。例如“背包”相关的行会进入 data["背包"],行李箱相关的行会进入 data["行李箱"],钱包相关的行会进入 data["钱包"]。
最终字典结构大致是这样的:
data = {
"背包": [
["双肩包", "背包", 10, 129, 1290],
["登山包", "背包", 5, 199, 995],
["单肩包", "背包", 7, 89, 623]
],
"行李箱": [
["拉杆箱", "行李箱", 8, 299, 2392],
["旅行箱", "行李箱", 6, 399, 2394]
],
"钱包": [
["钱包A", "钱包", 20, 59, 1180],
["钱包B", "钱包", 15, 69, 1035]
]
}
原理说明:key 决定输出文件名,value 决定写入该文件的数据内容。理解这一点,就能看懂后面的 for key, value in data.items() 为什么可以逐类生成工作簿。
风险提醒:分类字段不能随便选。如果字段里有空值、错别字、多余空格,比如“背包”和“背包 ”,程序会把它们当成两个不同分类,最终生成的文件也会被拆散。
4. 操作流程:读取、分组、输出、保存
在写代码之前,先把流程画清楚。这个案例的稳定写法不是边读边保存,而是先读取总表,再分组,最后按分组结果批量输出。这样逻辑更清楚,也更方便排错。
这张图展示的是完整的执行流程:读取总表、按类别分组、新建工作簿、保存文件。

从图中能看出,这个案例不是单步操作,而是一条完整的数据处理链路。先从 总表.xlsx 读取数据,再通过 data = dict() 完成分类,接着为每个分类新建一个工作簿,最后保存为对应的 Excel 文件。
推荐做法:如果你是第一次写这种脚本,建议先把流程跑通,不要急着做复杂封装。先能正确拆出文件,再考虑日志、界面、异常处理。
5. 完整代码:按分类字段拆分为多个工作簿
下面这段代码使用 xlwings 读取源工作簿,并按指定列拆分为多个新工作簿。这里假设按第 1 列进行分类,实际使用时可以根据自己的表结构修改 group_col_index。
import os
import re
import xlwings as xw
def safe_filename(name):
"""
将分类值转换成合法文件名,避免 Windows 文件名非法字符导致保存失败
"""
name = str(name).strip()
name = re.sub(r'[\\/:*?"<>|]', "_", name)
return name if name else "未分类"
# ====== 需要根据实际情况修改的参数 ======
source_file = r"e:\file\总表.xlsx"
source_sheet = "Sheet1"
output_dir = r"e:\file\拆分结果"
group_col_index = 1 # 按哪一列拆分:0 表示 A 列,1 表示 B 列
# =====================================
os.makedirs(output_dir, exist_ok=True)
app = xw.App(visible=False, add_book=False)
try:
wb = app.books.open(source_file)
sht = wb.sheets[source_sheet]
# 读取连续表格区域,包含表头
table = sht.range("A1").expand("table").value
if not table or len(table) < 2:
raise ValueError("源表数据为空,或只有表头,没有可拆分的数据行。")
header = table[0]
rows = table[1:]
data = dict()
for row in rows:
key = row[group_col_index]
if key is None or str(key).strip() == "":
key = "未分类"
key = str(key).strip()
if key not in data:
data[key] = []
data[key].append(row)
for key, value in data.items():
file_name = safe_filename(key) + ".xlsx"
out_path = os.path.join(output_dir, file_name)
new_wb = app.books.add()
new_sht = new_wb.sheets[0]
new_sht.name = safe_filename(key)[:31]
new_sht.range("A1").value = [header] + value
new_wb.save(out_path)
new_wb.close()
print(f"已生成:{out_path},行数:{len(value)}")
wb.close()
finally:
app.quit()
这段代码比最基础版本多做了两件事:第一,用 safe_filename() 处理非法文件名;第二,对空分类值做了兜底处理,避免分类字段为空时直接报错。
注意:Excel 工作表名称最长不能超过 31 个字符,所以这里使用 safe_filename(key)[:31] 做了截断。如果不处理,分类值太长时可能导致工作表改名失败。
原理说明:new_sht.range("A1").value = [header] + value 这句非常关键。它不是只写数据行,而是把表头也一起写进去。否则拆出来的文件虽然有数据,但缺少字段名,后续阅读和二次处理都会不方便。
6. 关键代码理解:不要只会复制
这段代码里最值得重点理解的是三处:一是 data = dict(),二是 data[key].append(row),三是 for key, value in data.items()。
data = dict() 是创建一个空字典,用来存放分类结果。每遇到一个新的分类值,就在字典里新增一个键;如果这个分类已经存在,就把当前行追加到对应列表中。
if key not in data:
data[key] = []
data[key].append(row)
这两句代码可以理解成:如果还没有这个分类,就先创建一个空文件夹;如果已经有了,就把这一行数据放进去。虽然实际结构不是文件夹,但思路很像。
for key, value in data.items() 是输出阶段的核心。key 用来生成文件名,value 是该分类下所有数据行。每循环一次,就生成一个新的 Excel 工作簿。
for key, value in data.items():
file_name = safe_filename(key) + ".xlsx"
out_path = os.path.join(output_dir, file_name)
推荐做法:学习这类脚本时,不要一开始就盯着所有代码看。先抓主线:数据从哪里来,按什么分组,最终输出到哪里。主线清楚了,细节才有意义。
7. 常见问题:拆分前必须先检查
按条件拆分工作表,真正容易翻车的地方往往不是语法,而是数据本身。字段为空、分类值不统一、文件名包含非法字符、输出目录不存在、生成结果没有核对,这些问题都会影响最终交付。
这张图展示的是拆分工作表前需要重点关注的几个检查点。

从图中可以看出,拆分前至少要检查四件事:关键字段不能为空,输出目录要提前创建,文件名要合法,结果要核对。尤其是文件名问题,在 Windows 下不能包含 \ / : * ? " < > | 等字符,否则保存文件时会失败。
坑 1:分类字段为空。如果某些行的分类字段为空,脚本可能跳过这些行,也可能把它们归到“未分类”。具体选择要看业务要求,不能随便处理。
坑 2:分类值表面相同,实际不同。比如“华北”和“华北 ”,后者多了一个空格。肉眼看起来差不多,但程序会认为它们是两个不同的分类。所以代码里最好使用 strip() 清理前后空格。
坑 3:输出文件名重复。如果多个分类值清洗后变成相同文件名,就可能覆盖或保存失败。严格场景下应该在文件名后追加编号,避免冲突。
def get_unique_path(folder, filename):
base, ext = os.path.splitext(filename)
path = os.path.join(folder, filename)
index = 1
while os.path.exists(path):
path = os.path.join(folder, f"{base}_{index}{ext}")
index += 1
return path
推荐做法:正式输出前先统计每个分类的行数。比如背包多少行、行李箱多少行、钱包多少行。这样能提前发现“某一类数据异常偏少”或“分类值写错导致拆分异常”的问题。
8. 效果验证:拆出来不等于拆对了
脚本运行完以后,不要只看控制台有没有报错。对这种批量拆分任务来说,真正要确认的是结果是否完整、分类是否正确、文件是否能正常打开。
我一般会从三个角度检查。第一,检查输出文件数量是否等于分类数量。比如总表里有 3 个产品分类,输出目录里就应该有 3 个工作簿。第二,抽查每个工作簿里的分类列,确认里面没有混入其他分类。第三,核对总行数,所有输出文件的数据行加起来,应该等于源表数据行数。
total_output_rows = 0
for key, value in data.items():
print(f"{key}:{len(value)} 行")
total_output_rows += len(value)
print(f"源数据行数:{len(rows)}")
print(f"输出数据行数合计:{total_output_rows}")
原理说明:拆分验证的核心是“守恒”。如果只是按条件拆分,而没有删除数据,那么输出文件中的总数据行数应该和源表数据行数一致。只要行数对不上,就必须回头查分类字段、空值处理和过滤逻辑。
不要犯的错误:看到输出目录里生成了几个 Excel 文件,就以为任务完成了。文件生成只是第一步,拆分正确才是交付标准。
9. 总结提升:把它变成自己的办公自动化模板
这一节看似只是“把一个工作表拆分为多个工作簿”,但背后其实是一个非常通用的数据处理模型:读取总数据、按字段分组、逐组输出结果。这个模型以后可以继续扩展到销售数据分发、资产清单拆分、人员绩效拆分、门店报表拆分等场景。
我认为这节最值得掌握的不是某一行代码,而是三种判断能力。
第一,先判断拆分字段是否可靠。字段不可靠,后面的自动化都是放大错误。
第二,输出前先做清洗和校验。分类值去空格、文件名合法化、输出目录创建,这些都是批量处理的基本安全动作。
第三,结果必须核对。自动化不是脚本跑完就结束,而是要确认输出结果能交付、能复查、能复用。
如果后续把这段代码继续封装,可以加上图形界面,让用户选择源文件、选择拆分字段、选择输出目录,再一键生成多个工作簿。这样它就不只是读书笔记,而是一个真正能用于办公现场的小工具。
到此这篇关于Python自动化拆分Excel工作表的实战教学的文章就介绍到这了,更多相关Python拆分Excel工作表内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
详解Python如何在Web环境中使用Matplotlib进行数据可视化
数据可视化是数据科学和分析中一个至关重要的部分,它能帮助我们更好地理解和解释数据,在现代应用中,越来越多的开发者希望能够将数据可视化结果展示在网页上,本文将介绍如何在 Web 环境中使用 Matplotlib 进行可视化,包括基本概念、集成方式以及实用示例2024-11-11


最新评论