Python操作Excel工作簿的示例代码(*.xlsx)

Jasper
Jasper
发布时间:2026-10-13| 5人浏览过
原创

本文对比了Python中处理Excel文件的几个主要库:xlrd、xlwt、xlutils、openpyxl和xlwings。重点介绍了功能更完善的xlwings库,涵盖创建、读写、行列增删及单元格格式设置。同时分析了.xls与.xlsx格式差异及文件体积问题,提供了各库的支持情况对比表,帮助开发者根据需求选择合适的库。

前言与测试环境

前言

Excel作为广泛使用的桌面数据处理工具,渗透于各行各业,在编程领域同样常见。Python生态中处理Excel格式文件的库众多,包括xlrd、xlwt、xlutils、openpyxl和xlwings等。然而,各库的操作机制存在差异,部分库在处理特定场景时具有局限性。

下文将对比上述几个库的差异,并重点记录xlwings库的使用心得。目前看来,xlwings是个人觉得较为便捷的库;其他库在使用过程中常遇到各类问题,不过在特定场景下仍具有不错的适用性。

Excel文件格式差异

EXCEL文件格式简介

Excel作为电子表格软件,支持多种保存格式,其中“Excel工作簿(*.xlsx)”和“Excel 97-2003工作簿(*.xls)”最为常用。通常认为,.xls格式是03版Excel之前常用的格式,而.xlsx则是03版之后,一般指07版Excel之后常用的格式。

大多数Excel程序均支持打开和编辑上述两种格式,并支持相互转换存储。不过,建议在没有特殊要求的情况下优先使用新版格式。一方面,新版稳定版本可能修复了旧版的某些Bug,另一方面也带来了性能优化。

在撰写本文前,笔者发现一个空白的.xlsx格式文件大小约为7KB,而空白的.xls格式文件大小约为24KB。当写入相同的汉字内容后,两个文件分别变为10KB和30KB,体积差异明显。此外,将.xlsx文件另存为.xls格式时,系统会弹出兼容性提示,警告部分设置可能丢失。因此,建议尽量使用新版本格式。

测试环境说明

由于应用程序和Python库不断迭代,不同版本可能存在差异。以下列出尽可能详细的版本号,供参考:

  • 操作系统: Windows 10 随意版
  • Python: 3.75
  • xlrd: 1.2.0
  • xlwt: 1.3.0
  • xlutils: 2.0.0
  • openpyxl: 3.0.3
  • xlwings: 0.18.0

以上各程序库在使用前需自行安装,此处不再赘述安装方法。但可提供一个快速安装的镜像源命令,使用 pip install -i https://pypi.doubanio.com/simple 库名 可以尽可能解决下载安装缓慢的问题。

Python操作Excel的三种方案

Excel具体操作方法

Python操作Excel的方法大致可分为三组:第一组配合使用xlrd、xlwt、xlutils;第二组使用openpyxl库;第三组使用xlwings库。本文重点总结xlwings的使用,对其他两组仅作简要了解。

xlrd、xlwt、xlutils库

xlrd、xlwt、xlutils库的使用

这组库的名称形象地反映了功能:一个负责读,一个负责写,加上一个小工具,组合起来即可对Excel进行操作。下面通过一个小练习演示:打开一个Excel文件,修改第一个单元格的值,再另存为新文件。代码如下:


import xlrd
import xlwt
import xlutils.copy

def save_as_new_file(file_name, new_file_name):
 # 打开Excel文件
 rb = xlrd.open_workbook(file_name)
 # 创建一个可写入的副本
 wb = xlutils.copy.copy(rb)
 # 获得第一个sheet页签
 ws = wb.get_sheet(0)
 # 第一个单元格写入测试值
 ws.write(0, 0, 'test value')
 # 另存为一个新文件
 wb.save(new_file_name)

上述代码在操作.xlsx或.xls文件时均不会报错,但另存为.xlsx格式的文件可能无法打开;同时,正常存储的.xls文件打开后格式可能会丢失。解决方法是修改打开文件的参数,代码如下:


rb = xlrd.open_workbook(file_name, formatting_info=True)

其中参数formatting_info=True表示打开Excel时保留原有格式,但这仅针对.xls格式文件。对于.xlsx格式文件,直接抛出异常raise NotImplementedError("formatting_info=True not yet implemented")。由于无法处理.xlsx格式的格式保留,笔者暂未使用这几个库操作Excel。

此外需注意,这几个库在操作单元格时,行和列的索引均从0开始。

openpyxl库

openpyxl库的使用

