>>> from env_helper import info; info()
页面更新时间: 2024-04-06 23:09:04
运行环境:
Linux发行版本: Debian GNU/Linux 12 (bookworm)
操作系统内核: Linux-6.1.0-18-amd64-x86_64-with-glibc2.36
Python版本: 3.11.2
1.2. 使用 OpenpyXL 读取 XLSX 电子表格¶
OpenpyXL 是一个开源项目,Openpyxl模块是一个读写Excel 2010文档的Python库。 XLSX 格式的电子表格文件是微软的开放电子表格格式,应用得越来越多。 如果要处理更早格式的Excel文档,可以使用其它库(如:xlrd、xlwt等)。 Openpyxl是一款比较综合的工具,不仅能够同时读取和修改Excel文档,而且可以对Excel文件内单元格进行详细设置, 包括单元格样式等内容,甚至还支持图表插入、打印设置等内容, 使用Openpyxl可以读写xltm, xltx, xlsm, xlsx等类型的文件, 且可以处理数据量较大的Excel文件,跨平台处理大量数据是其它模块没法相比的。 因此,Openpyxl 成为处理Excel XLSX 格式的电子表格的首选库工具。
1.2.1. xlrd、xlwt和openpyxl模块的比较¶
1)xlrd:对xls、xlsx、xlsm文件进行读操作–读操作效率较高,推荐
2)xlwt:对xls文件进行写操作–写操作效率较高,但是不能执行xlsx文件
3)openpyxl:对xlsx、xlsm文件进行读、写操作–xlsx写操作推荐使用
1.2.2. 电子表格的基本概念¶
在使用Openpyxl前先要了解三个概念,即:Workbook(工作簿,一个包含多个Sheet的Excel文件)、 Worksheet(工作表,一个Workbook有多个Worksheet,表名识别,如“Sheet1”,“Sheet2”等)、 Cell(单元格,存储具体的数据对象)三个对象。
在此将介绍使用 OpenpyXL 读取电子表格的方法。 OpenpyXL 使用下面的命令安装:
pip install Openpyxl
首先导入 openpyxl 模块,如果出错说明安装并未成功:
>>> import openpyxl
读取电子表格文件使用 openpyxl.load_workbook()
函数:
>>> wb = openpyxl.load_workbook('drr_20200629.xlsx' )
默认可读写,若有需要可以指定write_only
和read_only
为True
。
1.2.3. 获取工作表¶
工作簿也就是我们能够在文件夹里看到的带有名字的Excel文件,当您双击这个文档时就打开了一个工作簿。 每一本工作簿可以拥有许多不同的工作表。
在 Excel 中每次只能处理一个工作表,这个工作表的状态称为活动状态。
获得当前正在显示的工作表可以用 active
属性:
>>> asheet = wb.active
每一个电子表格都有名称,通过 title
属性获得:
>>> asheet.title
'工作表2'
活动工作表的概念在使用 Excel 处理时比较方便。
但是编程处理中更倾向于使用更准确的方式来获取。 要获得某个工作表,
可以根据工作表的名字获得。 要知道工作表的名字,可以先通过 sheetnames
属性或 get_sheet_by_names()
函数把所有工作表的名称列出:
>>> wb.sheetnames
['中英文含摘要', '工作表2']
然后使用 get_sheet_by_name()
函数返回参数指定的工作表对象:
>>> sheet = wb.get_sheet_by_name('工作表2')
/tmp/ipykernel_48171/2928318896.py:1: DeprecationWarning: Call to deprecated function get_sheet_by_name (Use wb[sheetname]).
sheet = wb.get_sheet_by_name('工作表2')
也可以通过索引值 , 如下:
>>> sheet2 = wb.worksheets[1]
工作表还有一些属性,如最大列数与最大行数,这两个数据表示工作表是实际存储数据的最大值,可以通过下面的属性获取:
>>> sheet.max_row
4
>>> sheet.max_column
2
根据工作表的最大列数与最大行数,可以用来对工作表的行、列进行遍历 。
1.2.4. 获取行和列¶
得到工作表后,可以继续得到工作表中的所有的行和列对象,得到后可以进行遍历操作。
sheet.rows
为生成器, 里面是每一行的数据,每一行又由一个tuple包裹。
sheet.columns
类似,不过里面是每个tuple是每一列的单元格。
>>> type(sheet.rows), type(sheet.columns)
(generator, generator)
因为按行,所以返回 A1
, B1
, C1
这样的顺序:
>>> for row in sheet.rows:
>>> for cell in row:
>>> print(cell.coordinate, cell.value, end=', ')
>>> print()
A1 name, B1 age,
A2 Max, B2 26,
A3 Marry, B3 18,
A4 Nanncy, B4 10,
交换遍历的先后,下面以 A1
, A2
, A3
这样的顺序来获取单元格:
>>> for column in sheet.columns:
>>> for cell in column:
>>> print(cell.value, end=', ')
>>> print()
name, Max, Marry, Nanncy,
age, 26, 18, 10,
上面的代码就可以获得所有单元格的数据。
如果要通过指定的索引值来获得行或列对象,可以通过索引 。
因为sheet.rows
是生成器类型,
不能使用索引,转换成list之后再使用索引,list(sheet.rows)[2]
这样就获取到第二行的tuple对象。
>>> for cell in list(sheet.rows)[2]:
>>> print(cell.value , end=', ')
Marry, 18,
1.2.5. 通过坐标获取单元格¶
在 Excel 中,每个单元格都有一个“坐标”, 行坐标用字母表示 ,列坐标用数字表示 。
获取某个单元格的值,观察在 Excel 中是先字母再数字的顺序,即先列再行。 如下面获得第2列第4行的单元格,使用方式与字典有些类似,其键为“坐标”,即行坐标与列坐标的组合:
>>> b4 = sheet['B4']
>>> b4.value
10
有了单元格,也可以返回其“坐标”的值,如下面表达式,说明单元格的列、行及其值:
>>> f'({sheet.cell(row=4, column=2).coordinate}, {b4.column}, {b4.row}) is {b4.value}'
'(B4, 2, 4) is 10'
坐标的横坐标使用字母表达,在数目较少时比较方便, 但如果数目多了,就显得比较繁琐。
除了用坐标的方式获得,OpenpyXL 还可以用cell函数, 使用关键字参数传入行与列的索引值,下面同样获取 B4 单元格:
>>> b4t = sheet.cell(row=4, column=2)
>>> print(b4t.value)
10
有了单元格,也可以返回其“坐标”的值,如下面表达式,说明单元格的列、行及其值:
>>> f'({b4t.column}, {b4.row}) is {b4t.value}'
'(2, 4) is 10'
b4.column
返回 B
, b4.row
返回 4
, value
则是那个单元格的值。 另外cell还有一个属性coordinate
,返回其坐标表达:
>>> b4t.coordinate
'B4'
1.2.6. 如何获得任意区间的单元格?¶
在访问工作表的行、列或单元格时,除了全部获取,然后遍历,或直接通过行、列索引获取,也可以直接从中取一个窗口,或者说切片。
使用 Python 最直接的方式可以使用 range()
函数进行遍历。
下面的写法,获得了以A1为左上角,B3为右下角矩形区域的所有单元格。 注意
range()
函数中索引从 1
开始的,因为在 OpenpyXL
中为了和Excel中的表达方式一致,并不和编程语言的习惯以0表示第一个值。
>>> for i in range(1, 4):
>>> for j in range(1, 3):
>>> cel = sheet.cell(row=i, column=j)
>>> print( f'{cel.coordinate}:{cel.value}',end=', ')
>>> print()
A1:name, B1:age,
A2:Max, B2:26,
A3:Marry, B3:18,
除了使用遍历的方法,还可以像使用切片那样使用,相当于一个小的工作表。
sheet['A1':'B3']
返回一个元组,该元组由子元组对象构成;
子元组对象由每行的单元格构成。
>>> for row in sheet['A2':'B3']:
>>> for cell in row:
>>> print(cell.coordinate, end=', ')
>>> print()
A2, B2,
A3, B3,
根据遍历后打印的坐标来看,与工作表中的排列顺序是一致的。
1.2.7. 根据字母获得列号,根据列号返回字母¶
另外还有一个有用的功能,可以将表达列号的字母与索引值进行相互转换。
根据字母获得列号,需要使用 column_index_from_string
,
根据列号获取字母,需要使用 get_column_letter
。
这两个函数存在于openpyxl.utils
,用法如下:
>>> from openpyxl.utils import get_column_letter, column_index_from_string
根据列的数字返回字母,如下:
>>> get_column_letter(2)
'B'
根据字母返回列的数字,如下:
>>> column_index_from_string('D')
4