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

向现有Excel按指定列间隔写入列表时遇MergedCell只读错误求助

解决Excel写入时MergedCell只读错误及按指定列间隔写入数据的问题

错误原因分析

出现AttributeError: 'MergedCell' object attribute 'value' is read-only的核心原因是目标工作表Buff163AppliedStickers中存在合并单元格,pandas的to_excel在覆盖模式下尝试写入合并单元格区域时,触发了只读属性限制。同时原代码还存在两个关键问题:

  • 直接用DataFrame写入会按连续列输出,无法实现“每4列写入一个值”的需求
  • 每次循环重复创建ExcelWriter,效率低且容易引发文件访问冲突

修复方案与优化代码

下面是修改后的代码,解决合并单元格问题,同时实现指定列间隔写入、每行写入后保存的需求:

from openpyxl import load_workbook
import pandas as pd

def start_buy_monitoring():
    excel_file = "MarketBots (1).xlsx"
    sheet_name = "Buff163AppliedStickers"
    
    # 读取需要的基础数据
    excel_output = pd.read_excel(excel_file, sheet_name=sheet_name, usecols=['Buff163 URL', 'Sticker URL Code', 'Sticker Price (Average)'])
    num_rows = len(excel_output.index)
    
    # 用openpyxl直接操作工作簿,精准控制单元格写入
    wb = load_workbook(excel_file)
    ws = wb[sheet_name]
    
    start_row = 2  # 数据起始行(Excel行号从1开始,对应原代码的起始位置)
    start_col = 5  # 起始列(Excel第5列,后续每4列写入一个值)
    
    for row_inc in range(num_rows):
        percentages = []
        sticker_price = excel_output.at[row_inc, 'Sticker Price (Average)']
        adjusted_prices = returnDataBuff163(driver163, excel_output.at[row_inc, 'Buff163 URL'])
        
        # 计算百分比列表
        for price in adjusted_prices:
            try:
                # 注意:若sticker_price是从Excel读取的数值,直接转float即可,无需.text
                pct = round(float(price) / float(sticker_price), 4)
                percentages.append(pct)
            except Exception:
                percentages.append("Error")
        
        # 按间隔列写入当前行数据
        current_row = start_row + row_inc
        for idx, val in enumerate(percentages):
            # 计算目标列:起始列 + 索引*4,转换为openpyxl的0基索引(减1)
            target_col_idx = start_col + idx * 4 - 1
            target_cell = ws.cell(row=current_row, column=target_col_idx)
            
            # 处理合并单元格:合并单元格仅首单元格可写入值
            if target_cell.merged:
                # 查找当前单元格所属的合并区域
                for merged_rng in ws.merged_cells.ranges:
                    if merged_rng.min_row <= current_row <= merged_rng.max_row and merged_rng.min_col <= target_col_idx <= merged_rng.max_col:
                        ws.cell(row=merged_rng.min_row, column=merged_rng.min_col, value=val)
                        break
            else:
                target_cell.value = val
        
        # 每写入一行立即保存
        wb.save(excel_file)
    
    driver163.quit()

关键优化点说明

  • 规避合并单元格问题:使用openpyxl直接操作单元格,检查目标单元格是否为合并单元格,若为合并单元格则写入其首单元格(合并单元格仅首单元格支持写入)
  • 实现间隔列写入:通过start_col + idx*4计算目标列,转换为openpyxl的0基索引后定位单元格
  • 确保每行写入后保存:每次循环结束调用wb.save(),保证数据及时写入文件
  • 简化逻辑:用for循环替代原while循环,代码更简洁易维护

注意事项

  • 确认sticker_price的类型:原代码中的stickerPrice.text可能是错误的,若从Excel读取的是数值类型,直接用float(sticker_price)即可
  • 若工作表合并单元格较多,建议提前解除合并(如果业务允许),可大幅提升写入效率
  • 频繁保存可能影响性能,若数据量极大,可改为每N行保存一次,按需调整

内容的提问来源于stack exchange,提问作者Dallin Kump

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 20:23:12