该库主要用于操作.xlsx格式文件,无法打开.xls格式文件,会报错openpyxl does not support the old .xls file format。但可以存储为.xls格式,再次打开时会有格式不匹配的警告,不过基础数据仍在。因此,若需处理.xls格式,仍建议优先使用其他库或注意此限制。

创建新文件的常见用法如下:


from openpyxl import Workbook
from openpyxl import load_workbook
from openpyxl.styles import Font, Fill, Alignment, PatternFill

def write_new_excel(file_name):
 # 创建一个excel文档
 wb = Workbook()
 # 获得当前激活的sheet对象
 ws = wb.active
 # 给A2单元格赋值
 ws['A2'] = 'This is A2 cell'
 # 一行添加多列数据
 ws.append([1, 2, 'hello'])
 # 添加新的sheet
 ws = wb.create_sheet(title='NewInfo',index=0)
 # 设置单元格的值
 ws['A1'] = 'This is new sheet'

 # 保存excel
 wb.save(file_name)

读取并改写原有文件的常见用法如下:


def read_update_excel(file_name):
 # 加载Excel表
 wb = load_workbook(file_name)
 # 打印sheet数量
 print('sheet count:', len(wb.sheetnames))
 # 打印所有sheet名字
 print('sheet name list:', wb.sheetnames)
 # 获取第一个sheet对象
 ws = wb[wb.sheetnames[0]]
 # 打印sheet表行数和列数
 print('rows count:', ws.max_row, 'cols count:', ws.max_column)
 # 更新单元格A1的内容
 ws['A1'] = 'this is A1'
 # 在第二行位置插入一行
 ws.insert_rows(2)
 # 删除第五行
 ws.delete_rows(5)
 # 获取单元格对象,对应B2单元格
 cell = ws.cell(2,2)
 # 设置单元格内容
 cell.value = 'this is B2'
 # 修改字体格式为粗体
 cell.font = Font(bold=True)
 # 修改单元格格式
 cell.fill = PatternFill("solid", fgColor="F0CDCD")

 # 保存原文件或另存一个文件
 wb.save(file_name)

使用该库时,存储带有样式的数据未发现明显问题。但当加入计算公式后,另存为文件时文件尺寸明显变小,尽管数据和公式本身看似正常。

有资料指出该库处理速度较慢,因笔者处理的文件较小,未明显察觉此问题。另一个问题是Excel中的宏会全部丢失。测试中确实发现宏丢失,这与文件格式有关:保存宏需存储为.xlsm格式。但openpyxl主要用于操作.xlsx文件,存储时会导致宏丢失;强行存储为.xlsm格式会导致最终文件无法打开。

此外,该库在操作单元格时,行和列的索引从1开始。

xlwings库详解

xlwings库的使用

使用xlwings前需创建一个App对象,通过该App对象来操作Excel,这类似于将Excel的各种操作API封装在一起,再通过App对象调用。若在创建App时不设置隐藏参数,会正常打开Excel程序界面。

使用xlwings的基本方式如下:


import xlwings as xw

# 设置Excel程序不可见
app = xw.App(visible=False, add_book=False)

# 通过 app 操作 Excel文件
# app.bala bala bala .....
# app.bala bala bala .....

# 优雅的退出
app.quit()

创建一个新的Excel文件并写入数据的示例代码如下:


def write_new_excel(app, file_name):
 # 创建新的 Excel 表
 wb = app.books.add()
 # 获取当前活动的sheet
 ws = wb.sheets.active
 # 初始化二维区域的值
 arr_data = [[1, 2, 3], [4, 5, 6], [7, 8, 'end']]
 # 设置到新建的Excel中
 ws.range('A1:B3').value=arr_data
 # 设置单独一个单元格的值
 ws.range('A4').value='this is A4'
 # 设置单独一个单元格的值
 ws[3,1].value='this is B4'
 # 保存Excel文件
 wb.save(file_name)
 wb.close()

需要注意的是,通过行索引和列索引修改单元格时,起始索引为0。

读入已有Excel表格并修改的示例代码如下:


