如何使用 Python openpyxl 包自动筛选 Excel 数据?openpyxl AutoFilter 对象介绍
由于 Pythonopenpyxl
包自身的实现问题,本节内容不涉及 Excel 中颜色筛选,图标筛选,动态筛选,前十筛选。
Python openpyxl 包中的 Excel 自动筛选对象 AutoFilter
Pythonopenpyxl
包中的AutoFilter
类,属于模块openpyxl.worksheet.filters
,用于表示 Excel 工作表的自动筛选功能。由于自动筛选功能相对复杂,因此,openpyxl.worksheet.filters
模块还包含了FilterColumn
,Filters
等重要的类,他们对应了 Excel 工作表中某个列的自动筛选。
可能需要重新应用 Excel 文件中的自动筛选功能才能看到实际效果
如果通过 Pythonopenpyxl
包的AutoFilter
对象对 Excel 工作表中的自动筛选功能做出了修改和调整,那么可能需要在相关 Office 软件中重新应用 Excel 文件中的自动筛选功能才能看到修改和调整的效果。
Excel 工作表的自动筛选功能
在 Office 软件中,Excel 工作表的自动筛选功能可以让用户仅关注某些数据,该功能按照列的方式进行,你可以选择在某一列显示或隐藏一些内容。
使用 Python openpyxl 包的 Worksheet 对象获取和设置 Excel 工作表中的自动筛选
Pythonopenpyxl
包的Worksheet
对象的auto_filter
变量是一个AutoFilter
对象,他对应了 Excel 工作表中的自动筛选功能。
worksheet.auto_filter
使用 Python openpyxl 包的 AutoFilter 对象获取和设置自动筛选的 Excel 区域
Pythonopenpyxl
包的AutoFilter
对象的ref
变量可以是一个字符串,用于表示 Excel 工作表中进行自动筛选的区域,比如A1:C1
表示对 Excel 工作表的前三列进行自动筛选。需要指出的是,一些 Office 软件仅会考虑ref
包含的列,不会考虑包含了多少行,因此,区域A1:C3
与区域A1:C1
的效果是相同的。
worksheet.auto_filter.ref
worksheet.auto_filter.ref = range
- range 值
range
是表示需要进行自动筛选的 Excel 区域的字符串,比如A1:C1
。
未包含在 AutoFilter 对象的 ref 变量所表示的 Excel 区域的列将不会进行自动筛选
如果一个列未被包含在openpyxl
Worksheet
对象的auto_filter.ref
变量所表示的 Excel 区域中,那么该列将不会进行自动筛选,即便他之前进行了自动筛选。
因此,通过openpyxl
AutoFilter
对象的ref
变量,你可以启用或禁用某个 Excel 列的自动筛选功能。
在下面的示例中,我们通过ref
变量将 Excel 工作表的第一列和第二列设置为自动筛选区域,而第三列将被取消自动筛选。
# 打开 Data.xlsx 中的工作表 Trees
from openpyxl import load_workbook
workbook = load_workbook('Data.xlsx')
worksheet = workbook['Trees']
# 设置对 A,B 两列进行自动筛选
worksheet.auto_filter.ref = 'A1:B1'
workbook.save('Ref.xlsx')
使用 Python openpyxl 包的 FilterColumn 对象为 Excel 列创建自动筛选
Pythonopenpyxl
包中的FilterColumn
类,属于模块openpyxl.worksheet.filters
,用于表示 Excel 工作表中某个列的自动筛选功能,你可以创建一个FilterColumn
对象,并将其添加至 Excel 工作表对象中,以设置相关列的自动筛选,具体可以参考为列添加自动筛选一段。
以下是openpyxl
包的FilterColumn
类的构造器。
FilterColumn(colId=None, hiddenButton=False, showButton=True, filters=None, top10=None, customFilters=None, dynamicFilter=None, colorFilter=None, iconFilter=None, extLst=None, blank=None, vals=None)
- colId 参数
colId
参数为 Excel 列的索引,0
表示第一列。- hiddenButton 参数
hiddenButton
参数的作用尚不明确。- showButton 参数
showButton
参数表示是否在相关的 Excel 列显示筛选按钮,如果设置为True
,则显示筛选按钮。- filters 参数
filters
参数是一个表示普通筛选条件的Filters
对象。- top10 参数
top10
参数是一个表示前十筛选条件的Top10
对象。- customFilters 参数
customFilters
参数是一个表示自定义筛选条件的CustomFilters
对象。- dynamicFilter 参数
dynamicFilter
参数是一个表示动态筛选条件的DynamicFilter
对象。- colorFilter 参数
colorFilter
参数是一个表示颜色筛选条件的ColorFilter
对象。- iconFilter 参数
iconFilter
参数是一个表示图标筛选条件的IconFilter
对象。- extLst 参数
extLst
参数的作用尚不明确。- blank 参数
blank
参数表示是否将空单元格视为符合筛选条件,如果设置为True
,则会将空单元格视为符合条件。该参数将覆盖filters
参数所表示的Filters
对象的blank
变量。- vals 参数
vals
参数是一个 Python 序列对象,如果某个 Excel 单元格的值与序列中的某个项相同,那么该单元格是符合筛选条件的。该参数将覆盖filters
参数所表示的Filters
对象的filter
变量。
Python openpyxl 包的 FilterColumn 对象的变量
Pythonopenpyxl
包的FilterColumn
对象拥有一些变量,在未作出修改时,他们的值和名称与FilterColumn
构造器的参数相同。
另外,FilterColumn
对象拥有与colId
变量作用相同的col_id
变量(别名)。
Pythonopenpyxl
包的FilterColumn
对象的构造器涉及到了名称为Filters
的类,该类属于模块openpyxl.worksheet.filters
,用于表示 Excel 自动筛选的具体筛选条件,其构造器如下。
Filters(blank=None, calendarType=None, filter=(), dateGroupItem=())
- blank 参数
blank
参数表示是否将空单元格视为符合筛选条件,如果设置为True
,则会将空单元格视为符合条件。- calendarType 参数
calendarType
参数的作用尚不明确。- filter 参数
filter
参数是一个 Python 序列对象,如果某个 Excel 单元格的值与序列中的某个项相同,那么该单元格是符合筛选条件的。- dateGroupItem 参数
dateGroupItem
参数的作用尚不明确。
Python openpyxl 包的 Filters 对象的变量
Pythonopenpyxl
包的Filters
对象拥有一些变量,在未作出修改时,他们的值和名称与Filters
构造器的参数相同。
使用 Python openpyxl 包的 AutoFilter 对象为 Excel 列添加自动筛选
通过 Pythonopenpyxl
包的AutoFilter
对象的add_filter_column
方法,可以简单的为 Excel 工作表中的某个列添加自动筛选。
worksheet.auto_filter.add_filter_column(col_id, vals, blank=False)
- col_id 参数
colId
参数为 Excel 列的索引,0
表示第一列。- vals 参数
vals
参数是一个 Python 序列对象,如果某个 Excel 单元格的值与序列中的某个项相同,那么该单元格是符合筛选条件的。- blank 参数
blank
参数表示是否将空单元格视为符合筛选条件,如果设置为True
,则会将空单元格视为符合条件。
通过 Pythonopenpyxl
包的AutoFilter
对象的filterColumn.append
方法,可以为 Excel 工作表中的某个列添加更为复杂的自动筛选。
worksheet.auto_filter.filterColumn.append(filterColumn)
- filterColumn 参数
filterColumn
参数是一个FilterColumn
对象,表示了某个 Excel 列的自动筛选功能。
在下面的示例中,我们通过不同的方式为 Excel 工作表的列A
,D
添加了自动筛选。
# 打开 Data.xlsx 中的工作表 Trees
from openpyxl import load_workbook
wb = load_workbook('Data.xlsx')
ws = wb['Trees']
from openpyxl.worksheet.filters import FilterColumn, Filters
af = ws.auto_filter
# 为第一列添加自动筛选
f = Filters(filter=('苹果树', '梨树'))
# 将覆盖之前在 Filters 中设置的 filter
fc = FilterColumn(0, filters=f, blank=True, vals=('大树', '柳树'))
af.filterColumn.append(fc)
# 选出第四列中值为 3,3.5 的单元格或空单元格
af.add_filter_column(3, [3, 3.5], True)
# 将第一和第四列包含在进行自动筛选的区域中
af.ref = 'A1:D1'
# 在保存的 Excel 文件中,可能需要重新应用自动筛选才能看到效果
wb.save('Add.xlsx')
同一个 Excel 列可以拥有多个 Python openpyxl 包的 FilterColumn 对象
在 Excel 工作表中,同一个 Excel 列可以对应多个 Pythonopenpyxl
包的FilterColumn
对象,这些FilterColumn
对象之间可能会发生冲突。比如,假设列A
拥有两个FilterColumn
对象,一个包含普通筛选条件,一个包含颜色筛选条件,那么他们可以同时生效,如果两个FilterColumn
对象均是普通筛选条件,那么只有其中之一是有效的。当然,具体情况可能因 Office 软件的不同而不同。
在下面的示例中,我们为 Excel 工作表中的列B
添加了两个FilterColumn
对象,但在 Excel 文件AddMulti.xlsx
中,只有一个是有效的。
# 打开 Data.xlsx 中的工作表 Trees
from openpyxl import load_workbook
workbook = load_workbook('Data.xlsx')
worksheet = workbook['Trees']
af = worksheet.auto_filter
# 选出第二列中值为 20 的单元格或空单元格
af.add_filter_column(1, [20], True)
# 选出第二列中值为 15 的单元格
af.add_filter_column(1, [15], False)
workbook.save('AddMulti.xlsx')
使用 Python openpyxl 包的 AutoFilter 对象为 Excel 列修改或移除(删除)自动筛选
Pythonopenpyxl
包并没有直接提供用于修改或移除(删除)Excel 列中的自动筛选的方法或函数,要完成此目标,你可以遍历AutoFilter
对象的filterColumn
变量所表示的 Python 列表,对其中符合条件的FilterColumn
对象进行修改或移除。
在下面的示例中,我们移除了 Excel 工作表第二列的自动筛选,并修改了第一列的自动筛选。
# 打开 Data.xlsx 中的工作表 Teachers
from openpyxl import load_workbook
workbook = load_workbook('Data.xlsx')
worksheet = workbook['Teachers']
# 选出与第二列有关的所有 FilterColumn 对象
fcs = worksheet.auto_filter.filterColumn
del_fcs = [x for x in fcs if x.colId == 1]
# 移除与第二列有关的 FilterColumn 对象
for fc in del_fcs:
fcs.remove(fc)
# 修改第一列的 FilterColumn 对象
for fc in fcs:
if fc.colId == 0:
fc.filters.filter = ('大刚', '小刚')
# 在保存的 Excel 文件中,可能需要重新应用自动筛选才能看到效果
workbook.save('Change.xlsx')
使用 Python openpyxl 包的 CustomFilters 对象为 Excel 列创建自定义筛选
使用 Pythonopenpyxl
包的FilterColumn
类的构造器中的customFilters
参数,你可以为 Excel 列创建自定义筛选,以设置较为复杂的筛选条件,比如,值大于1
并小于10
的 Excel 单元格。
参数customFilters
是类CustomFilters
的实例,该类属于模块openpyxl.worksheet.filters
,用于表示一组自定义筛选条件,而组中的每一个自定义筛选条件均对应了CustomFilter
类或其派生类的实例。
CustomFilters(_and=None, customFilter=())
- _and 参数
_and
参数表示自定义筛选条件(CustomFilter
对象)之间的逻辑关系,如果设置为True
,则自定义筛选条件之间的逻辑关系为and
(与),否则为or
(或)。需要说明的是,当你设置了多个筛选条件,并且这些筛选条件的逻辑关系既有and
也有or
时,那么某些筛选条件可能无法生效或被保存。- customFilter 参数
customFilter
参数是一个 Python 序列对象,该对象包含一组表示自定义筛选条件的CustomFilter
对象。
CustomFilter(operator="equal", val=None)
- operator 参数
operator
参数是一个字符串,表示了与自定义筛选条件相关的运算方式,可以是以下取值之一。'equal'
(等于),'lessThan'
(小于),'lessThanOrEqual'
(小于等于),'notEqual'
(不等于),'greaterThanOrEqual'
(大于等于),'greaterThan'
(大于)。- val 参数
val
参数是表示与自定义筛选条件相关的值的字符串,该字符串可以针对 Excel 单元格中的数字或文字内容,比如,如果需要选出数字大于3
的 Excel 单元格,则val
参数可以被设置为'3'
,如果需要选出文字等于小明
的 Excel 单元格,则val
参数可以被设置为'小明'
。
在下面的示例中,我们为 Excel 工作表的第一和第二列添加了自定义筛选,虽然第二列的单元格的内容为数字,但CustomFilter
的val
参数依然要写为'9'
和'11'
。
# 打开 Data.xlsx 中的工作表 Games
from openpyxl import load_workbook
wb = load_workbook('Data.xlsx')
ws = wb['Games']
from openpyxl.worksheet.filters import FilterColumn, CustomFilter, CustomFilters
# 选出数字内容大于 9 并且 小于等于 11 的 Excel 单元格
cfs = CustomFilters(True, [
CustomFilter('greaterThan', '9'),
CustomFilter('lessThanOrEqual', '11')
])
# 为工作表的第二列设置自定义筛选
fc = FilterColumn(1, customFilters=cfs)
ws.auto_filter.filterColumn.append(fc)
# 选出第一列中文字内容不等于 疯狂自行车 的 Excel 单元格
cfs = CustomFilters(customFilter=[CustomFilter('notEqual', '疯狂自行车')])
ws.auto_filter.filterColumn.append(FilterColumn(0, customFilters=cfs))
# 在保存的 Excel 文件中,可能需要重新应用自动筛选才能看到效果
wb.save('Custom.xlsx')
Pythonopenpyxl
包的NumberFilter
是CustomFilter
的派生类,虽然CustomFilter
也可以完成数字运算,但NumberFilter
更为明确。
NumberFilter(operator="equal", val=None)
- operator 参数
operator
参数与CustomFilter
构造器中的operator
参数的作用相同。- val 参数
val
参数与CustomFilter
构造器中的val
参数的作用类似,但他是浮点数类型。
Pythonopenpyxl
包的StringFilter
是CustomFilter
的派生类,用于完成较为复杂的字符串运算。
StringFilter(operator="contains", val=None, exclude=False)
- operator 参数
operator
参数与CustomFilter
构造器中的operator
参数的作用类似,可以是以下取值之一。'contains'
(包含某些字符串),'startswith'
(以某些字符串开始),'endswith'
(以某些字符串结束),'wildcard'
(采用通配符)。- val 参数
val
参数与CustomFilter
构造器中的val
参数的作用相同。- exclude 参数
exclude
参数是一个布尔值,如果为True
,则将运算结果为假的 Excel 单元格视为是符合条件的。
Pythonopenpyxl
包的BlankFilter
是CustomFilter
的派生类,用于排除 Excel 列中的空单元格。
BlankFilter(**kw)
我们调整之前的示例,使用NumberFilter
和StringFilter
来完成 Excel 列的自动筛选,由于将exclude
参数设置为了True
,因此将选出第一列中不包含不
的 Excel 单元格。
# 打开 Data.xlsx 中的工作表 Games
from openpyxl import load_workbook
wb = load_workbook('Data.xlsx')
ws = wb['Games']
from openpyxl.worksheet.filters import FilterColumn, CustomFilters, NumberFilter, StringFilter
# 选出数字内容大于等于 10 或 小于等于 11 的 Excel 单元格
cfs = CustomFilters(True, [
NumberFilter('greaterThanOrEqual', 10),
NumberFilter('lessThanOrEqual', 11)
])
# 为工作表的第二列设置自定义筛选
fc = FilterColumn(1, customFilters=cfs)
ws.auto_filter.filterColumn.append(fc)
# 选出第一列中文字内容不包含 不 的 Excel 单元格
cfs = CustomFilters(customFilter=[StringFilter('contains', '不', True)])
ws.auto_filter.filterColumn.append(FilterColumn(0, customFilters=cfs))
# 在保存的 Excel 文件中,可能需要重新应用自动筛选才能看到效果
wb.save('NumStr.xlsx')
使用 Python openpyxl 包的 CustomFilter 对象为 Excel 列创建包含通配符的自定义筛选
在使用 Pythonopenpyxl
包的CustomFilter
或StringFilter
类为 Excel 列创建自定义筛选的过程中,你可以为其构造器的val
参数指定通配符,比如,*
表示多个任意字符,?
表示单个任意字符。而要使通配符产生预期效果,CustomFilter
和StringFilter
对象需要被指定正确的operator
参数,比如,为CustomFilter
指定'equal'
或'notEqual'
,为StringFilter
指定'wildcard'
。
此外,openpyxl
CustomFilter
和StringFilter
对象中的通配符不仅可以匹配 Excel 单元格中的文字内容,也可以匹配单元格中的数字内容。
Python openpyxl 包的 CustomFilter 对象中的通配符可能会被转换
在为openpyxl
包的CustomFilter
对象指定通配符之后,这些通配符可能会被转换,比如,表达式CustomFilter('equal','*自?车*')
中的*自?车*
,最终在 Excel 文件中显示为自.车
。
在下面的示例中,Excel 工作表Games
的第一列包含文字,第二列包含数字,表达式CustomFilter('equal','*自?车*')
将选出包含由自
,车
以及一个任意字符组成的单词的 Excel 单元格,表达式StringFilter('wildcard','?')
将选出包含个位数的 Excel 单元格。
# 打开 Data.xlsx 中的工作表 Games
from openpyxl import load_workbook
wb = load_workbook('Data.xlsx')
ws = wb['Games']
from openpyxl.worksheet.filters import FilterColumn, CustomFilters, CustomFilter, StringFilter
# 选出第一列中文字内容包含 自?车 的单元格
cfs = CustomFilters(customFilter=[CustomFilter('equal', '*自?车*')])
ws.auto_filter.filterColumn.append(FilterColumn(0, customFilters=cfs))
# 选出第二列中包含个位数的单元格
cfs = CustomFilters(customFilter=[StringFilter('wildcard', '?')])
ws.auto_filter.filterColumn.append(FilterColumn(1, customFilters=cfs))
# 在保存的 Excel 文件中,可能需要重新应用自动筛选才能看到效果
wb.save('Wildcards.xlsx')
源码
src/zh/openpyxl/data/filters·codebeatme/office-programming·GitHub