夜雨聆风学习资料网

ARTICLE · 1087110

Python语法日报 第13期|Excel自动化开篇——批量处理多个Excel

Python语法日报 第13期|Excel自动化开篇——批量处理多个Excel

上期整完了多sheet,这回来硬的——文件夹里躺几十个Excel,一个一个人工打开复制粘贴?那得干到猴年马月去。今天用代码全给它薅出来,揉成一张总表,完事儿泡杯茶等着就行。

一、先看家伙事儿:os模块

Python自带的os,专门跟文件夹和文件打交道。今天主要用俩功能:

os.listdir(文件夹):列出文件夹里所有文件名

os.path.join(文件夹, 文件名):把路径拼完整

import osfolder = r'F:\Desktop\部门报表'# 装Excel的文件夹files = os.listdir(folder)print(files)

跑一下,文件夹里所有文件名都列出来了。但这里面啥都有,图片、txt、快捷方式,得筛一下,只要xlsx。

二、筛出Excel文件

excel_files = [f for f in os.listdir(folder) if f.endswith('.xlsx')]print(f'找到{len(excel_files)}个Excel')

就这一行,把xlsx全薅出来。xls的老古董不认,要处理先另存为xlsx。

三、循环读取,堆到一张总表

假设每个Excel结构一样:第一行表头,第二行开始是数据。咱搞个总表,再加一列“来源文件”,以后查账知道哪行是从哪个文件来的。

from openpyxl import load_workbook, Workbookimport osfolder = r'F:\Desktop\部门报表'excel_files = [f for f in os.listdir(folder) if f.endswith('.xlsx')]# 搞个新工作簿装结果wb_out = Workbook()ws_out = wb_out.activews_out.title = '总表'# 先写表头,比原表多一列“来源文件”ws_out.append(['姓名', '部门', '工资', '来源文件'])for file in excel_files:    file_path = os.path.join(folder, file)print(f'正在处理:{file}')    wb_in = load_workbook(file_path)    ws_in = wb_in.active# 从第二行开始读,跳过表头for row in ws_in.iter_rows(min_row=2, values_only=True):        name, dept, salary = row        ws_out.append([name, dept, salary, file])wb_out.save(os.path.join(folder, '汇总结果.xlsx'))print('全干完了,收工')

四、踩过的坑

坑1:文件夹里混着临时文件

Excel打开的时候会生成~$开头的临时文件,也被.xlsx筛出来了,一读就报错。

excel_files = [f for f in os.listdir(folder) if f.endswith('.xlsx') and not f.startswith('~$')]
坑2:表头列数不一样

有的表三列,有的表五列。name, dept, salary = row 直接崩。稳妥写法是判断长度:

for row in ws_in.iter_rows(min_row=2, values_only=True):if len(row) >= 3:        name, dept, salary = row[0], row[1], row[2]        ws_out.append([name, dept, salary, file])
坑3:sheet名不统一

有的文件sheet叫“Sheet1”,有的叫“数据”。用wb.active拿默认激活的那个,一般没错。如果激活的不是你要的,得按名字取:

ws_in = wb_in['数据']   # 按名字
坑4:空文件

有的文件是空的,一读就报错。加个try包一下:

try:    wb_in = load_workbook(file_path)# 干活except Exception as e:print(f'{file}翻车了,跳过:{e}')continue

五、进阶:合并后按部门分类

汇总完想按部门拆成不同sheet,也简单:

from collections import defaultdict# 按部门分组dept_data = defaultdict(list)for row in ws_out.iter_rows(min_row=2, values_only=True):    name, dept, salary, source = row    dept_data[dept].append([name, salary, source])# 每个部门建一个sheetfor dept, rows in dept_data.items():    ws_new = wb_out.create_sheet(dept)    ws_new.append(['姓名', '工资', '来源'])for r in rows:        ws_new.append(r)wb_out.save(os.path.join(folder, '汇总_分类.xlsx'))

defaultdict是字典的升级版,key不存在自动建个空列表,省得判断。

六、今儿个知识点打包

干啥
代码

列文件夹

os.listdir(文件夹)

拼路径

os.path.join(文件夹, 文件名)

筛xlsx

[f for f in files if f.endswith('.xlsx')]

排除临时文件

and not f.startswith('~$')

循环读多个文件

for file in excel_files:

按部门分组

defaultdict(list)

已更Excel系列:

第9期:库的选择与第一个读写

第10期:行列操作与遍历

第11期:单元格样式与公式

第12期:多sheet处理

后台回复 001 ,直接拿Python全套学习资料、办公脚本、实战代码,拿走就能用。

相关学习资料