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),
