sc/qa/unit/data/ods/tdf123225_pivotTable_empty_row_col_items.ods |binary sc/qa/unit/pivottable_filters_test.cxx | 23 ++++++++++ sc/source/filter/excel/xepivotxml.cxx | 20 +++++--- 3 files changed, 35 insertions(+), 8 deletions(-)
New commits: commit fea8bccf636de423c4f1fef1468d295e4f91aee6 Author: Bayram Çiçek <bayram.ci...@collabora.com> AuthorDate: Wed Mar 5 13:40:08 2025 +0300 Commit: Bayram Çiçek <bayram.ci...@collabora.com> CommitDate: Mon Mar 17 04:55:56 2025 +0100 tdf#123225 - calculate count attribute correctly in xl/pivotTables/pivotTable*.xml we have e.g. <location ref="A3:B6" firstHeaderRow="1" firstDataRow="1" firstDataCol="1" rowPageCount="1" colPageCount="1"/> - the 'ref' attribute indicates the cell range of a pivot table. - 'firstDataRow' specifies the first row of the PivotTable data, relative to the top left cell in the ref value. - 'firstDataCol' specifies the first column of the PivotTable data, relative to the top left cell in the ref value. if we get the number of rows and cols in the pivot table (using <location ref="..."), and substract 'firstDataRow' & 'firstDataCol' from it, we get the correct count attr. value of <row/colItems> during export from ODS -> XLSX. - added testTdf123225PivotTableEmptyRowColItems Cppunit test to make sure that export works with empty row/col items. Signed-off-by: Bayram Çiçek <bayram.ci...@collabora.com> Change-Id: Ia85a89e429d95492f0f753af3fbf46771d1a2a0f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182529 Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com> Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> (cherry picked from commit 765bf4bff2b8d4ed9569e735dc663ac55ae7a424) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183018 diff --git a/sc/qa/unit/data/ods/tdf123225_pivotTable_empty_row_col_items.ods b/sc/qa/unit/data/ods/tdf123225_pivotTable_empty_row_col_items.ods new file mode 100644 index 000000000000..fba4bc00d3ab Binary files /dev/null and b/sc/qa/unit/data/ods/tdf123225_pivotTable_empty_row_col_items.ods differ diff --git a/sc/qa/unit/pivottable_filters_test.cxx b/sc/qa/unit/pivottable_filters_test.cxx index fe33c66d447c..1c17f569deec 100644 --- a/sc/qa/unit/pivottable_filters_test.cxx +++ b/sc/qa/unit/pivottable_filters_test.cxx @@ -233,6 +233,29 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testTdf123225PivotTableNoColItems) assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i/x:x", "v", u"0"); } +CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testTdf123225PivotTableEmptyRowColItems) +{ + // this doc contains blank row/col items + // <sharedItems containsBlank="1" count="..."> (xl/pivotCache/pivotCacheDefinition1.xml) + createScDoc("ods/tdf123225_pivotTable_empty_row_col_items.ods"); + save(u"Calc Office Open XML"_ustr); + + xmlDocUniquePtr pSheet = parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr); + CPPUNIT_ASSERT(pSheet); + + // Row items <rowItems> + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", 1); + // check if <rowItems count="4"> + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", "count", u"4"); + + // Column items <colItems> + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", 1); + // check if <colItems count="5"> + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", "count", u"5"); +} + 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 65e5d9c61839..f48569f32faa 100644 --- a/sc/source/filter/excel/xepivotxml.cxx +++ b/sc/source/filter/excel/xepivotxml.cxx @@ -863,6 +863,12 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP // NB: Excel's range does not include page field area (if any). ScRange aOutRange = rDPObj.GetOutputRangeByType(sheet::DataPilotOutputRangeType::TABLE); + // normalize the order to prevent negative row/col counts - just in case. + aOutRange.PutInOrder(); + // both start and end cells are included. subtraction excludes the start cells, therefore add +1. + SCROW pivotTableRowCount = aOutRange.aEnd.Row() - aOutRange.aStart.Row() + 1; + SCCOL pivotTableColCount = aOutRange.aEnd.Col() - aOutRange.aStart.Col() + 1; + sal_Int32 nFirstHeaderRow = rDPObj.GetHideHeader() ? 0 : (rDPObj.GetHeaderLayout() ? 2 : 1); sal_Int32 nFirstDataRow = rDPObj.GetHideHeader() ? 1 : 2; sal_Int32 nFirstDataCol = 1; @@ -1060,15 +1066,8 @@ 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(nItemsCount)); - - if (strcmp(toOOXMLAxisType(eOrient), "axisCol") == 0) - nColItemsCount = nItemsCount; - else if (strcmp(toOOXMLAxisType(eOrient), "axisRow") == 0) - nRowItemsCount = nItemsCount; + XML_count, OString::number(static_cast<tools::Long>(aMemberSequence.size() + aSubtotalSequence.size()))); for (const auto & nMember : aMemberSequence) { @@ -1079,6 +1078,11 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP pPivotStrm->singleElement(XML_item, pItemAttList); } + if (strcmp(toOOXMLAxisType(eOrient), "axisCol") == 0) + nColItemsCount = pivotTableColCount - nFirstDataCol; + else if (strcmp(toOOXMLAxisType(eOrient), "axisRow") == 0) + nRowItemsCount = pivotTableRowCount - nFirstDataRow; + for (const OString& sSubtotal : aSubtotalSequence) { pPivotStrm->singleElement(XML_item, XML_t, sSubtotal);