sc/qa/unit/data/xls/forum-mso-en4-147004.xls |binary
 sc/qa/unit/subsequent_export_test2.cxx       |   18 ++++++++++++++++++
 sc/source/filter/excel/xepivotxml.cxx        |   26 ++++++++++++++++++++++++--
 3 files changed, 42 insertions(+), 2 deletions(-)

New commits:
commit 2f88281720a712aefa61656aed09a93753358f75
Author:     Ujjawal Kumar <[email protected]>
AuthorDate: Fri Mar 6 00:22:57 2026 +0530
Commit:     Miklos Vajna <[email protected]>
CommitDate: Fri Mar 6 15:48:15 2026 +0100

    ooxml: Don't write pivot tables if no pivot fields are available
    
    Bug documnet: forum-mso-en4-147004.xls
    
    The above document when exported to xlsx contains
    pivot tables with no pivot field under it which
    excel considers as an error.
    
    Change-Id: Ia92bb50b466d73efbbfcb0ffbb4e6c00dd5d6f25
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/201067
    Reviewed-by: Miklos Vajna <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>

diff --git a/sc/qa/unit/data/xls/forum-mso-en4-147004.xls 
b/sc/qa/unit/data/xls/forum-mso-en4-147004.xls
new file mode 100644
index 000000000000..ff29e1131ae9
Binary files /dev/null and b/sc/qa/unit/data/xls/forum-mso-en4-147004.xls differ
diff --git a/sc/qa/unit/subsequent_export_test2.cxx 
b/sc/qa/unit/subsequent_export_test2.cxx
index 9c64fc917fbf..5f5563e82153 100644
--- a/sc/qa/unit/subsequent_export_test2.cxx
+++ b/sc/qa/unit/subsequent_export_test2.cxx
@@ -1532,6 +1532,24 @@ CPPUNIT_TEST_FIXTURE(ScExportTest2, testTdf137543XLSX)
         u"_xlfn.LET(_xlpm.first,B5:E15,_xlfn.CHOOSEROWS(_xlpm.first, 1, 3, 5, 
7, 9, 11))");
 }
 
+CPPUNIT_TEST_FIXTURE(ScExportTest2, testEmptyPivotFieldsTable)
+{
+    createScDoc("xls/forum-mso-en4-147004.xls");
+    save(TestFilter::XLSX);
+
+    xmlDocUniquePtr pDoc = parseExport(u"xl/workbook.xml"_ustr);
+    CPPUNIT_ASSERT(pDoc);
+
+    assertXPath(pDoc, "/x:workbook/x:pivotCaches", 0);
+
+    CPPUNIT_ASSERT_THROW(parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr),
+                         css::container::NoSuchElementException);
+    
CPPUNIT_ASSERT_THROW(parseExport(u"xl/pivotCache/pivotCacheDefinition1.xml"_ustr),
+                         css::container::NoSuchElementException);
+    
CPPUNIT_ASSERT_THROW(parseExport(u"xl/pivotCache/pivotCacheRecords1.xml"_ustr),
+                         css::container::NoSuchElementException);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xepivotxml.cxx 
b/sc/source/filter/excel/xepivotxml.cxx
index 363e8446d947..0118c480115f 100644
--- a/sc/source/filter/excel/xepivotxml.cxx
+++ b/sc/source/filter/excel/xepivotxml.cxx
@@ -144,11 +144,22 @@ XclExpXmlPivotCaches::XclExpXmlPivotCaches( const 
XclExpRoot& rRoot ) :
 void XclExpXmlPivotCaches::SaveXml( XclExpXmlStream& rStrm )
 {
     sax_fastparser::FSHelperPtr& pWorkbookStrm = rStrm.GetCurrentStream();
-    pWorkbookStrm->startElement(XML_pivotCaches);
+    bool bStartedPivotCaches = false;
 
     for (size_t i = 0, n = maCaches.size(); i < n; ++i)
     {
         const Entry& rEntry = maCaches[i];
+        const ScDPCache& rCache = *rEntry.mpCache;
+
+        size_t nFieldCount = rCache.GetFieldCount() + 
rCache.GetGroupFieldCount();
+        if (nFieldCount == 0)
+            continue;
+
+        if (!bStartedPivotCaches)
+        {
+            bStartedPivotCaches = true;
+            pWorkbookStrm->startElement(XML_pivotCaches);
+        }
 
         sal_Int32 nCacheId = i + 1;
         OUString aRelId;
@@ -169,7 +180,8 @@ void XclExpXmlPivotCaches::SaveXml( XclExpXmlStream& rStrm )
         rStrm.PopStream();
     }
 
-    pWorkbookStrm->endElement(XML_pivotCaches);
+    if (bStartedPivotCaches)
+        pWorkbookStrm->endElement(XML_pivotCaches);
 }
 
 void XclExpXmlPivotCaches::SetCaches( std::vector<Entry>&& rCaches )
@@ -673,6 +685,16 @@ void XclExpXmlPivotTables::SaveXml( XclExpXmlStream& rStrm 
)
         sal_Int32 nCacheId = rTable.mnCacheId;
         sal_Int32 nPivotId = rTable.mnPivotId;
 
+        const XclExpXmlPivotCaches::Entry* pCacheEntry = 
mrCaches.GetCache(nCacheId);
+        if (!pCacheEntry)
+                continue;
+
+        const ScDPCache& rCache = *pCacheEntry->mpCache;
+
+        size_t nFieldCount = rCache.GetFieldCount() + 
rCache.GetGroupFieldCount();
+        if (nFieldCount == 0)
+            continue;
+
         sax_fastparser::FSHelperPtr pPivotStrm = rStrm.CreateOutputStream(
             XclXmlUtils::GetStreamName("xl/pivotTables/", "pivotTable", 
nPivotId),
             XclXmlUtils::GetStreamName(nullptr, "../pivotTables/pivotTable", 
nPivotId),

Reply via email to