使用 openpyxl 写入 Excel 时出现“空行”或“数据偏移”的完整解决方案

Python3.10

Python3.10

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

关键词:openpyxl、Excel 写入空行、数据偏移、merge_cells、current_row 不同步


🧩 一、问题描述

在使用 Python 的 openpyxl 模块向 Excel 表格写入数据时,出现了以下问题:

  • 表头与第一行数据之间多了一个空行
  • 某些数据本应写入第 2 行,实际却出现在第 3 行
  • 合并单元格后,表格整体内容下移

这些问题导致最终生成的 Excel 文件格式错乱、样式不对齐、数据偏移,影响后续使用。


🔍 二、问题原因分析

1. merge_cells() 使用顺序错误

你原本的逻辑是:

start_row = current_row
end_row = current_row + len(group) - 1
self.merge_and_fill_cell(ws, start_row, end_row, chinese_param_category)

for _, row in group.iterrows():
    ws.append([None] + row.tolist())
    current_row += 1

错误点:先调用 merge_cells(),再写入数据

虽然 merge_cells() 本身不会插入空行,但在没有实际数据时就合并单元格,某些 Excel 渲染器(如 Microsoft Excel)会自动插入空行来保持结构美观,导致数据下移。

正确做法:先写入数据,再执行 merge_cells()


2. 手动维护 current_row 与实际行号不同步

你使用了:

current_row = 2
...
current_row += 1

ws.append() 本身就会自动新增一行。你又手动维护了 current_row,导致:

  • start_row 和 end_row 的计算出现偏差
  • 最终合并区域与实际数据不一致

推荐做法:使用 ws.max_row 自动管理行号


3. 原始数据中存在空行或 NaN 值

row.tolist() 中,某些行可能包含:

[None] + [nan, nan, nan, ...]

这会导致写入 [None, nan, nan, nan, ...],看起来像一个“空行”。

解决方案:写入前过滤空行

if any(pd.notna(x) for x in row):
    ws.append([None] + row.tolist())

✅ 三、最终解决方案

✅ 修改后的写入逻辑(推荐使用)

for param_category, group in grouped:
    # 先写入数据
    for _, row in group.iterrows():
        if any(pd.notna(x) for x in row):  # 跳过空行
            ws.append([None] + row.tolist())

    # 获取实际写入的行号范围
    end_row = ws.max_row
    start_row = end_row - len(group) + 1
    chinese_param_category = self.param_category_mapping.get(param_category, param_category)

    # 再合并单元格
    self.merge_and_fill_cell(ws, start_row, end_row, chinese_param_category)
    self.apply_borders(ws, start_row, end_row)

🧪 四、推荐加入的打印语句(调试用)

print(f"📌 合并单元格: A{start_row}:A{end_row} → 内容: {chinese_param_category}")
print(f"📝 写入行数据 (第 {ws.max_row + 1} 行): {[None] + row.tolist()}")
print(f"📊 当前总行数: {ws.max_row}")

📌 五、merge_and_fill_cell 函数说明

def merge_and_fill_cell(self, ws: Any, start_row: int, end_row: int, value: str) -> None:
    ws.merge_cells(start_row=start_row, start_column=1, end_row=end_row, end_column=1)
    cell = ws.cell(row=start_row, column=1, value=value)
    cell.alignment = Alignment(horizontal="center", vertical="center")
    cell.font = Font(bold=True)
  • ✅ 必须在写入数据后调用
  • ✅ 只写入合并区域左上角单元格内容即可

📚 六、总结一句话

“空行”和“数据偏移”问题的根本原因是:merge_cells() 被提前调用、current_row 计数不准确、或原始数据中存在空值。

您可能感兴趣的与本文相关的镜像

Python3.10

Python3.10

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值