Python自動(dòng)化拆分Excel工作表的實(shí)戰(zhàn)教學(xué)
1. 問題背景:為什么要把一個(gè)總表拆成多個(gè)工作簿
本文主題是 按條件將一個(gè)工作表拆分為多個(gè)工作簿。這個(gè)案例在辦公自動(dòng)化里非常實(shí)用,因?yàn)楹芏鄷r(shí)候我們拿到的是一張“總表”,但實(shí)際分發(fā)時(shí)需要按產(chǎn)品、地區(qū)、門店、人員等字段拆成多份文件。
手工處理時(shí),常見流程是先篩選,再復(fù)制,再新建工作簿,再粘貼,再保存。數(shù)據(jù)量少的時(shí)候還能忍,分類一多就很浪費(fèi)時(shí)間。更麻煩的是,人工操作容易漏篩、漏復(fù)制、保存錯(cuò)文件名,最后還要反復(fù)返工。
這張圖展示的是本文的核心目標(biāo):用 Python + Excel 自動(dòng)化,把一個(gè)總表按分類條件拆分成多個(gè)獨(dú)立工作簿。

從圖中可以看出,左側(cè)是一份完整的 總表.xlsx,右側(cè)根據(jù)“類別”拆出了 背包.xlsx、行李箱.xlsx、錢包.xlsx 等多個(gè)工作簿。這個(gè)過程的本質(zhì)不是簡單復(fù)制文件,而是先識別每一行屬于哪一類,再把同類數(shù)據(jù)分別寫入對應(yīng)的新工作簿。
原理說明:這類自動(dòng)化任務(wù)的關(guān)鍵不在 Excel 表格本身,而在“分類規(guī)則”。只要分類字段確定,后面的處理就可以交給程序循環(huán)完成。
2. 場景說明:哪些業(yè)務(wù)適合按條件拆分
這個(gè)案例適合處理“同一張表,需要分發(fā)給不同對象”的場景。比如銷售總表按產(chǎn)品拆分給產(chǎn)品負(fù)責(zé)人,門店數(shù)據(jù)按門店拆分給店長,區(qū)域業(yè)績按地區(qū)拆分給區(qū)域經(jīng)理,員工績效按人員拆分給個(gè)人或主管。
這張圖展示的是按不同字段分發(fā)數(shù)據(jù)的典型應(yīng)用場景。

從圖中能看出,同一張銷售總表可以按照不同維度拆分:按產(chǎn)品輸出 背包.xlsx,按地區(qū)輸出 華北.xlsx,按門店輸出 門店A.xlsx,按人員輸出 張三.xlsx。這說明拆分邏輯并不局限于“產(chǎn)品名稱”,只要是表格中的某一列,都可以作為拆分條件。
推薦做法:實(shí)際工作中不要一上來就寫死“按產(chǎn)品拆分”,而是先確認(rèn)業(yè)務(wù)真正要按哪一列拆分。字段選錯(cuò)了,腳本跑得再快也沒有意義。
我認(rèn)為這類需求最適合用 Python 處理,因?yàn)樗腥齻€(gè)明顯優(yōu)勢:第一,批量生成文件穩(wěn)定;第二,文件命名規(guī)則清晰;第三,后續(xù)可以繼續(xù)加日志、校驗(yàn)、異常處理,沉淀成可復(fù)用的小工具。
3. 核心原理:用字典完成分類分組
這節(jié)真正要吃透的是 dict()。如果只看代碼,很容易覺得這只是一個(gè)普通字典;但放到 Excel 拆分場景里看,字典就是“分類容器”。它負(fù)責(zé)把同一個(gè)類別的數(shù)據(jù)行集中放到一起。
這張圖展示的是字典分類的核心思路:key 是分類值,value 是該分類下的數(shù)據(jù)列表。

從圖中可以看出,源數(shù)據(jù)表中的每一行都會(huì)根據(jù)“類別”字段流向?qū)?yīng)的分組。例如“背包”相關(guān)的行會(huì)進(jìn)入 data["背包"],行李箱相關(guān)的行會(huì)進(jìn)入 data["行李箱"],錢包相關(guān)的行會(huì)進(jìn)入 data["錢包"]。
最終字典結(jié)構(gòu)大致是這樣的:
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 決定寫入該文件的數(shù)據(jù)內(nèi)容。理解這一點(diǎn),就能看懂后面的 for key, value in data.items() 為什么可以逐類生成工作簿。
風(fēng)險(xiǎn)提醒:分類字段不能隨便選。如果字段里有空值、錯(cuò)別字、多余空格,比如“背包”和“背包 ”,程序會(huì)把它們當(dāng)成兩個(gè)不同分類,最終生成的文件也會(huì)被拆散。
4. 操作流程:讀取、分組、輸出、保存
在寫代碼之前,先把流程畫清楚。這個(gè)案例的穩(wěn)定寫法不是邊讀邊保存,而是先讀取總表,再分組,最后按分組結(jié)果批量輸出。這樣邏輯更清楚,也更方便排錯(cuò)。
這張圖展示的是完整的執(zhí)行流程:讀取總表、按類別分組、新建工作簿、保存文件。

