如何使用openpyxl修改Excel工作表名称且不丢失图表引用
问题解决办法
根因说明
openpyxl修改工作表名称时,不会自动同步更新工作簿内所有依赖工作表名的引用对象,包括图表数据源、单元格公式、自定义名称等。这些对象内仍然存储旧的Sheet1/Sheet2等名称,Excel无法匹配到当前工作表,就会判定为无效的外部链接,图表也无法读取到正确数据,不需要重新生成图表就能解决。
代码优化与修复
首先你原有代码存在逻辑问题:range(1, len(Sheet_names))会跳过列表第一个元素"A",导致Sheet1没有完成改名,先修正该问题,再增加图表数据源批量替换的逻辑,完整代码如下:
import openpyxl # 配置项 Sheet_names = ("A","B","C","D") file_path = "file_name.xlsx" # 旧sheet名前缀,根据实际情况调整 old_sheet_prefix = "Sheet" # 加载工作簿,keep_links=True避免误清有效链接 wb = openpyxl.load_workbook(file_path, keep_links=True) # 存储新旧名称映射,后面替换用 name_map = {} for idx in range(len(Sheet_names)): old_name = f"{old_sheet_prefix}{idx+1}" new_name = Sheet_names[idx] # 改工作表名 wb[old_name].title = new_name name_map[old_name] = new_name # 遍历所有工作表的所有图表,替换数据源引用 for ws in wb.worksheets: for chart in ws._charts: # 处理系列的数据源引用 for ser in chart.series: for old_name, new_name in name_map.items(): if old_name in str(ser.ref): ser.ref = str(ser.ref).replace(old_name, new_name) if old_name in str(ser.title): ser.title = str(ser.title).replace(old_name, new_name) # 处理分类轴的数据源引用 if hasattr(chart, 'cat') and chart.cat is not None: for old_name, new_name in name_map.items(): if old_name in str(chart.cat.ref): chart.cat.ref = str(chart.cat.ref).replace(old_name, new_name) # 保存关闭 wb.save(file_path) wb.close()
额外注意事项
- 如果工作簿内还有大量引用旧工作表名的单元格公式,可以再加一段遍历所有工作表单元格、替换公式内旧工作表名的逻辑,避免出现公式引用错误
- 如果存在自定义名称管理器的引用,也需要遍历
wb.defined_names做对应替换
内容的提问来源于stack exchange,提问作者Livmkie
相关产品推荐
相关产品推荐

