openpyxl表更改表现有(自动)过滤器

时间:2019-10-22 19:33:42

标签: python excel openpyxl

创建表后,Excel会自动为所有列创建过滤器。

然后在我的Python + openpyxl代码中,我想过滤掉一些数据,但是我不知道如何检索和更改此现有过滤器。

考虑我的表可能包含“失败”,“通过”,“跳过”和空白值 而我只想看到“失败”和“通过”。

如果我尝试向表中添加过滤器,它似乎只是被忽略了:

ws.auto_filter.add_filter_column(1,
                                 ["Fail", "Pass"])

稍后添加了一堆数据,并相应地更新了表“ ref”。 不过,在Excel中打开文件会显示所有选定的过滤器值-根本没有过滤器。

有任何线索吗? 谢谢!


更新:

我注意到表对象有其自己的autoFilter字段,因此我认为如果创建AutoFilter并进行相应设置,那将是公平的。 看起来会成功,但是在保存文件时,此过滤器丢失了。

向下挖掘,我发现openpyxl/worksheet/_writer.py处的write_tables(self)正在呼叫table._initialise_columns(),这搞砸了我的过滤器。

好的,所以我也需要初始化我的table.tableColumns属性,而从一个简单任务开始的事情就变成了许多隐藏在函数initialise_columns()initialise_filters()中的样板。

    table = Table(displayName=table_name,
                  ref=ref_range,
                  tableColumns=initialise_columns(),
                  autoFilter=initialise_filters(),
                  **kwargs)
    ws.add_table(table)

现在更改表数据之后,我必须更新两个引用:

    table .ref = ref
    table .autoFilter.ref = ref

好吧,那么它“几乎”起作用了... 我可以使用Excel打开文件而没有任何错误,出现过滤器,我已按预期选择了过滤器值,但未过滤数据。

如果我单击过滤器值(即使此后所选项目相同),则Excel将应用过滤器,结果将与预期相同。

1 个答案:

答案 0 :(得分:1)

<块引用>

我注意到 table 对象有自己的 autoFilter 字段,所以我认为如果我创建一个 AutoFilter 并相应地设置它会公平。看起来它会成功,但保存我的文件时,此过滤器丢失了。

<块引用>

深入研究,我看到 write_tables(self) 中的 openpyxl/worksheet/_writer.py 正在调用 table._initialise_columns() 并搞砸了我的过滤器。

我为该错误找到了一个非常简单的解决方案(变通方法),无需任何额外(重复)代码。是的,我会称之为错误!这个 bug 使得 Table 的构造函数参数 autofilter 没用了。

表的自动筛选仅在您第一次保存工作簿时设置/替换为默认的自动筛选。之后,自动过滤器属性不会被 openpyxl 修改。

workbook.save('table.xlsx')  # 1st time 

table.autoFilter = AutoFilter(ref=table.ref)
table.autoFilter.add_filter_column(0, ['Bananas'])
table.autoFilter.add_sort_condition("B2:B15")

workbook.save('table.xlsx')  # 2nd time

到目前为止,一切都很好......

<块引用>

好吧,那么它“几乎”有效......我可以用 Excel 打开文件,没有错误,过滤器出现,我按预期选择了过滤器值,但数据没有被过滤。 我也有同样的问题。我用表格和普通工作表对其进行了测试。在这两种情况下,行为相同。

这是错误还是功能?

我查看了 openpyxl 错误跟踪器 :-(

https://foss.heptapod.net/openpyxl/openpyxl/-/issues/1156

覆盖自动过滤器的问题(有一个简单的解决方案)已经存在两年多了 :-(