從圖中能看出,這個(gè)案例不是單步操作,而是一條完整的數(shù)據(jù)處理鏈路。先從 總表.xlsx 讀取數(shù)據(jù),再通過 data = dict() 完成分類,接著為每個(gè)分類新建一個(gè)工作簿,最后保存為對應(yīng)的 Excel 文件。
推薦做法:如果你是第一次寫這種腳本,建議先把流程跑通,不要急著做復(fù)雜封裝。先能正確拆出文件,再考慮日志、界面、異常處理。
5. 完整代碼:按分類字段拆分為多個(gè)工作簿
下面這段代碼使用 xlwings 讀取源工作簿,并按指定列拆分為多個(gè)新工作簿。這里假設(shè)按第 1 列進(jìn)行分類,實(shí)際使用時(shí)可以根據(jù)自己的表結(jié)構(gòu)修改 group_col_index。
import os
import re
import xlwings as xw
def safe_filename(name):
"""
將分類值轉(zhuǎn)換成合法文件名,避免 Windows 文件名非法字符導(dǎo)致保存失敗
"""
name = str(name).strip()
name = re.sub(r'[\\/:*?"<>|]', "_", name)
return name if name else "未分類"
# ====== 需要根據(jù)實(shí)際情況修改的參數(shù) ======
source_file = r"e:\file\總表.xlsx"
source_sheet = "Sheet1"
output_dir = r"e:\file\拆分結(jié)果"
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]
# 讀取連續(xù)表格區(qū)域,包含表頭
table = sht.range("A1").expand("table").value
if not table or len(table) < 2:
raise ValueError("源表數(shù)據(jù)為空,或只有表頭,沒有可拆分的數(shù)據(jù)行。")
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},行數(shù):{len(value)}")
wb.close()
finally:
app.quit()
這段代碼比最基礎(chǔ)版本多做了兩件事:第一,用 safe_filename() 處理非法文件名;第二,對空分類值做了兜底處理,避免分類字段為空時(shí)直接報(bào)錯(cuò)。
注意:Excel 工作表名稱最長不能超過 31 個(gè)字符,所以這里使用 safe_filename(key)[:31] 做了截?cái)唷H绻惶幚?,分類值太長時(shí)可能導(dǎo)致工作表改名失敗。
原理說明:new_sht.range("A1").value = [header] + value 這句非常關(guān)鍵。它不是只寫數(shù)據(jù)行,而是把表頭也一起寫進(jìn)去。否則拆出來的文件雖然有數(shù)據(jù),但缺少字段名,后續(xù)閱讀和二次處理都會(huì)不方便。
6. 關(guān)鍵代碼理解:不要只會(huì)復(fù)制
這段代碼里最值得重點(diǎn)理解的是三處:一是 data = dict(),二是 data[key].append(row),三是 for key, value in data.items()。
data = dict() 是創(chuàng)建一個(gè)空字典,用來存放分類結(jié)果。每遇到一個(gè)新的分類值,就在字典里新增一個(gè)鍵;如果這個(gè)分類已經(jīng)存在,就把當(dāng)前行追加到對應(yīng)列表中。
if key not in data:
data[key] = []
data[key].append(row)
這兩句代碼可以理解成:如果還沒有這個(gè)分類,就先創(chuàng)建一個(gè)空文件夾;如果已經(jīng)有了,就把這一行數(shù)據(jù)放進(jìn)去。雖然實(shí)際結(jié)構(gòu)不是文件夾,但思路很像。
for key, value in data.items() 是輸出階段的核心。key 用來生成文件名,value 是該分類下所有數(shù)據(jù)行。每循環(huán)一次,就生成一個(gè)新的 Excel 工作簿。
for key, value in data.items():
file_name = safe_filename(key) + ".xlsx"
out_path = os.path.join(output_dir, file_name)
推薦做法:學(xué)習(xí)這類腳本時(shí),不要一開始就盯著所有代碼看。先抓主線:數(shù)據(jù)從哪里來,按什么分組,最終輸出到哪里。主線清楚了,細(xì)節(jié)才有意義。
7. 常見問題:拆分前必須先檢查
按條件拆分工作表,真正容易翻車的地方往往不是語法,而是數(shù)據(jù)本身。字段為空、分類值不統(tǒng)一、文件名包含非法字符、輸出目錄不存在、生成結(jié)果沒有核對,這些問題都會(huì)影響最終交付。
這張圖展示的是拆分工作表前需要重點(diǎn)關(guān)注的幾個(gè)檢查點(diǎn)。

