Excel and LibreOffice both persist the active AutoFilter range as a defined-name of the reserved name _xlnm._FilterDatabase scoped to the owning sheet. python-xlsx's DefinedNameList.from_tree strips all names whose owner is the reserved _xlnm. prefix, so the AutoFilter range is lost and Excel re-inserts a different one (or none) on reopen.
Library verdicts: python-xlsx: — xlsxjs: —
| Feature id | xlsx/preserve-workbook-filter-database |
|---|---|
| Format | xlsx |
| Category | round-trip |
| Spec | ecma-376-5-part-1 § 18.2.5 definedName |
| ID / part | Predicate | XPath | python-xlsx | xlsxjs |
|---|---|---|---|---|
filter-database-defined-name-preservedxl/workbook.xml | existThe _xlnm._FilterDatabase definedName must survive round-trip — it is the durable record of the sheet's active AutoFilter range. | //x:workbook/x:definedNames/x:definedName[@name='_xlnm._FilterDatabase'] | — | — |
filter-database-scope-preservedxl/workbook.xml | existThe localSheetId attribute must survive — a workbook-scoped filter range applies to a different UI affordance than a sheet-scoped one. | //x:workbook/x:definedNames/x:definedName[@name='_xlnm._FilterDatabase']/@localSheetId | — | — |
filter-database-range-preservedxl/workbook.xml | match = Sheet1!\$A\$1:\$A\$3351The cell reference inside the definedName must survive verbatim. Any rewriting invalidates the AutoFilter range. | //x:workbook/x:definedNames/x:definedName[@name='_xlnm._FilterDatabase'] | — | — |
No render assertions declared.
{
"$schema": "../manifest.schema.json",
"id": "xlsx/preserve-workbook-filter-database",
"title": "Preserve <definedName name=\"_xlnm._FilterDatabase\"> across round-trip",
"format": "xlsx",
"category": "round-trip",
"summary": "Excel and LibreOffice both persist the active AutoFilter range as a defined-name of the reserved name _xlnm._FilterDatabase scoped to the owning sheet. python-xlsx's DefinedNameList.from_tree strips all names whose owner is the reserved _xlnm. prefix, so the AutoFilter range is lost and Excel re-inserts a different one (or none) on reopen.",
"roles": [
"authoring"
],
"spec": {
"source": "ecma-376-5-part-1",
"clause": "18.2.5",
"element": "definedName",
"rnc_reference": "spec/ecma-376-5/part-1/rnc/SpreadsheetML.rnc",
"xsd_reference": "spec/ecma-376-5/part-1/xsd/sml.xsd",
"notes": "ECMA-376 Part 1 clause 18.2.5 (definedName) and 18.2.6 (definedNames) cover the workbook-level defined-name table. Clause 18.2.6 lists the reserved _xlnm.* names — _xlnm.Print_Area, _xlnm.Print_Titles, _xlnm.Criteria, _xlnm._FilterDatabase, _xlnm.Extract — every one of which is user-observable through a different UI affordance in Excel (print area, print-title rows, advanced-filter criteria, AutoFilter range, advanced-filter output). python-xlsx's src/xlsx/workbook/defined_name.py treats all _xlnm names as internal and filters them out of the round-trip, which silently breaks those UI affordances. Code: src/xlsx/workbook/defined_name.py::DefinedNameList (idx_base / from_tree filter logic)."
},
"fixtures": {
"machine": "xlsx/preserve-workbook-filter-database"
},
"round_trip": {
"library": "python-xlsx",
"source_fixture": "xlsx/preserve-workbook-filter-database",
"notes": "Source is a copy of python-xlsx's own bundled mac_date.xlsx test fixture — a small LibreOffice-authored workbook carrying a localSheetId=\"0\" _xlnm._FilterDatabase definedName pointing at Sheet1!$A$1:$A$3351."
},
"assertions": [
{
"id": "filter-database-defined-name-preserved",
"part": "xl/workbook.xml",
"namespaces": {
"x": "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
},
"xpath": "//x:workbook/x:definedNames/x:definedName[@name='_xlnm._FilterDatabase']",
"must": "exist",
"description": "The _xlnm._FilterDatabase definedName must survive round-trip — it is the durable record of the sheet's active AutoFilter range."
},
{
"id": "filter-database-scope-preserved",
"part": "xl/workbook.xml",
"namespaces": {
"x": "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
},
"xpath": "//x:workbook/x:definedNames/x:definedName[@name='_xlnm._FilterDatabase']/@localSheetId",
"must": "exist",
"description": "The localSheetId attribute must survive — a workbook-scoped filter range applies to a different UI affordance than a sheet-scoped one."
},
{
"id": "filter-database-range-preserved",
"part": "xl/workbook.xml",
"namespaces": {
"x": "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
},
"xpath": "//x:workbook/x:definedNames/x:definedName[@name='_xlnm._FilterDatabase']",
"must": "match",
"value": "Sheet1!\\$A\\$1:\\$A\\$3351",
"description": "The cell reference inside the definedName must survive verbatim. Any rewriting invalidates the AutoFilter range."
}
]
}
No rendered reference is available for this case.