Python借助openpyxl自动填充Excel公式时死循环如何排查
Bug原因分析
代码运行卡顿、近似无限循环是3个逻辑错误共同导致的:
- 嵌套循环冗余:外层遍历行号的循环里,套了一层遍历全部公式的内层循环,每一行都会被重复写入整份公式列表的所有内容。如果数据有1000行,实际会执行近百万次单元格赋值操作,运算量被放大了数百倍。
- 保存逻辑错误:你将
workbook.save()放在了最内层循环中,每修改一个单元格就会执行一次全文件写入磁盘的操作,IO开销极高,这是运行速度极慢的核心诱因。 - 写入结果错误:内层循环会反复覆盖同一个单元格的内容,最终所有行的D列只会留下公式列表里最后一条公式,完全达不到逐行匹配填充的效果。
修正后代码
去掉冗余的列表预生成、嵌套循环,将保存操作移到所有写入完成后执行即可:
from openpyxl import load_workbook import pandas as pd file_source = r'C:\Users\user\Desktop\BB\Data.xlsx' # 获取数据总行数 row_len = len(pd.read_excel(file_source, sheet_name='new_sheet', usecols=['iso2'])) # 加载工作簿与目标工作表 workbook = load_workbook(filename=file_source) ws4 = workbook["new_sheet"] # 逐行写入对应公式,默认第1行为表头,数据从第2行开始 for row_idx in range(2, row_len + 1): ws4.cell(row=row_idx, column=4).value = f'=VLOOKUP(A{row_idx},old_sheet!A:G,7,0)+200/C{row_idx}' # 所有写入完成后仅保存一次 workbook.save(filename=file_source)
可选优化
如果不想额外用pandas读取文件计算行数,可以直接用openpyxl自带的属性获取工作表最大行,减少一次文件读取开销:
# 替换原来读取pandas计算row_len的逻辑 workbook = load_workbook(filename=file_source) ws4 = workbook["new_sheet"] row_len = ws4.max_row
内容的提问来源于stack exchange,提问作者CanaryTheBird
相关产品推荐
相关产品推荐

