sc/qa/unit/data/ods/tdf123225_pivotTable_row_col_items.ods |binary sc/qa/unit/pivottable_filters_test.cxx | 36 ++++++++++++ sc/source/filter/excel/xepivotxml.cxx | 39 ++++++++++++- 3 files changed, 74 insertions(+), 1 deletion(-)
New commits: commit 02398c20b206c016f210705f6de312c1eecf0d19 Author: Bayram Çiçek <bayram.ci...@collabora.com> AuthorDate: Mon Feb 17 18:38:07 2025 +0300 Commit: Caolán McNamara <caolan.mcnam...@collabora.com> CommitDate: Thu Feb 20 09:33:05 2025 +0100 tdf#123225 - export <rowItems> and <colItems> of xl/pivotTables/pivotTable*.xml. - additionally, export <i> and <x> with their default attribute values. - <x/> single element has only "v" attribute and its value is increased by 1 up to the count attribute value of rowItems/colItems. - it is expected that this will fix function loss in XLSX pivot table's context menu and there will be no need to refresh the pivot table. (ODS -> XLSX) - this is also fix "Cannot determine which PivotTable field to sort by" warning on Excel if you try to e.g. sort the items - alongside the loss of functions. - add testTdf123225PivotTableRowColItems Cpp unit test Signed-off-by: Bayram Çiçek <bayram.ci...@collabora.com> Change-Id: Id44806e666a55500ba3faeb0571e50e407c15791 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181795 Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com> diff --git a/sc/qa/unit/data/ods/tdf123225_pivotTable_row_col_items.ods b/sc/qa/unit/data/ods/tdf123225_pivotTable_row_col_items.ods new file mode 100644 index 000000000000..c47e083311e5 Binary files /dev/null and b/sc/qa/unit/data/ods/tdf123225_pivotTable_row_col_items.ods differ diff --git a/sc/qa/unit/pivottable_filters_test.cxx b/sc/qa/unit/pivottable_filters_test.cxx index 5bc3970d022c..276dcd324248 100644 --- a/sc/qa/unit/pivottable_filters_test.cxx +++ b/sc/qa/unit/pivottable_filters_test.cxx @@ -125,6 +125,42 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testPivotTableBasicODS) sal_uInt16(pDim->GetFunction())); } +CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testTdf123225PivotTableRowColItems) +{ + createScDoc("ods/tdf123225_pivotTable_row_col_items.ods"); + save(u"Calc Office Open XML"_ustr); + + xmlDocUniquePtr pSheet = parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr); + CPPUNIT_ASSERT(pSheet); + + // be sure that we have <rowItems> and <colItems> element + // under <pivotTableDefinition> after export of the .ods to .xlsx + + // Row items <rowItems> + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", 1); + // check if <rowItems count="8"> + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", "count", u"8"); + // check if <rowItems> has enough <i> depending on count attribute value + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i", 8); + // check if first <i> has single <x/> element + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x", 1); + // check if <x/> of the first <i> element, has v="0" attribute value + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x", "v", u"0"); + + // Column items <colItems> + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", 1); + // check if <colItems count="5"> + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", "count", u"5"); + // check if <colItems> has enough <i> depending on count attribute value + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i", 5); + // check if first <i> has single <x/> element + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x", 1); + // check if <x/> of the first <i> element, has v="0" attribute value + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x", "v", u"0"); +} + CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testPivotTableNamedRangeSourceODS) { createScDoc("ods/pivot-table-named-range-source.ods"); diff --git a/sc/source/filter/excel/xepivotxml.cxx b/sc/source/filter/excel/xepivotxml.cxx index 90f58aebc574..c0c9946fa8b5 100644 --- a/sc/source/filter/excel/xepivotxml.cxx +++ b/sc/source/filter/excel/xepivotxml.cxx @@ -776,6 +776,8 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP std::vector<tools::Long> aPageFields; std::vector<DataField> aDataFields; + tools::Long nRowItemsCount = 0; // for <rowItems count="..."> of pivotTable*.xml + tools::Long nColItemsCount = 0; // for <colItems count="..."> of pivotTable*.xml tools::Long nDataDimCount = rSaveData.GetDataDimensionCount(); // Use dimensions in the save data to get their correct ordering. // Dimension order here is significant as they specify the order of @@ -1055,8 +1057,15 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP pAttList->add( XML_outline, ToPsz10(false)); pPivotStrm->startElement(XML_pivotField, pAttList); + tools::Long nItemsCount + = static_cast<tools::Long>(aMemberSequence.size() + aSubtotalSequence.size()); pPivotStrm->startElement(XML_items, - XML_count, OString::number(static_cast<tools::Long>(aMemberSequence.size() + aSubtotalSequence.size()))); + XML_count, OString::number(nItemsCount)); + + if (strcmp(toOOXMLAxisType(eOrient), "axisCol") == 0) + nColItemsCount = nItemsCount; + else + nRowItemsCount = nItemsCount; for (const auto & nMember : aMemberSequence) { @@ -1094,6 +1103,20 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP } // <rowItems> + if (nRowItemsCount > 0) + { + pPivotStrm->startElement(XML_rowItems, XML_count, OString::number(nRowItemsCount)); + + // export nRowItemsCount times <i> and <x> elements + for (tools::Long nCount = 0; nCount < nRowItemsCount; ++nCount) + { + pPivotStrm->startElement(XML_i); + pPivotStrm->singleElement(XML_x, XML_v, OString::number(nCount)); + pPivotStrm->endElement(XML_i); + } + + pPivotStrm->endElement(XML_rowItems); + } // <colFields> @@ -1111,6 +1134,20 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP } // <colItems> + if (nColItemsCount > 0) + { + pPivotStrm->startElement(XML_colItems, XML_count, OString::number(nColItemsCount)); + + // export nColItemsCount times <i> and <x> elements + for (tools::Long nCount = 0; nCount < nColItemsCount; ++nCount) + { + pPivotStrm->startElement(XML_i); + pPivotStrm->singleElement(XML_x, XML_v, OString::number(nCount)); + pPivotStrm->endElement(XML_i); + } + + pPivotStrm->endElement(XML_colItems); + } // <pageFields>