使用Openpyxl复制源文件前100行并粘贴为值时公式单元格为空的解决方法
解决Openpyxl复制公式单元格为值的问题
首先,你代码里的data_only=True参数放错位置了——它应该是load_workbook()的参数,而不是range()的参数!这就是公式单元格复制后为空的核心原因。另外,我们可以简化你的代码逻辑,让复制过程更清晰直观。
核心问题解析
当你用data_only=True加载工作簿时,openpyxl会读取单元格上次保存时的公式计算结果,而不是公式本身。但如果你的源文件在修改公式后没有手动保存过(或者用其他程序保存时未触发公式计算),这些公式单元格的值就会是空的。如果是这种情况,你需要先确保源文件的公式已经完成计算并保存。
修正后的代码
from openpyxl import load_workbook, Workbook # 加载源工作簿时必须加上data_only=True,才能读取公式的计算值 wb_source = load_workbook("sample_book.xlsx", data_only=True) ws_source = wb_source["Ark2"] # 创建目标工作簿并设置工作表 wb_target = Workbook() # 删除默认生成的空工作表 wb_target.remove(wb_target.active) ws_target = wb_target.create_sheet("WS1") # 复制前100行数据(以值的形式) # 遍历源表的前100行(openpyxl的行号从1开始计数) for row in ws_source.iter_rows(min_row=1, max_row=100, values_only=True): # 将每行的数值直接追加到目标工作表 ws_target.append(row) # 保存目标工作簿 wb_target.save("WB2.xlsx")
关键改进点
- 正确放置data_only=True:把它放在
load_workbook()的参数列表中,确保程序读取的是单元格的计算值而非公式本身。 - 使用values_only=True:
iter_rows()加上这个参数后,可以直接获取整行的数值列表,无需再逐个遍历单元格取.value,代码更简洁高效。 - 简化复制逻辑:直接指定复制前100行,去掉了冗余的offset计算,让代码逻辑更易读维护。
额外注意事项
如果用了data_only=True还是读不到公式值,大概率是源文件的问题:
- 手动打开源文件
sample_book.xlsx,按Ctrl+S保存一次,确保公式的计算结果被写入文件。 - 如果你是用其他程序生成的源文件,要确认该程序保存时已经完成了所有公式的计算。
内容的提问来源于stack exchange,提问作者Christian




