向现有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
相关产品推荐
相关产品推荐

