sc/qa/unit/data/xlsx/tdf166712.xlsx |binary sc/qa/unit/subsequent_export_test4.cxx | 15 +++++++++++++++ sc/source/filter/excel/excdoc.cxx | 22 ++++++++++++---------- 3 files changed, 27 insertions(+), 10 deletions(-)
New commits: commit c55d85888752f128a7d414963c9d7b8787d1fc48 Author: Aron Budea <aron.bu...@collabora.com> AuthorDate: Sun May 25 13:55:50 2025 +0930 Commit: Bayram Çiçek <bayram.ci...@collabora.com> CommitDate: Mon May 26 06:53:37 2025 +0200 tdf#166712 sc: don't export empty dbPr/olapPr elements to connections.xml Otherwise Excel fails to open the file. Change-Id: I6eec74c48d20f62a3a75f06a4197ef7ead75b446 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185742 Reviewed-by: Bayram Çiçek <bayram.ci...@collabora.com> Tested-by: Jenkins diff --git a/sc/qa/unit/data/xlsx/tdf166712.xlsx b/sc/qa/unit/data/xlsx/tdf166712.xlsx new file mode 100644 index 000000000000..33e2ec951c00 Binary files /dev/null and b/sc/qa/unit/data/xlsx/tdf166712.xlsx differ diff --git a/sc/qa/unit/subsequent_export_test4.cxx b/sc/qa/unit/subsequent_export_test4.cxx index 7709a1451fe2..4ff0ba0e8b4a 100644 --- a/sc/qa/unit/subsequent_export_test4.cxx +++ b/sc/qa/unit/subsequent_export_test4.cxx @@ -2276,6 +2276,21 @@ CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf166413) u"RIGHT(A4,LEN(\"\"\"ABC\"\"\"))=\"\"\"ABC\"\"\""); } +CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf166712) +{ + createScDoc("xlsx/tdf166712.xlsx"); + + save(u"Calc Office Open XML"_ustr); + + xmlDocUniquePtr pConn = parseExport(u"xl/connections.xml"_ustr); + CPPUNIT_ASSERT(pConn); + + // empty dbPr/olapPr mustn't exist in the result's xl/connections.xml + assertXPath(pConn, "/x:connections/x:connection/x:dbPr", 0); + + assertXPath(pConn, "/x:connections/x:connection/x:olapPr", 0); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/filter/excel/excdoc.cxx b/sc/source/filter/excel/excdoc.cxx index 63f29d88aefc..00f23be6e292 100644 --- a/sc/source/filter/excel/excdoc.cxx +++ b/sc/source/filter/excel/excdoc.cxx @@ -924,10 +924,11 @@ void ExcDocument::WriteXml( XclExpXmlStream& rStrm ) ScDocument& rDoc = GetDoc(); bool connectionXml = rDoc.hasConnectionXml(); + const ConnectionVector& vConnVector = rDoc.getConnectionVector(); - if (connectionXml) + if (connectionXml && !vConnVector.empty()) { - // save xl/connections.xml reference into [Content_Types].xml + // save xl/connections.xml reference into [Content_Types].xml and open stream to xl/connections.xml sax_fastparser::FSHelperPtr aConnectionsXml = rStrm.CreateOutputStream( "xl/connections.xml", u"connections.xml", rStrm.GetCurrentStream()->getOutputStream(), "application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml", @@ -950,7 +951,6 @@ void ExcDocument::WriteXml( XclExpXmlStream& rStrm ) rStrm.getNamespaceURL(OOX_NS(xr16)), FSNS(XML_mc, XML_Ignorable), "xr16"); // get a list of <connection> element and export it with its child elements - ConnectionVector vConnVector = rDoc.getConnectionVector(); for (const auto& rConnection : vConnVector) { const oox::xls::ConnectionModel& rModel = rConnection->getModel(); @@ -1036,26 +1036,28 @@ void ExcDocument::WriteXml( XclExpXmlStream& rStrm ) </xsd:sequence> */ - { // export <dbPr> - + css::uno::Sequence<css::uno::Any> aSeqs; + aSeqs = rConnection->getDbPrSequenceAny(); + // export <dbPr> if not empty + if (aSeqs.hasElements()) + { rtl::Reference<sax_fastparser::FastAttributeList> pAttrListDbPr = sax_fastparser::FastSerializerHelper::createAttrList(); - css::uno::Sequence<css::uno::Any> aSeqs = rConnection->getDbPrSequenceAny(); addElemensToAttrList(pAttrListDbPr, aSeqs); rStrm.GetCurrentStream()->singleElement(XML_dbPr, pAttrListDbPr); } - { // export <olapPr> - + aSeqs = rConnection->getOlapPrSequenceAny(); + // export <olapPr> if not empty + if (aSeqs.hasElements()) + { rtl::Reference<sax_fastparser::FastAttributeList> pAttrListOlapPr = sax_fastparser::FastSerializerHelper::createAttrList(); - css::uno::Sequence<css::uno::Any> aSeqs = rConnection->getOlapPrSequenceAny(); addElemensToAttrList(pAttrListOlapPr, aSeqs); - // this prints empty <olapPr/> even if aSeqs is empty, TODO: check if aSeqs is empty rStrm.GetCurrentStream()->singleElement(XML_olapPr, pAttrListOlapPr); }