def read_update_excel(app, file_name):
 # 加载已有的表格
 load_wb = app.books.open(file_name)
 # 获取Excel表中第一个sheet
 load_ws = load_wb.sheets[0]
 # 打印sheet的名字
 print(load_ws.name)
 # 根据sheet名字获取sheet对象
 load_ws = load_wb.sheets[load_ws.name]
 # 获取当前活动的sheet
 load_ws = load_wb.sheets.active

 # 获取存在数据的行数和列数
 rows = load_ws.api.UsedRange.Rows.count
 cols = load_ws.api.UsedRange.Columns.count
 print('rows count:', rows, 'cols count:', cols)

 # 修改指定单元格数据(A1单元格)
 load_ws[0,0].value='this is A1'

 # 有空行或空列时获取准确的行列数量
 print(load_ws.used_range.shape)

 # 从A1单元格开始扩展到非空行空列,最后的行数和列数
 print((load_ws.range('A1').expand().last_cell.row,
  load_ws.range('A1').expand().last_cell.column))

 # 从A1单元格开始扩展到非空行空列,最后的行数和列数
 print((load_ws.range('A1').expand().last_cell.row,
  load_ws.range('A1').expand().last_cell.column))

 # 从A1单元格开始扩展到非空行空列,最后形状
 print(load_ws.range(1,1).expand().shape)

 # 从A1单元格开始扩展到非空行空列,最后的行数和列数
 print((load_ws.range('A1').expand('table').rows.count,
  load_ws.range('A1').expand('table').columns.count))

 # 保存修改后的Excel
 load_wb.save(file_name)
 load_wb.close()

Excel中增加或删除行和列的示例代码如下:


def insert_delete_rowscols(app, file_name):
 # 加载已有的表格
 load_wb = app.books.open(file_name)
 # 获取当前活动的sheet
 load_ws = load_wb.sheets.active

 # 从第2行开始插入4行,也就是说2-5行变成新插入的空行
 load_ws.api.rows('2:5').insert
 # 删除第6行和第7行
 load_ws.api.rows('6:7').delete
 # 插入一个单元格,实际测试效果是B列从B2开始向下移动,B2为新添加的单元格
 load_ws.range('B2').api.insert
 # 插入新的一列
 load_ws.api.columns('B').insert
 # 删除一列
 load_ws.api.columns('C').delete

 # 保存修改后的Excel
 load_wb.save(file_name)
 load_wb.close()

单元格宽高查询、设置与合并的示例代码如下:


def cell_operation(app, file_name):
 # 加载已有的表格
 load_wb = app.books.open(FILE_PATH_ROOT + file_name)
 # 获取当前活动的sheet
 load_ws = load_wb.sheets.active

 # 合并单元格
 load_ws.range('A2:A3').api.merge

 #获取单元格
 cell = xw.Range('B2')
 # 打印单元格所在的行和列
 print("row is:", cell.row, "col is:", cell.column)

 # 打印当前格子的高度和宽度
 print("cell.width:", cell.width, "cell.height:", cell.height)

 # 设置当前格子的高度和宽度
 cell.row_height = 32
 cell.column_width = 64

 # 指定单元格的高度和宽度自适应
 cell.columns.autofit()
 cell.rows.autofit()

 # 再次打印当前格子的高度和宽度
 print("cell.width:", cell.width, "cell.height:", cell.height)

 # 保存修改后的Excel
 load_wb.save(file_name)
 load_wb.close()

库功能对比与总结

几个库的支持情况对比

尽管前文介绍了多种方法,但在实际遇到问题时仍会犹豫选择哪种方式。以下根据实验结果进行简单对比,若有不准确或错误之处,欢迎指正,笔者会尽快改正。

情景/库 xlrd、xlwt、xlutils openpyxl xlwings
读取.xls 可以带有样式读取 不支持 可以读取
保存.xls 可以带有样式保存 可以保存,但是提示文件扩展名不匹配,可以看到原始数据 可以保存,但是提示文件扩展名不匹配,可以看到原始数据
读取.xlsx 可以读取,但没有样式 可以带有样式读取 可以带有样式读取
保存.xlsx 保存后打不开 可以带有样式保存 可以带有样式保存
读取.xlsm 可以读取,但没有样式和宏 可以读取,但没有宏 可以读取包含宏的表格
保存.xlsm 保存后打不开,存成 .xls 格式宏丢失 保存后打不开,存成 .xls想 格式宏丢失 存储后宏还在
增删行和列 没有直接方法 支持 支持
另存后大小 .xls 文件没有变化 .xlsx 文件会变小 .xls、.xlsx 文件没有变化
使用建议 只操作.xls文件可以考虑 只操作.xlsx文件可以考虑,不能带有宏 一个比较好的选择,使用时感觉速度稍微有点慢

总结

  1. Excel表格程序经过版本更替发生了巨大变化,出现了相同内容下.xls格式文件比.xlsx格式文件大得多的情况。
  2. 基于上述考虑,若能使用新版表格格式,建议放弃旧格式。
  3. 此外还有一个有趣的现象:包含少量数据的.xlsx格式表格,其体积有时比空表格还要小。具体原因尚不明确,恳知情的读者告知。

到此这篇关于Python操作Excel工作簿的示例代码(*.xlsx)的文章就介绍到这了,更多相关Python操作Excel工作簿内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。