在办公自动化场景中,批量重命名Excel工作表是高频需求。例如,月度销售报表中常出现“销售_1月”“销售_2月”这类命名,手动修改几十张工作表既耗时又容易遗漏。利用Python脚本可以高效解决此类问题,核心思路是:遍历工作簿的所有工作表,对每个工作表名称执行字符串替换。
本文以xlwings库为例(也可用openpyxl或pandas,思路相同),演示从基础实现到增强校验的完整方案。
- import xlwings as xw
- file_path = r"e:\file\demo.xlsx" # 替换为实际路径
- old_word = "销售"
- new_word = "" # 设置为空字符串表示删除该关键词
- app = xw.App(visible=False, add_book=False)
- try:
- wb = app.books.open(file_path)
- worksheets = wb.sheets
- for sht in worksheets:
- old_name = sht.name
- new_name = old_name.replace(old_word, new_word)
- if old_name != new_name:
- sht.name = new_name
- wb.save()
- wb.close()
- finally:
- app.quit()
复制代码
这段代码的核心逻辑是:获取所有工作表对象,依次读取原名称,用replace()替换后赋值给工作表name属性。保存并关闭工作簿即可完成批量处理。注意xlwings操作需显式创建App实例并设置visible=False以降低资源消耗。
如果只想修改部分工作表(例如只改第2到第5张或只改名称中包含“销售”的工作表),可以通过切片或条件判断实现:
- # 切片方式:只处理第2~5张工作表(对应索引1~4)
- for sht in worksheets[1:5]:
- sht.name = sht.name.replace("销售", "")
- # 条件判断方式:只处理名称包含“销售”的工作表
- for sht in worksheets:
- if "销售" in sht.name:
- sht.name = sht.name.replace("销售", "")
复制代码
切片方式依赖工作表位置;条件判断依赖名称规则,推荐后者,因为它不会受顺序变更影响。
批量重命名时容易踩坑:Excel限制工作表名称最多31个字符,不能包含 \ / : * ? [ ] 等字符,且必须唯一。直接执行替换可能导致重名或非法名称,脚本中途报错。
建议先在校验代码中加入函数检测新名称合法性:
- def is_valid_sheet_name(name):
- invalid_chars = ['\\', '/', ':', '*', '?', '[', ']']
- if not name:
- return False
- if len(name) > 31:
- return False
- for char in invalid_chars:
- if char in name:
- return False
- return True
复制代码
更稳妥的做法是先生成全部重命名计划,检查无重复名称后再执行修改:
- new_names = []
- for sht in worksheets:
- new_name = sht.name.replace(old_word, new_word)
- new_names.append(new_name)
- if len(new_names) != len(set(new_names)):
- raise ValueError("重命名后存在重复工作表名,请先检查规则。")
复制代码
以下是一个增强版脚本,整合名称校验、重复检测和日志输出,适合投入真实业务:
- import xlwings as xw
- file_path = r"e:\file\demo.xlsx"
- old_word = "销售"
- new_word = ""
- def is_valid_sheet_name(name):
- invalid_chars = ['\\', '/', ':', '*', '?', '[', ']']
- if not name:
- return False, "工作表名不能为空"
- if len(name) > 31:
- return False, "工作表名不能超过31个字符"
- for char in invalid_chars:
- if char in name:
- return False, f"工作表名不能包含非法字符:{char}"
- return True, "校验通过"
- app = xw.App(visible=False, add_book=False)
- try:
- wb = app.books.open(file_path)
- worksheets = wb.sheets
- rename_plan = []
- for sht in worksheets:
- old_name = sht.name
- new_name = old_name.replace(old_word, new_word)
- valid, message = is_valid_sheet_name(new_name)
- if not valid:
- raise ValueError(f"{old_name} -> {new_name} 校验失败:{message}")
- rename_plan.append((old_name, new_name))
-
- new_names = [item[1] for item in rename_plan]
- if len(new_names) != len(set(new_names)):
- raise ValueError("重命名后存在重复工作表名,请调整替换规则。")
-
- for old_name, new_name in rename_plan:
- if old_name != new_name:
- print(f"重命名:{old_name} -> {new_name}")
- wb.sheets[old_name].name = new_name
- wb.save()
- wb.close()
- finally:
- app.quit()
复制代码
这个版本采用“先预演再执行”的原则:先将所有旧名称和新名称收集到列表中,逐一校验合法性,并检查整体是否有重复;全部通过后才真正修改工作表名称。运行过程中打印每次修改的日志,便于事后回溯。
实践建议:在处理重要文件前务必备份;若不确定替换规则,可先不执行wb.save(),仅打印重命名计划,确认无误后再保存。这种思维同样适用于批量修改单元格内容、合并多个工作簿等场景——将重复任务抽象为“对象+循环+规则”,脚本就能稳定可靠地运行。 |