從圖中可以看出,拆分前至少要檢查四件事:關(guān)鍵字段不能為空,輸出目錄要提前創(chuàng)建,文件名要合法,結(jié)果要核對。尤其是文件名問題,在 Windows 下不能包含 \ / : * ? " < > | 等字符,否則保存文件時(shí)會(huì)失敗。
坑 1:分類字段為空。如果某些行的分類字段為空,腳本可能跳過這些行,也可能把它們歸到“未分類”。具體選擇要看業(yè)務(wù)要求,不能隨便處理。
坑 2:分類值表面相同,實(shí)際不同。比如“華北”和“華北 ”,后者多了一個(gè)空格。肉眼看起來差不多,但程序會(huì)認(rèn)為它們是兩個(gè)不同的分類。所以代碼里最好使用 strip() 清理前后空格。
坑 3:輸出文件名重復(fù)。如果多個(gè)分類值清洗后變成相同文件名,就可能覆蓋或保存失敗。嚴(yán)格場景下應(yīng)該在文件名后追加編號,避免沖突。
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
推薦做法:正式輸出前先統(tǒng)計(jì)每個(gè)分類的行數(shù)。比如背包多少行、行李箱多少行、錢包多少行。這樣能提前發(fā)現(xiàn)“某一類數(shù)據(jù)異常偏少”或“分類值寫錯(cuò)導(dǎo)致拆分異常”的問題。
8. 效果驗(yàn)證:拆出來不等于拆對了
腳本運(yùn)行完以后,不要只看控制臺有沒有報(bào)錯(cuò)。對這種批量拆分任務(wù)來說,真正要確認(rèn)的是結(jié)果是否完整、分類是否正確、文件是否能正常打開。
我一般會(huì)從三個(gè)角度檢查。第一,檢查輸出文件數(shù)量是否等于分類數(shù)量。比如總表里有 3 個(gè)產(chǎn)品分類,輸出目錄里就應(yīng)該有 3 個(gè)工作簿。第二,抽查每個(gè)工作簿里的分類列,確認(rèn)里面沒有混入其他分類。第三,核對總行數(shù),所有輸出文件的數(shù)據(jù)行加起來,應(yīng)該等于源表數(shù)據(jù)行數(shù)。
total_output_rows = 0
for key, value in data.items():
print(f"{key}:{len(value)} 行")
total_output_rows += len(value)
print(f"源數(shù)據(jù)行數(shù):{len(rows)}")
print(f"輸出數(shù)據(jù)行數(shù)合計(jì):{total_output_rows}")
原理說明:拆分驗(yàn)證的核心是“守恒”。如果只是按條件拆分,而沒有刪除數(shù)據(jù),那么輸出文件中的總數(shù)據(jù)行數(shù)應(yīng)該和源表數(shù)據(jù)行數(shù)一致。只要行數(shù)對不上,就必須回頭查分類字段、空值處理和過濾邏輯。
不要犯的錯(cuò)誤:看到輸出目錄里生成了幾個(gè) Excel 文件,就以為任務(wù)完成了。文件生成只是第一步,拆分正確才是交付標(biāo)準(zhǔn)。
9. 總結(jié)提升:把它變成自己的辦公自動(dòng)化模板
這一節(jié)看似只是“把一個(gè)工作表拆分為多個(gè)工作簿”,但背后其實(shí)是一個(gè)非常通用的數(shù)據(jù)處理模型:讀取總數(shù)據(jù)、按字段分組、逐組輸出結(jié)果。這個(gè)模型以后可以繼續(xù)擴(kuò)展到銷售數(shù)據(jù)分發(fā)、資產(chǎn)清單拆分、人員績效拆分、門店報(bào)表拆分等場景。
我認(rèn)為這節(jié)最值得掌握的不是某一行代碼,而是三種判斷能力。
第一,先判斷拆分字段是否可靠。字段不可靠,后面的自動(dòng)化都是放大錯(cuò)誤。
第二,輸出前先做清洗和校驗(yàn)。分類值去空格、文件名合法化、輸出目錄創(chuàng)建,這些都是批量處理的基本安全動(dòng)作。
第三,結(jié)果必須核對。自動(dòng)化不是腳本跑完就結(jié)束,而是要確認(rèn)輸出結(jié)果能交付、能復(fù)查、能復(fù)用。
如果后續(xù)把這段代碼繼續(xù)封裝,可以加上圖形界面,讓用戶選擇源文件、選擇拆分字段、選擇輸出目錄,再一鍵生成多個(gè)工作簿。這樣它就不只是讀書筆記,而是一個(gè)真正能用于辦公現(xiàn)場的小工具。
到此這篇關(guān)于Python自動(dòng)化拆分Excel工作表的實(shí)戰(zhàn)教學(xué)的文章就介紹到這了,更多相關(guān)Python拆分Excel工作表內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Python實(shí)現(xiàn)精準(zhǔn)拆分Excel文件大表數(shù)據(jù)功能
- 使用Python合并與拆分Excel單元格的實(shí)用方法
- Python辦公之實(shí)現(xiàn)批量拆分Excel
- Python實(shí)現(xiàn)Excel拆分和合并的優(yōu)化版本
- 基于Python實(shí)現(xiàn)excel拆分和合并工具并打包
- 使用Python實(shí)現(xiàn)Excel文件的拆分與合并操作
- Python實(shí)現(xiàn)凍結(jié)、取消凍結(jié)和拆分Excel窗格
- 基于Python編寫文件拆分工具(兼容Excel&csv)
- 使用Python拆分與合并Excel文檔的操作指南
相關(guān)文章
使用Python創(chuàng)建一個(gè)視頻管理器并實(shí)現(xiàn)視頻截圖功能
在這篇博客中,我將向大家展示如何使用 wxPython 創(chuàng)建一個(gè)簡單的圖形用戶界面 (GUI) 應(yīng)用程序,該應(yīng)用程序可以管理視頻文件列表、播放視頻,并生成視頻截圖,我們將逐步實(shí)現(xiàn)這些功能,并確保代碼易于理解和擴(kuò)展,感興趣的小伙伴跟著小編一起來看看吧2024-08-08
詳解Python如何在Web環(huán)境中使用Matplotlib進(jìn)行數(shù)據(jù)可視化
數(shù)據(jù)可視化是數(shù)據(jù)科學(xué)和分析中一個(gè)至關(guān)重要的部分,它能幫助我們更好地理解和解釋數(shù)據(jù),在現(xiàn)代應(yīng)用中,越來越多的開發(fā)者希望能夠?qū)?shù)據(jù)可視化結(jié)果展示在網(wǎng)頁上,本文將介紹如何在 Web 環(huán)境中使用 Matplotlib 進(jìn)行可視化,包括基本概念、集成方式以及實(shí)用示例2024-11-11
Python監(jiān)控主機(jī)是否存活并以郵件報(bào)警
本文是利用python腳本寫的簡單測試主機(jī)是否存活,此腳本有個(gè)缺點(diǎn)不適用線上,由于網(wǎng)絡(luò)延遲、丟包現(xiàn)象會(huì)造成誤報(bào)郵件,感興趣的朋友一起看看Python監(jiān)控主機(jī)是否存活并以郵件報(bào)警吧2015-09-09
Python函數(shù)調(diào)用追蹤實(shí)現(xiàn)代碼
這篇文章主要介紹了Python函數(shù)調(diào)用追蹤實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11
python入門課程第一講之安裝與優(yōu)缺點(diǎn)介紹
這篇文章主要介紹了python入門課程第一講之安裝與優(yōu)缺點(diǎn),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09
Pycharm打印大數(shù)據(jù)文件顯示不全的解決方法
這篇文章主要介紹了Pycharm打印大數(shù)據(jù)文件顯示不全的解決方法,昨晚寫了個(gè)小爬蟲,簡單分析下發(fā)現(xiàn)可以修改請求的url,直接獲取所有目標(biāo)的數(shù)據(jù),想先打印在控制臺看看,發(fā)現(xiàn)打印的數(shù)據(jù)不全,所以本文記錄了一下解決方法,需要的朋友可以參考下2024-03-03

