在日常办公中,经常需要批量修正多个Excel文件中的固定错误行数据,比如部门名称变更、产品名称写错、负责人调整等。手动修改几十个工作簿不仅效率低,还容易遗漏。本文介绍如何使用Python的xlwings库,配合enumerate()精确定位行号,实现批量替换多个工作簿中的整行数据。
一、适用场景与风险提示
整行替换适合“确定性很强”的修正任务,例如多个文件中都存在同一旧记录(如[“北京”,“销售”,“张三”,1000]),需要统一替换为新记录(如[“北京”,“销售事业部”,“张三”,1200])。如果只是单列名称变更,优先考虑按列替换。注意:整行替换会覆盖多个字段,必须确保匹配条件足够准确,否则容易误改。
二、核心原理:enumerate()定位行号+精确匹配
程序流程:遍历指定文件夹中的所有Excel工作簿 → 读取指定工作表的数据区域(A1.current_region) → 去掉表头后逐行匹配 → 如果整行与旧行完全一致,则用新行替换。关键代码:- for idx, row in enumerate(rows, start=2):
- if row == old_row:
- sht.range(f"A{idx}").value = new_row
复制代码 这里rows是去掉表头(table[1:])后的数据行列表。使用enumerate(..., start=2)使Python索引与Excel真实行号对齐(Excel第1行为表头,数据从第2行开始)。row == old_row是精确匹配,空格、数字类型(如1000 vs 1000.0)都会导致匹配失败,因此正式处理前需确认源数据格式。
三、完整代码实现
以下脚本使用xlwings,需要先安装:pip install xlwings。注意替换folder_path、sheet_name、old_row和new_row。- import os
- import xlwings as xw
- folder_path = r"e:\file\target"
- sheet_name = "Sheet1"
- old_row = ["北京", "销售", "张三", 1000]
- new_row = ["北京", "销售事业部", "张三", 1200]
- app = xw.App(visible=False, add_book=False)
- try:
- for file_name in os.listdir(folder_path):
- if file_name.startswith("~$"):
- continue
- if not file_name.lower().endswith((".xlsx", ".xls", ".xlsm")):
- continue
- full_path = os.path.join(folder_path, file_name)
- wb = app.books.open(full_path)
- try:
- sheet_names = [s.name for s in wb.sheets]
- if sheet_name not in sheet_names:
- print(f"跳过:{file_name},不存在工作表 {sheet_name}")
- continue
- sht = wb.sheets[sheet_name]
- table_rng = sht.range("A1").current_region
- table = table_rng.value
- if not table or len(table) < 2:
- print(f"跳过:{file_name},没有可处理的数据")
- continue
- rows = table[1:]
- hit_count = 0
- for idx, row in enumerate(rows, start=2):
- if row == old_row:
- sht.range(f"A{idx}").value = new_row
- hit_count += 1
- if hit_count > 0:
- wb.save()
- print(f"已替换:{file_name},命中 {hit_count} 行")
- else:
- print(f"未命中:{file_name}")
- finally:
- wb.close()
- finally:
- app.quit()
复制代码 代码中增加了hit_count统计每个文件命中的行数。写入新行时使用sht.range(f"A{idx}").value = new_row,需要确认new_row字段数量与原表列数一致,否则可能残留旧数据或写到表格外。
四、关键细节与常见坑
1. 必须跳过~$临时文件。
2. 先检查目标工作表是否存在,否则报错。
3. 行匹配是精确比较,如果Excel中数字读取为浮点数(如1000.0),而old_row写的是整数1000,则匹配失败。建议先打印rows查看真实数据格式。
4. 正式替换前先运行“预览模式”:只打印命中的文件名、行号和旧行内容,不执行写入和保存。确认无误后再放开保存。
五、效果验证与安全建议
不要仅凭控制台输出“已替换”就认为成功。建议做三类验证:
- 检查命中数量是否符合预期(例如总共应命中6行)。
- 随机打开几个目标文件,确认旧行已变成新行。
- 确认文件可以正常打开无损坏。
建议在副本目录中先测试,不要直接在原始文件夹运行。
六、总结提升
本文的核心价值不是记enumerate(),而是理解“遍历文件→定位行号→精确匹配→替换保存”的完整流程。可复用经验:
- 精确匹配适合确定性修正,格式混乱时需先清洗。
- 批量脚本必须有命中统计,方便复盘。
- 保存处理日志(文件名、行号、旧数据、新数据),便于追溯。
在此基础上可以扩展为带界面的小工具,或增加日志记录功能,从脚本走向可交付工具。 |