导出带多级列头的Pandas DataFrame到Excel时如何避免单元格合并
解决Pandas多级索引DataFrame导出Excel时保留未合并三级列头的问题
核心思路
直接使用df.to_excel的merge_cells=False会扁平化多级索引,而通过openpyxl手动写入表头并设置格式,既能保留三级列头结构,又能让上层索引在每列重复显示,同时维持表头的加粗居中样式。
操作步骤及代码示例
1. 准备示例多级索引DataFrame
import pandas as pd import numpy as np # 构建三级列索引(年份、月份、日期) columns = pd.MultiIndex.from_tuples( [("2024", "1", "2"), ("2024", "1", "3"), ("2024", "1", "4")], names=["年份", "月份", "日期"] ) # 创建带行索引的示例数据 df = pd.DataFrame( np.random.randint(0, 100, (5, 3)), columns=columns, index=[f"行{i+1}" for i in range(5)] )
2. 手动写入Excel并设置格式
from openpyxl import Workbook from openpyxl.styles import Font, Alignment from openpyxl.utils.dataframe import dataframe_to_rows # 初始化工作簿和工作表 wb = Workbook() ws = wb.active # 写入数据部分(从第4行开始,预留3行作为三级表头) data_rows = dataframe_to_rows(df, index=True, header=False) for row_idx, row in enumerate(data_rows, start=4): ws.append(row) # 逐层级写入三级表头,确保上层索引每列重复显示 # 第一级:年份 for col in range(2, len(df.columns)+2): # 第1列为行索引,从第2列开始写入列头 ws.cell(row=1, column=col, value=df.columns[col-2][0]) # 第二级:月份 for col in range(2, len(df.columns)+2): ws.cell(row=2, column=col, value=df.columns[col-2][1]) # 第三级:日期 for col in range(2, len(df.columns)+2): ws.cell(row=3, column=col, value=df.columns[col-2][2]) # 设置表头格式:加粗、居中对齐 header_font = Font(bold=True) header_align = Alignment(horizontal="center", vertical="center") # 应用格式到所有表头单元格(包括行索引的表头) for row_num in range(1, 4): for col_num in range(1, len(df.columns)+2): cell = ws.cell(row=row_num, column=col_num) cell.font = header_font cell.alignment = header_align # 自动调整列宽(可选优化) for col in ws.columns: max_len = 0 col_letter = col[0].column_letter for cell in col: try: if len(str(cell.value)) > max_len: max_len = len(str(cell.value)) except: pass ws.column_dimensions[col_letter].width = max_len + 2 # 保存文件 wb.save("output.xlsx")
效果说明
- 三级列头完整保留,第一级"2024"在每列单独显示,无单元格合并
- 所有表头(包括行索引的表头)均为加粗居中格式
- 数据部分与表头对应,结构清晰
内容的提问来源于stack exchange,提问作者Josep Gregori
相关产品推荐
相关产品推荐

