You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用openpyxl根据单元格内容移动单元格区域遇问题求助

用openpyxl合并Excel中特定索引行的数据

需求

需要将从PDF提取后存入Excel的数据按索引合并:
原始数据格式:

1 abc def ghi
2 jkl mno pqr
1 stu vwx yza
2 bcd efg hij
...

转换为目标格式:

1 abc def ghi jkl mno pqr
2 null null null null
1 stu vwx yza bcd efg hij
2 null null null null
...

最初尝试(无效果)

代码运行无报错,但数据未按预期移动:

from openpyxl import load_workbook

excel_file = load_workbook("C:\Users\Jake\Documents\Shared-VB\upload 2.5.23\Excel Result.xlsx")
sh = excel_file.active

for i in range(1, sh.max_row + 1):
    if sh.cell(row=i, column=1).value == "2":
        sh.move_range("B{i}:D{i}", rows=-1, cols=3)

excel_file.save("C:\Users\Jake\Documents\Shared-VB\upload 2.5.23\Final Result.xlsx")

问题:将索引值当作字符串比较,但实际Excel中是数字类型,导致条件不触发。

更新后代码(报错)

修改为数字比较后,出现坐标无效的错误:

from openpyxl import load_workbook

excel_file = load_workbook("C:\Users\Jake\Documents\Shared-VB\upload 2.5.23\Excel Result.xlsx")
sh = excel_file.active

for i in range(1, sh.max_row + 1):
    if sh.cell(row=i, column=1).value == 2:  # 原代码误写为4,修正为2
        sh.move_range("B{i}:D{i}", rows=-1, cols=3)

excel_file.save("C:\Users\Jake\Documents\Shared-VB\upload 2.5.23\Final Result.xlsx")

报错信息:

Traceback (most recent call last):
  File "C:\Users\Jake\Documents\Work Projects\Python\Contract Extraction\contract_extraction_xlm_1.py", line 23, in <module>
    sh.move_range("B{i}:D{i}", rows=-1, cols=3)
  File "C:\Users\Jake\anaconda3\lib\site-packages\openpyxl\worksheet\worksheet.py", line 772, in move_range
    cell_range = CellRange(cell_range)
  File "C:\Users\Jake\anaconda3\lib\site-packages\openpyxl\worksheet\cell_range.py", line 53, in __init__
    min_col, min_row, max_col, max_row = range_boundaries(range_string)
  File "openpyxl\utils\cell.py", line 135, in openpyxl.utils.cell.range_boundaries
ValueError: B{i}:D{i} is not a valid coordinate or range
[Finished in 923ms]

问题:字符串未正确格式化,"B{i}:D{i}"中的{i}没有被替换成实际行号,导致openpyxl无法识别单元格范围。

解决方案

1. 动态生成单元格范围

使用f-string格式化范围字符串,让{i}被实际循环的行号替换:

sh.move_range(f"B{i}:D{i}", rows=-1, cols=3)

也可以用.format()方法:

sh.move_range("B{}:D{}".format(i, i), rows=-1, cols=3)

2. 调整循环方向(关键)

如果从第一行向下循环,移动行后会导致后续行索引混乱(比如第2行数据被移到第1行,原第3行变成新第2行),可能漏处理数据。因此需要从最后一行倒序循环。

最终完整代码

from openpyxl import load_workbook

# 路径前加r表示原始字符串,避免转义字符出错
excel_file = load_workbook(r"C:\Users\Jake\Documents\Shared-VB\upload 2.5.23\Excel Result.xlsx")
sh = excel_file.active

# 倒序循环,避免移动行后索引混乱
for i in range(sh.max_row, 0, -1):
    cell_value = sh.cell(row=i, column=1).value
    # 确保值是数字2,避免类型不匹配问题
    if isinstance(cell_value, int) and cell_value == 2:
        # 动态生成单元格范围并移动数据
        sh.move_range(f"B{i}:D{i}", rows=-1, cols=3)
        # 清空当前行的B-D列,实现目标格式的null效果
        for col in range(2, 5):
            sh.cell(row=i, column=col).value = None

excel_file.save(r"C:\Users\Jake\Documents\Shared-VB\upload 2.5.23\Final Result.xlsx")

额外说明

  • 路径前加r可避免反斜杠转义错误;
  • 增加isinstance判断,防止非数字值导致的比较异常;
  • 移动数据后手动清空当前行对应列,符合目标格式要求。

内容的提问来源于stack exchange,提问作者databank-zero

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 03:20:52