URLhttps://learnscript.net/zh/office-programming/openpyxl/excel-files/
    复制链接转到说明  示例

    如何使用 openpyxl 读取和写入 Excel 文件

    我被代码海扁署名-非商业-禁演绎
    阅读 12:35·字数 3780·更新 

    运行本节中的示例,需要安装 Python 包openpyxl,你可以查看安装 openpyxl 包一段来了解相关信息。

    openpyxl 包支持的 Excel 文件格式

    无论使用包中的哪个函数或类,openpyxl包只能读取和写入以下 Microsoft Excel 文件格式,.xlsx.xlsm(启用了宏的 Excel 文件),.xltx(Excel 模板文件),.xltm(启用了宏的 Excel 模板文件)。

    对于旧的 Excel 文件格式.xls,可以尝试采用包xlrdxlwt进行操作,或者将.xls转换为.xlsx格式的 Excel 文件。

    使用 openpyxl 包读取 Excel 文件

    你可以使用openpyxl包的load_workbook函数或其别名open(非 Python 内置函数open),来读取 Excel 文件中的数据,该函数的返回值是一个可操作 Excel 数据的工作簿对象Workbook

    load_workbook(filename, read_only=False, keep_vba=KEEP_VBA, data_only=False, keep_links=True, rich_text=False)

    filename 参数

    filename参数为需要读取的 Excel 文件的路径(绝对路径或相对路径),或者与 Excel 文件相关并采用了二进制模式的file-like(类文件)对象。比如,调用 Python 内置函数open(非load_workbook的别名),并采用rb模式创建的file-like对象。

    read_only 参数

    read_only参数默认为False,用来指示load_workbook函数返回的工作簿对象Workbook是否是只读的。如果设置为True,那么你将无法通过Workbook对象保存对 Excel 数据的改动,这可能会改进一些性能,因为与写入相关的逻辑以及一些复杂的内容(比如,Excel 单元格中的超链接)将被忽略。

    keep_vba 参数

    在非测试环境下,keep_vba参数的默认值为False,表示不会读取 Excel 文件中与 VBA(Visual Basic for Applications)有关的内容。如果设置为True,那么文件中关于 VBA 的内容将被读取到Workbook对象中,当然,这并不意味着你可以执行 VBA 中的代码,或使用 VBA 所实现的功能。

    data_only 参数

    data_only参数(默认值为False)用于指示是读取单元格的公式的计算结果,还是读取单元格的公式,当 Excel 文件包含具有公式的单元格时。如果设置为True,那么将读取公式的计算结果,这意味着Workbook对象中的相关单元格不再拥有公式。

    keep_links 参数

    keep_links参数的默认值为True,用于指示在读取 Excel 文件时,是否读取外部链接数据的缓存,比如,另一个 Excel 文件的工作表的某个单元格的值。如果设置为False,那么外部链接数据的缓存不会被读取到Workbook对象中,当缓存过大时,这种做法将是有效的。

    rich_text 参数

    rich_text参数用于指示在读取 Excel 文件时,是否保留单元格中的富文本格式(Rich Text Formatting,RFT),其默认值为False(不保留富文本格式),这意味着Workbook对象中相关单元格的富文本格式将丢失。当rich_text参数为True时,保存Workbook对象可能会失败。

    下面,我们准备了名称为Hello.xlsx的 Excel 文件,以及读取该文件的 Python 脚本文件read.py,他们位于同一目录中。

    read.py
    # 请将命令行跳转至 Hello.xlsx 所在的目录,然后运行此脚本文件
    # 导入函数 load_workbook
    from openpyxl import load_workbook
    
    # 读取 Excel 文件 workbook = load_workbook('Hello.xlsx')
    # 获取工作表 1.1班 中的单元格 A1,B1,C1,B4,C4 并显示 worksheet = workbook['1.1班'] name = worksheet['A1'].value age = worksheet['B1'].value score = worksheet['C1'].value print(f'第一个学生 {name} {age} {score}') avg_age = worksheet['B4'].value avg_score = worksheet['C4'].value print(f'平均值公式 {avg_age} {avg_score}')
    第一个学生 小小 13 100
    平均值公式 =AVERAGE(B1:B3) =AVERAGE(C1:C3)

    openpyxl 通过 read 特性来判断 filename 参数是否为 file-like 对象

    在读取 Excel 文件的过程中,openpyxl会检查load_workbook函数的参数filename是否具有特性read,如果具有,那么filename参数将被视为file-like对象,read特性将作为方法被调用,以获取 Excel 文件的二进制格式数据。

    在下面的代码中,我们使用open函数打开了 Excel 文件Hello.xlsx,并将返回的对象作为load_workbook函数的实参。

    data_only.py
    # 请将命令行跳转至 Hello.xlsx 所在的目录,然后运行此脚本文件
    # 导入函数 load_workbook
    from openpyxl import load_workbook
    
    # 使用 open 函数打开 Excel 文件 xlsx = open('Hello.xlsx', 'rb') workbook = load_workbook(xlsx, data_only=True)
    # 读取单元格 B4,C4 的公式计算结果并显示 worksheet = workbook['1.1班'] avg_age = worksheet['B4'].value avg_score = worksheet['C4'].value print(f'平均值 {avg_age} {avg_score}')
    平均值 13 96.3333333333333

    将 read_only 参数设置为 True 后,依然可以进行某些修改操作

    虽然将load_workbook函数的read_only参数设置为True后,执行工作簿对象Workbooksave方法或对单元格进行写入会导致异常,但并非所有的修改操作都是不可行的(比如,可以修改工作表的标题),只不过这些改变无法被保存。

    下面,我们通过只读的方式来打开 Excel 文件Hello.xlsx,然后修改工作表的标题。

    read_only.py
    # 请将命令行跳转至 Hello.xlsx 所在的目录,然后运行此脚本文件
    # 导入包 openpyxl
    import openpyxl
    
    # 以只读方式打开 Excel 文件,并修改工作表标题 workbook = openpyxl.open('Hello.xlsx', True) worksheet = workbook['1.1班'] worksheet.title = '1.2班'
    # ERROR 只读的 Workbook 对象不能修改单元格的值 worksheet['A1'].value = '一个好人'
    AttributeError: Cell is read only

    rich_text 参数为 False 不意味着单元格会丢失全部格式

    load_workbook函数的rich_text参数为False,并不表示Workbook对象中的单元格会丢失全部格式,因为一些格式可能不属于富文本格式,不针对单元格中的文本块(Text Block),比如,为整个单元格设置的文本颜色。

    使用 openpyxl 包写入(保存)Excel 文件

    使用openpyxl.writer.excel模块的save_workbook函数,或Workbook对象的save方法,可以将Workbook对象保存为 Microsoft Excel 文件。

    save_workbook(workbook, filename)
    save(filename)

    workbook 参数

    workbook参数为需要进行保存的Workbook对象。

    filename 参数

    filename参数为 Excel 文件的绝对路径或相对路径,如果路径指向的文件已经存在,那么他将被覆盖。

    下面,我们尝试在修改单元格A1后,再次将Workbook对象保存为文件Overwrite.xlsx,原有的Overwrite.xlsx会被覆盖。

    save.py
    # Overwrite.xlsx 会被保存至命令行的当前工作目录
    # 导入包 openpyxl
    import openpyxl
    
    # 创建 Workbook 并先后保存两次 workbook = openpyxl.Workbook() workbook.save('Overwrite.xlsx') workbook['Sheet']['A1'].value = '你好!' workbook.save('Overwrite.xlsx')

    write_only 属性为 True 的 Workbook 对象仅能被保存一次

    当你直接创建Workbook对象,并将其构造器的write_only参数设置为True时,被创建的Workbook对象将是只写的(write_only属性为True),对于只写的Workbook对象,只能调用其save方法或使用save_workbook函数保存一次,多次保存将导致异常。

    在下面的例子中,我们尝试保存只写的Workbook对象两次。

    write_only.py
    # 导入函数 save_workbook 和类 Workbook
    from openpyxl.writer.excel import save_workbook
    from openpyxl import Workbook
    
    # 创建 Workbook 对象并保存 workbook = Workbook(True) workbook.save('New.xlsx') # ERROR 只能保存一次 save_workbook(workbook, 'New.xlsx')

    被保存的 Workbook 对象需要拥有至少一个可见的工作表

    无论是使用openpyxl.writer.excel模块的save_workbook函数,还是Workbook对象的save方法,openpyxl要求工作簿对象拥有至少一个可见的工作表,即至少一个sheet_state属性为'visible'Worksheet对象,否则,保存为 Excel 文件将是不可行的,异常IndexError: At least one sheet must be visible会被抛出。

    在下面的代码中,工作簿对象将拥有两个工作表,由于他们都是不可见的,因此保存将失败。

    no_sheet.py
    # 导入 Workbook 类
    from openpyxl import Workbook
    
    # 创建一个 Workbook 对象,将其中的工作表设置为隐藏 workbook = Workbook() workbook['Sheet'].sheet_state = 'hidden' workbook.create_sheet().sheet_state = 'hidden' # ERROR 无法保存没有可见工作表的 Workbook 对象 workbook.save('nosheet.xlsx')
    IndexError: At least one sheet must be visible

    关闭 openpyxl 包打开的 Excel 文件

    如果你在使用load_workbook函数时,将read_only参数设置为True,获取了只读的Workbook对象,那么调用Workbook对象的close方法,可以关闭与工作簿相关的ZipFile对象,此后,读取工作表中的单元格将是不可行的,但工作表自身的一些相关信息依然可以访问,比如工作表的名称(标题)。

    close 方法对只写的 Workbook 对象的影响不明显

    虽然在官方的说明中,close方法会对只写的Workbook对象产生影响,但这种影响并不明显(似乎是不存在的),你可以将一行数据写入调用了close方法的Workbook对象,并通过save方法保存他们。

    在对Workbook对象调用close方法之前或之后,写入数据均没有问题,并可以调用save方法将Workbook对象保存为 Excel 文件。

    close.py
    # 请将命令行跳转至 Hello.xlsx 所在的目录,然后运行此脚本文件
    from openpyxl import Workbook, load_workbook
    
    # 创建只写的工作簿 w_workbook = Workbook(True) w_workbook.create_sheet() w_workbook['Sheet'].append(['Hello', 'World']) # 调用 close 方法之后,再次写入一行数据,并保存 w_workbook.close() w_workbook['Sheet'].append(['你好', '世界']) w_workbook.save('Close.xlsx')
    # 创建只读的工作簿 r_workbook = load_workbook('Hello.xlsx', True) print(r_workbook['1.1班']['A1'].value) # 调用 close 方法之后,读取单元格 A1 r_workbook.close() # ERROR 无法读取 A1 单元格 print(r_workbook['1.1班']['A1'])
    小小

    ValueError: Attempt to use ZIP archive that was already closed

    源码

    src/zh/openpyxl/excel_files·codebeatme/office-programming·GitHub

    讲解视频

    如何使用 openpyxl 读取、修改、保存 Excel 工作簿·YouTube如何使用 openpyxl 读取、修改、保存 Excel 工作簿·Bilibili