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>
 

Reply via email to