除openpyxl外,如何更快编辑含多模板的XLSM文件?
解决OpenPyXL加载大型XLSM文件过慢的问题
嘿,我完全懂你现在的困扰——用openpyxl处理那种4-5MB、带4-5个模板的XLSM文件时,加载速度慢到让人跺脚,而且你还不想折腾新建文件那一套,就想直接修改原文件对吧?下面给你几个实用的解决方案:
方案1:微调OpenPyXL的加载参数(小幅提速)
OpenPyXL默认会加载工作簿里的所有内容,包括公式、外部链接这些你可能不需要的东西,调整几个参数能帮你省点时间:
- 如果你的模板里不需要保留公式,只需要单元格的实际值,可以加上
data_only=True;如果工作簿里没有外部链接,再加上keep_links=False,这能减少OpenPyXL需要解析的内容:file = 'excel.xlsm' wb = openpyxl.load_workbook( filename=file, read_only=False, keep_vba=True, data_only=True, keep_links=False ) # 后续你的编辑代码不变 sheet = wb['Template'] rowx = ['x','y','z'] rows = sheet.max_row for j in range(len(rowx)): sheet.cell(row=rows+1, column=j+1).value = rowx[j] wb.save(file) - 注意:如果你的模板依赖公式计算,
data_only=True就不能用了,这个优化也就失效了。
方案2:用Xlwings直接操作Excel进程(强烈推荐)
如果OpenPyXL的速度实在没法忍,Xlwings绝对是更好的选择——它直接调用你本地的Excel应用程序来修改文件,根本不需要把整个工作簿加载到内存里,速度快一大截,而且完美支持XLSM的宏和模板,还能直接修改原文件:
示例代码:
import xlwings as xw file = 'excel.xlsm' # 后台打开Excel文件,visible=False表示不显示Excel窗口 with xw.Book(file) as wb: sheet = wb.sheets['Template'] rowx = ['x','y','z'] # 获取最后一行的行号(跟Excel里的Ctrl+↑逻辑一样) last_row = sheet.range(f"A{sheet.cells.last_cell.row}").end('up').row + 1 # 写入新数据 for idx, val in enumerate(rowx): sheet.range(last_row, idx+1).value = val # with块结束后会自动保存并关闭Excel
这个方法的优势简直戳中你的需求:
- 完全不用加载整个工作簿,大文件处理速度比OpenPyXL快N倍
- 完美保留原文件的VBA宏和所有格式
- 直接修改原文件,不需要新建副本折腾
方案3:OpenPyXL读写分离模式(备选)
如果你不想用第三方库,也可以用OpenPyXL的只读模式读取原文件内容,再用写入模式生成新文件覆盖原文件——虽然本质是新建后覆盖,但也算能达到修改原文件的效果:
# 只读模式读取原文件 wb_read = openpyxl.load_workbook(file, read_only=True, keep_vba=True) sheet_read = wb_read['Template'] # 创建写入模式的工作簿,复制原文件的VBA宏 wb_write = openpyxl.Workbook(write_only=True) wb_write.vba_archive = wb_read.vba_archive # 保留VBA # 复制原工作表的所有内容 sheet_write = wb_write.create_sheet('Template') for row in sheet_read.iter_rows(values_only=True): sheet_write.append(row) # 添加新数据 rowx = ['x','y','z'] sheet_write.append(rowx) # 覆盖原文件 wb_write.save(file)
不过这个方法需要处理VBA的复制,而且还是要生成新文件,不如Xlwings来得直接。
总的来说,如果你追求速度和省心,Xlwings是最优解;如果只想用OpenPyXL,微调加载参数能帮你小幅提速,但对大型文件的效果有限。
内容的提问来源于stack exchange,提问作者Sai Ram
相关产品推荐
相关产品推荐

