推荐两个⾼效处理Excel的Python开源库
【导语】:openpyxl 和 formulas 是两个成熟的开源库,在Python中借助这两个库,处理Excel电⼦表格,可以实现⾃动访问、处理表格中数据的功能,省时⾼效,不易出错,是处理Excel表格的⼀种好办法。
简介
Excel在⼯作中很常见,许多公司的软件项⽬都会⽤到它。对于应⽤程序开发者⽽⾔,我们经常需要将Excel⽂件转换为应⽤程序。⼤多数情况下我们都把Excel作为数据的导出格式,有时也将其作为数据的输⼊格式。
虽然Excel并不是⼀个软件领域的专⽤语⾔,但⼀些软件领域的专家常常需要⽤其处理问题。这就导致会“说”Excel的软件更受⽤户的青睐。即使从长远来看,我们的⽬标是把Excel变成⼀个应⽤程序或者软件领域的⼀种语⾔(DSL),但能⾃动处理Excel中的数据也是⼀个重要⽅向。
在以下情景中,⾃动处理Excel数据将⾮常有⽤:
例如在⼀个项⽬中,许多⽤户需要使⽤某些相同的Excel⽂件,⽽应⽤程序通过处理这些Excel⽂件,让⽤户使⽤起来更加⽅便。或者当⼀些⽤户想⽤Excel中的数据⽣成带有附加图表和formulas的报告时,应⽤程序可以⽣成⼀个电⼦表格,⽤来输出⼀些查询或计算结果,⽅便⽤户使⽤这些数据。
在本⽂中,我们将探索如何使⽤openpyxl库和其他⼯具,结合Python处理Excel电⼦表格。主要分为以下⼏点:
处理Excel⽂件,⽤不同的⽅法访问其中的数据;
使⽤formulas;
输出Excel⽂件。
注意:本⽂中我们处理的只是“现代”(2010)基于xml的Excel⽂件,⽂件扩展名为.xlsx。Openpyxl不⽀持之前的⼆进制Excel⽂件(.xls),针对这类⽂件有其他的解决⽅案,在本⽂中不做讨论。本⽂中的所有⽰例代码均可在GitHub仓库中到。
项⽬地址:
github/Strumenta/article-python-excel
安装
下⾯,我们设定⼀个类似unix的环境-Linux、OSX或者WSL。第⼀步,创建⼀个⽬录来存放我们的项⽬:
mkdir python-excel
cd python-excel
如果想要把代码放到Github上,我们可以在Github上创建⼀个仓库,然后把它克隆到本地:
git clone <repo-url> python-excel
cd python-excel
这将使我们能在GitHub为Python⽣成⼀个.gitignore⽂件,为我们⽣成⼀个README⽂件和⼀个license⽂件。在创建了项⽬根⽬录之后,我们可以使⽤pip安装来openpyxl。我们需要设置⼀个虚拟环境,这样就不会影响到系统的Python安装:
python -m venv .venv
source .venv/bin/activate
激活环境后,我们应该可以在shell prompt中看到:
(.venv) python-excel (main*) »
调⽤load_workbook的结果
Openpyxl打开⽂件后,⼀般可以同时进⾏读取和写⼊⼯作,除⾮我们给load_workbook设置⼀个read_only=True参数,表⽰只读取⽂件,当我们使⽤完⼀个Excel⽂件后,必须关闭它:
wb.close()
不幸的是,Workbook不是⼀个“⽂件管理者”,所以不能⽤Python中的语句来⾃动关闭它。即使在⼀些exceptions的情况中,也必须得⼿动关闭⽂件:
wb = load_workbook(path)
try:
#
finally:
wb.close()
2.处理⼀个Excel⽂件 - 通⽤案例
通常,Workbooks中可能有⼏个表,我们需要选择Excel⽂件中的⼀个表,访问其中的数据。随后,我们再学习如何处理多个表。现在,假设我们对active⼯作表中的数据⽐较感兴趣——当⽤户在他们的应⽤中打开⽂件就会看到的⼯作表:
sheet = wb.active
这实际上是⽂档中最常⽤的表。我们可以⽤不同的⽅法访问表格中的数据。我们可以使⽤Pythonic⽣成器每次处理⼀⾏数据
(1)对⾏进⾏遍历:
for row ws():
# Do something with the row
rows()产⽣的⾏,本⾝就是⼀个⽣成器,我们可以遍历它们:
for row ws():
for cell in row:
# Do something with the cell
还可以根据索引访问数据:
for row ws():
header = row[2]
实际上,表格本⾝就是可以按⾏进⾏迭代的,所以我们可以忽略所有⾏:
for row in sheet:
pass
(2)使⽤cols⽅法对列进⾏遍历。
for col ls():
# Use the column
遍历列与遍历⾏的操作基本相同:它们本⾝都是可迭代的,并且可以通过索引寻址。rows函数的使用方法及实例
(3)通过地址访问单元格。
如果我们需要某个单元格中的数据,那么并不需要遍历整个表格去;可以使⽤excel样式的坐标来访问这个单元格:
cell = sheet['C5']
在随后的章节中,将展⽰如何从⼀⾏,⼀列,或者⼀些单元格中获取⼀个⽣成器。
3.处理单元格
在任何情况下,想要处理电⼦表格中的数据,就必须访问每个单元格。在Openpyxl中,单元格有⼀个值和许多仅⽤于编写的其他信息,⽐如样式信息。更⽅便地是,我们可以把单元格中的值作为Python对象(数字、⽇期、字符串等),⽤Openpyxl将它们转换为Excel类型。因此,单元格内容就不⼀定要是字符串。例如,我们以数字的形式读取单元格的内容:
tax_percentage = sheet['H16'].value
tax_amount = taxable_amount * tax_percentage
然⽽,我们并不能保证⽤户⼀定在单元格中输⼊了数字;如果它包含字符串"bug",如果⽐较幸运的话,在运⾏上⾯的代码后,我们会得到⼀个运⾏错误:
TypeError: can't multiply sequence by non-int of type 'float'
然⽽,在不那么幸运的情况下,例如,当taxable_amount是⼀个整数时——因为我们在⽰例中处理的数据是钱,所以应该是整数——我们将得到⼀个重复taxable_amount次的“bug”。这是因为Python把*操作符当成了字符串,整数就意味着“重复字符串n次”。这可能会导致进⼀步的类型错误,或者在Python⽆法放置如此⼤的字符串时出现内存错误。因此,我们应该验证程序的输⼊,包括Excel⽂件。在这个特殊的例⼦中,我们可以使⽤Python的isinstance函数来检查单元格中值的类型:
if isinstance(cell.value, numbers.Number):
# Use the value
我们还可以询问单元格它存储的数据类型是什么:
if cell.data_type == TYPE_NUMERIC:
# Use the numeric value
4.单元格⾼级寻址
到⽬前为⽌,我们已经使⽤了访问单元格最简单、最直接的⽅法。然⽽,这并不是所有⽅法;让我们来看看更复杂的⽅案。
(1)除了active之外的其他表。
我们可以通过在workbook中通过名称来访问它们:
sheet = wb['2020 Report']
然后我们就可以像之前看到的那样访问单元格了。
(2)单元格范围
我们不⼀定要⼀个⼀个的寻址单元格-还可以设定范围来访问单元格:
sheet['D']是指⼀整⾏(本例中是D这⼀⾏)
sheet[7]是指⼀整列(本例中是第7列)
sheet['B:F']代表许多⾏
sheet['4:10'] 代表许多列
sheet['C3:H5']是最通⽤的选择,代表任意范围的单元格
以上任何⼀种情况,结果都是⼀个按⾏迭代所有单元格(除⾮迭代的范围以列为标准,在这种情况下,单元格按列顺序进⾏迭代):
for cell in sheet['B2:F10']:
# B2, B3, ..., F1, F2, ..., F10
for cell in sheet['4:10']:
# A4, B4, ..., A10, B10, ...
sheet['B2:F10']中的单元格
sheet['4:10']中的单元格
5.单元格迭代器
如果上述寻址⽅案解决不了问题,那我们可以考虑⼀些简单的⽅法iter_rows和iter_columns,它们分别按⾏和列返回单元格⽣成器。需要指出,这些⽅法都需要5个参数:
min_row - 起始⾏的编号(1就是A,2就是B,以此类推)
min_col - 起始列的编号
max_row - 最后⼀⾏的编号
max_col - 最后⼀列的编号
values_only - ⽣成器将只显⽰每个单元格的值,⽽不是整个单元格对象。所以,我们不需要⽤cell.value,⽽只要value。另⼀⽅⾯,我们不能访问单元格的其他属性,⽐如data_type。例如,如果我们想按列在B2:F10的范围上进⾏迭代,可以这样写:
for cell in sheet.iter_columns(min_row=2, min_col=2, max_row=6, max_col=10):
# Use the cell
6.编写⼀个Excel⽂件
要写⼀个Excel⽂件,我们只需在workbook上调⽤save⽅法:
wb.save('someFile.xlsx')
知道如何保存⼀个workbook后,让我们看看如何修改它,这将会很有趣。我们可以修改⽂件中的workbook,也可以修改在Python中创建的workbook。
7.修改单个单元格
我们可以⽤指定的⽅式来改变⼀个单元格中的值:
cell.value = 42
这会⾃动更新单元格的数据类型以存储新的值。除了基本类型(整数、浮点数、字符串)之外,还包括datetime模块中的各种类,如果你安装了NumPy,那么NumPy数字类型也可以使⽤。不仅可以设置值和类型,我们还可以设置单元格的其他属性,特别是样式信息(字体、颜⾊等),这对做⼀个好看的报告很有⽤。
Openpyxl的⽂档中有许多关于调整样式的详细信息,我们可以在这⾥查询:
adthedocs.io/en/stable/styles.html
8.添加或移除表格
到⽬前为⽌,我们已经看到了如何处理⼀些对象,特别是workbooks和worksheets——就像处理字典⼀样,访问其中的细节:⼯作表、⾏、列、单个单元格、单元格范围。现在,我们将学习如何添加新信息,以及如何更改现有信息。我们先从表格开始。
使⽤ create_sheet⽅法来创建worksheet:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论