使用Python批量保存后Excel宏文件(.xlsm)损坏问题排查
问题原因及解决方案
核心问题
openpyxl原生不支持保留并保存Excel宏(VBA代码)。当你用load_workbook加载.xlsm文件时,它仅读取工作表中的单元格数据,并不会加载文件中的VBA项目(存储在vbaProject.bin中的宏代码)。直接调用wb.save()生成的.xlsm文件缺少宏相关的核心结构,因此会被Excel识别为损坏文件。
解决方案
根据你的需求,分两种场景处理:
场景1:不需要保留宏,仅复制工作表内容
如果目标文件不需要保留宏,可将保存格式改为.xlsx,修改代码如下:
from openpyxl import load_workbook wb = load_workbook('Collections/Collection Note - 001.xlsm') for x in range(2,25): newname = "%03d" % x wb.save(f'Collections/Collection Note - {newname}.xlsx')
但此方法生成的文件无法存储宏,仅适合纯数据复制场景。
场景2:需要完整保留宏(推荐)
直接用文件复制的方式批量生成带宏的文件,这是最可靠的方案。使用Python内置的shutil库复制源文件并重命名,完整保留所有文件结构(包括宏):
import shutil import os source_file = 'Collections/Collection Note - 001.xlsm' target_dir = 'Collections' for x in range(2, 25): new_filename = f'Collection Note - {x:03d}.xlsm' target_path = os.path.join(target_dir, new_filename) shutil.copy2(source_file, target_path)
shutil.copy2会保留源文件的元数据(如创建时间、权限),比简单的copy更适合文件复制场景。
可选复杂方案:用openpyxl保留宏
若必须用openpyxl修改内容同时保留宏,需加载时指定keep_vba=True,但此方法存在兼容性风险,仅作参考:
from openpyxl import load_workbook # 加载时保留VBA项目 wb = load_workbook('Collections/Collection Note - 001.xlsm', keep_vba=True) ws = wb.active # 在这里做你的数据修改操作 for x in range(2,25): newname = "%03d" % x wb.save(f'Collections/Collection Note - {newname}.xlsm')
注意:此方法仅能保留原有宏,无法新增或修改宏代码,且部分复杂宏仍可能导致文件异常,优先推荐文件复制方案。
内容的提问来源于stack exchange,提问作者Geographos
相关产品推荐
相关产品推荐

