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

openpyxl写入xlsx报错:'WriteOnlyWorksheet'对象无cell属性

问题现象

使用openpyxl库编写Python脚本写入xlsx文件时,在单元格赋值行抛出如下异常:

AttributeError: 'WriteOnlyWorksheet' object has no attribute 'cell'

运行时打印的相关变量值如下:

titulo: checkalllfromdatesbiggerthannumber
xp:  [40.0, 39.0, 42.0, 39.0, 24.0, 22.0, 9.0]
xp1:  [1143.0, 1278.0, 1157.0, 1115.0, 617.0, 484.0, 241.0]
yp:  ['2021-11-08', '2021-11-09', '2021-11-10', '2021-11-11', '2021-11-12', '2021-11-13', '2021-11-14']

出问题的原始功能函数代码:

def faz_fich_excell(titulo,xp,xp1,yp):
    print("titulo: ", titulo)
    print('xp: ', xp)
    print('xp1: ', xp1)
    print('yp: ', yp)
    ficheiro = "teste_a.xlsx"

    ayp = list(yp)
    axp = list(xp)
    axp1 = list(xp1)
    titulo = titulo[:30]

    if not os.path.exists(ficheiro):
        wb = openpyxl.Workbook()
        for x in wb.get_sheet_names():
            std = wb.get_sheet_by_name(x)
            wb.remove_sheet(std)
    else:
        os.chmod(os.path.join(ficheiro), 0o777)
        wb = openpyxl.Workbook(ficheiro)

    wb.create_sheet(titulo.replace(" ", ""))
    ws = wb[titulo.replace(" ", "")]
    ws = wb.active

    r=1
    for y,x,z in zip(ayp,axp,axp1):
        print(y,x,z)
        ws.cell(row=r, column=1).value = str(y)
        ws.cell(row=r, column=2).value = str(x)
        ws.cell(row=r, column=3).value = str(z)

        r += 1

    wb.save(os.path.join(ficheiro))
错误根因
  • 核心触发原因:工作簿打开方式错误。openpyxl.Workbook()是创建新空白工作簿的构造方法,第一个位置参数是write_only(只写模式开关,默认False),不能用来打开已有文件。代码中在文件已存在的分支里写wb = openpyxl.Workbook(ficheiro),传入的文件路径会被当做write_only参数值,非空字符串判定为布尔真,因此自动开启了只写工作簿模式。该模式下生成的工作表是WriteOnlyWorksheet类型,不支持.cell()方法随机读写单元格,仅支持append()逐行追加写入,因此调用.cell()时直接抛出属性不存在的错误。打开已有xlsx文件的正确方法是使用openpyxl.load_workbook()。
  • 次要逻辑错误:工作表引用被覆盖。代码中先通过名称获取了刚创建的自定义工作表,紧接着执行ws = wb.active将变量重新指向工作簿默认激活的工作表,前面的自定义表引用完全失效,在只写模式场景下刚好拿到了不支持.cell()方法的WriteOnlyWorksheet对象。
  • 兼容隐患:使用已废弃API。代码中调用的get_sheet_names()、get_sheet_by_name()、remove_sheet()都是openpyxl早期版本的API,在新版本中已被标记废弃,容易出现兼容问题。
修复方案

按以下规则修改代码即可解决问题:

  1. 已有文件加载统一使用openpyxl.load_workbook(),禁止给Workbook()构造函数传入文件路径
  2. 删除多余的ws = wb.active赋值,直接使用自定义名称的工作表对象
  3. 替换所有废弃API:获取所有工作表用wb.sheetnames,删除工作表用wb.remove(worksheet)
  4. 调整工作表创建逻辑:新建工作簿时不需要先删默认表再建新表,可以直接修改默认表的名称,减少冗余操作;增加重名工作表判断,避免重复运行时报错

修复后的完整代码:

import os
import openpyxl

def faz_fich_excell(titulo,xp,xp1,yp):
    print("titulo: ", titulo)
    print('xp: ', xp)
    print('xp1: ', xp1)
    print('yp: ', yp)
    ficheiro = "teste_a.xlsx"
    sheet_name = titulo[:30].replace(" ", "")

    ayp = list(yp)
    axp = list(xp)
    axp1 = list(xp1)

    if not os.path.exists(ficheiro):
        wb = openpyxl.Workbook()
        # 直接修改默认工作表名称,不需要删了再建
        ws = wb.active
        ws.title = sheet_name
    else:
        os.chmod(ficheiro, 0o777)
        # 正确加载已有工作簿
        wb = openpyxl.load_workbook(ficheiro)
        # 如果同名工作表已存在先删除,避免创建报错
        if sheet_name in wb.sheetnames:
            del wb[sheet_name]
        ws = wb.create_sheet(sheet_name)

    r=1
    for y,x,z in zip(ayp,axp,axp1):
        print(y,x,z)
        ws.cell(row=r, column=1).value = str(y)
        ws.cell(row=r, column=2).value = str(x)
        ws.cell(row=r, column=3).value = str(z)
        r += 1

    wb.save(ficheiro)
    wb.close()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 05:21:47