
Polars 的 write_excel 默认不支持为不同列头单独设置旋转角度,但可通过分段写入 + xlsxwriter 底层控制实现:将 DataFrame 拆分为两部分,分别写入同一工作表的连续区域,并只为后半部分指定 header_format={"rotation": 90}。
polars 的 `write_excel` 默认不支持为不同列头单独设置旋转角度,但可通过分段写入 + `xlsxwriter` 底层控制实现:将 dataframe 拆分为两部分,分别写入同一工作表的连续区域,并只为后半部分指定 `header_format={"rotation": 90}`。
在使用 Polars 导出 Excel 时,header_format 参数(如 {"rotation": 90})作用于整个表头行,无法按列精细化控制。若需仅旋转最后三列的标题(例如用于节省横向空间或突出关键指标),标准 API 无直接支持,但可借助 xlsxwriter 的底层能力,通过「分段写入 + 精确定位」达成目标。
核心思路是:
- 将原始 DataFrame 拆分为两个子集:前 N−3 列(
df1)和后 3 列(df2); - 使用
xlsxwriter.Workbook创建工作簿对象,避免重复初始化; - 先调用
df1.write_excel(...)写入起始位置(默认 A1); - 再计算
df2的起始列坐标(如前 2 列 → 第 3 列即'C'),构造position字符串(格式为"列行",如"C1"); - 调用
df2.write_excel(..., position="C1", header_format={"rotation": 90})写入剩余列,仅对其表头应用旋转。
以下是完整可运行示例:
import polars as pl
import xlsxwriter
df = pl.DataFrame({
'A long name': [1, 2, 3],
'Be my guest': [4, 5, 6],
'Come in and find out': ['a', 'b', 'c'],
'Dont stop me now': ['d', 'e', 'f'],
'Easy stuff only': ['g', 'h', 'i'],
})
# 拆分:保留前 len-3 列,提取后 3 列
n = len(df.columns)
df1 = df.select(df.columns[:n-3])
df2 = df.select(df.columns[n-3:])
# 计算 df2 起始列(Excel 列字母),从 A=1 开始;例如前 2 列 → 第 3 列 = 'C'
start_col_idx = n - 3 + 1 # 1-based 列索引
position_df2 = chr(64 + start_col_idx) + "1" # 64+'A'=65 → chr(65)='A'
with xlsxwriter.Workbook('rotated_headers.xlsx') as workbook:
df1.write_excel(workbook=workbook, worksheet="Sheet1")
df2.write_excel(
workbook=workbook,
worksheet="Sheet1",
header_format={"rotation": 90},
position=position_df2
)
✅ 注意事项:
-
position必须是字符串格式(如"C1"),不可传入整数坐标; -
df1和df2必须写入同一 worksheet,否则无法构成连续表头; - 所有样式(如字体、边框)需在各自
write_excel调用中独立配置,df1不会继承df2的header_format; - 若需合并单元格、添加冻结窗格等高级功能,建议直接使用
xlsxwriter原生 API 配合df.to_numpy()或df.rows()手动写入。
该方案虽需额外拆分逻辑,但完全兼容 Polars 生态,无需导出为 Pandas,也无需临时文件——是当前实现「选择性表头旋转」最简洁、可控的工程实践。











