如何使用openpyxl将pandas DataFrame写入Excel指定单元格
问题背景
- 从SQL查询读取得到4行5列的pandas DataFrame对象
output_total,读取代码为output_total = pd.read_sql_query(text(query), engine1) - 需求为将整表数据写入已打开的openpyxl工作表
ws_hi的指定起始位置(例如B10) - 此前使用
ws_hi["c31"].value = output_total.iloc[0]仅能写入单个单元格值,无法完成整表批量写入
实现方案
方案1:逐单元格遍历写入(兼容所有openpyxl版本)
通过定位起始行列坐标,先按需写入表头,再逐行逐列写入数据,逻辑直观易调整:
# 配置写入起始位置,例:B10对应行号10、列号2,可根据实际需求修改 start_row = 10 start_col = 2 # --- 如需写入DataFrame列名作为表头,保留以下代码,不需要可删除 --- for col_offset, col_name in enumerate(output_total.columns): ws_hi.cell( row=start_row, column=start_col + col_offset, value=col_name ) # 表头占1行,数据起始行顺延1位 data_start_row = start_row + 1 # --- 表头代码结束 --- # 写入表格数据 for row_offset, row_content in enumerate(output_total.values): for col_offset, cell_val in enumerate(row_content): ws_hi.cell( row=data_start_row + row_offset, column=start_col + col_offset, value=cell_val )
方案2:范围批量写入(执行效率更高)
将DataFrame转为嵌套列表结构,直接匹配Excel单元格范围一次性写入,代码更简洁,适合数据量稍大的场景:
from openpyxl.utils import get_column_letter # 配置写入起始位置 start_row = 10 start_col = 2 # 转换数据格式为嵌套列表,每个子列表对应一行数据 write_data = output_total.values.tolist() # --- 如需写入表头,取消下行注释即可 --- # write_data.insert(0, output_total.columns.tolist()) # 计算写入范围的结束行列坐标 row_count = len(write_data) col_count = len(write_data[0]) end_row = start_row + row_count - 1 end_col = start_col + col_count - 1 # 拼接单元格范围字符串,例:4行5列从B10开始对应范围为B10:F13 target_range = f"{get_column_letter(start_col)}{start_row}:{get_column_letter(end_col)}{end_row}" # 批量写入数据 ws_hi[target_range] = write_data
注意事项
- openpyxl的行、列序号均从1开始计数,和Excel原生的行列序号规则一致,配置起始位置时不要按0索引计算
- 所有写入操作完成后,必须调用工作簿对象的
save()方法保存文件,否则所有内存中的修改不会同步到本地文件 - 若写入数据包含日期、空值等特殊类型,可提前对DataFrame做格式转换,或写入后单独设置对应单元格的
number_format属性调整显示格式
内容的提问来源于stack exchange,提问作者crawling_panda
相关产品推荐
相关产品推荐

