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 a4460b67b7c5273b62cf8597dedbbb2850c97489
Author:     Bayram Çiçek <bayram.ci...@collabora.com>
AuthorDate: Wed Mar 5 13:40:08 2025 +0300
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Tue Mar 18 11:39:07 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/+/183063
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>

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 9c710bcd5324..1baaca95568e 100644
--- a/sc/qa/unit/pivottable_filters_test.cxx
+++ b/sc/qa/unit/pivottable_filters_test.cxx
@@ -234,6 +234,29 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, 
testTdf123225PivotTableNoColItems)
     assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i/x:x"_ostr, 
"v"_ostr, "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"_ostr, 1);
+    // check if <rowItems count="4">
+    assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems"_ostr, 
"count"_ostr, "4");
+
+    // Column items <colItems>
+
+    assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems"_ostr, 1);
+    // check if <colItems count="5">
+    assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems"_ostr, 
"count"_ostr, "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 66bebb04865a..41ec742a7fa1 100644
--- a/sc/source/filter/excel/xepivotxml.cxx
+++ b/sc/source/filter/excel/xepivotxml.cxx
@@ -861,6 +861,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;
@@ -1058,15 +1064,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)
         {
@@ -1077,6 +1076,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);

Reply via email to