diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2017-08-24 13:18:44 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2017-08-26 13:33:24 +0200 |
commit | d828577bcd522eaa57e40f889c8f3ae563ea1a75 (patch) | |
tree | 25a12f660b3415a03b1becd59e83e444a4cf7322 | |
parent | 3c49b28ffa7ab062726e5e600312d9164224404e (diff) |
tdf#89139: list all items in pivot table definition, incl. hidden
Change-Id: I14ce935185a6e0e3739fcf01fdefa031d814e821
Reviewed-on: https://gerrit.libreoffice.org/41509
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
-rw-r--r-- | sc/qa/unit/data/xlsx/tdf89139_pivot_table.xlsx | bin | 0 -> 15483 bytes | |||
-rw-r--r-- | sc/qa/unit/subsequent_export-test.cxx | 18 | ||||
-rw-r--r-- | sc/source/filter/excel/xepivotxml.cxx | 46 |
3 files changed, 51 insertions, 13 deletions
diff --git a/sc/qa/unit/data/xlsx/tdf89139_pivot_table.xlsx b/sc/qa/unit/data/xlsx/tdf89139_pivot_table.xlsx Binary files differnew file mode 100644 index 000000000000..83d5b3dc1556 --- /dev/null +++ b/sc/qa/unit/data/xlsx/tdf89139_pivot_table.xlsx diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx index 10031f9f5b86..2ba55186cd30 100644 --- a/sc/qa/unit/subsequent_export-test.cxx +++ b/sc/qa/unit/subsequent_export-test.cxx @@ -115,6 +115,7 @@ public: void testCellNoteExportXLS(); void testFormatExportODS(); + void testPivotTableExportXLSX(); void testPivotExportXLSX(); void testCommentExportXLSX(); #if HAVE_MORE_FONTS @@ -227,6 +228,7 @@ public: CPPUNIT_TEST(testCellNoteExportXLS); CPPUNIT_TEST(testFormatExportODS); + CPPUNIT_TEST(testPivotTableExportXLSX); CPPUNIT_TEST(testPivotExportXLSX); CPPUNIT_TEST(testCommentExportXLSX); #if HAVE_MORE_FONTS @@ -563,6 +565,22 @@ void ScExportTest::testFormatExportODS() xDocSh->DoClose(); } +void ScExportTest::testPivotTableExportXLSX() +{ + // tdf#89139: pivot table definition needs to list items, including hidden + + ScDocShellRef xShell = loadDoc("tdf89139_pivot_table.", FORMAT_XLSX); + CPPUNIT_ASSERT(xShell.is()); + + std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX); + xmlDocPtr pTable = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/pivotTables/pivotTable1.xml"); + CPPUNIT_ASSERT(pTable); + + assertXPath(pTable, "/x:pivotTableDefinition/x:pivotFields/x:pivotField[3]/x:items", "count", "4"); + assertXPath(pTable, "/x:pivotTableDefinition/x:pivotFields/x:pivotField[3]/x:items/x:item", 4); + assertXPath(pTable, "/x:pivotTableDefinition/x:pivotFields/x:pivotField[3]/x:items/x:item[3]", "h", "1"); +} + void ScExportTest::testPivotExportXLSX() { // tdf#89139 FILESAVE xlsx pivot table corrupted after save with LO and re-open with MS Office diff --git a/sc/source/filter/excel/xepivotxml.cxx b/sc/source/filter/excel/xepivotxml.cxx index c5872e24da4a..e3283ef87c2d 100644 --- a/sc/source/filter/excel/xepivotxml.cxx +++ b/sc/source/filter/excel/xepivotxml.cxx @@ -701,24 +701,35 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP } // Dump field items. - css::uno::Sequence<OUString> aMemberNames; + std::vector<ScDPLabelData::Member> aMembers; { // We need to get the members in actual order, getting which requires non-const reference here auto& dpo = const_cast<ScDPObject&>(rDPObj); - dpo.GetMemberNames(i, aMemberNames); + dpo.GetMembers(i, dpo.GetUsedHierarchy(i), aMembers); } const ScDPCache::ScDPItemDataVec& rCacheFieldItems = rCache.GetDimMemberValues(i); - std::vector<size_t> aMemberSequence; - for (const OUString& sMemberName : aMemberNames) + const auto iCacheFieldItems_begin = rCacheFieldItems.begin(), iCacheFieldItems_end = rCacheFieldItems.end(); + // The pair contains the member index in cache and if it is hidden + std::vector< std::pair<size_t, bool> > aMemberSequence; + std::set<size_t> aUsedCachePositions; + for (const auto & rMember : aMembers) { - auto it = std::find_if(rCacheFieldItems.begin(), rCacheFieldItems.end(), - [&sMemberName](const ScDPItemData& arg) -> bool { return arg.GetString() == sMemberName; }); - if (it != rCacheFieldItems.end()) + auto it = std::find_if(iCacheFieldItems_begin, iCacheFieldItems_end, + [&rMember](const ScDPItemData& arg) -> bool { return arg.GetString() == rMember.maName; }); + if (it != iCacheFieldItems_end) { - aMemberSequence.push_back(it - rCacheFieldItems.begin()); + size_t nCachePos = it - iCacheFieldItems_begin; + aMemberSequence.push_back(std::make_pair(nCachePos, !rMember.mbVisible)); + aUsedCachePositions.insert(nCachePos); } } + // Now add all remaining cache items as hidden + for (size_t nItem = 0; nItem < rCacheFieldItems.size(); ++nItem) + { + if (aUsedCachePositions.find(nItem) == aUsedCachePositions.end()) + aMemberSequence.push_back(std::make_pair(nItem, true)); + } auto pAttList = sax_fastparser::FastSerializerHelper::createAttrList(); pAttList->add(XML_axis, toOOXMLAxisType(eOrient)); @@ -726,14 +737,20 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP long nSubTotalCount = pDim->GetSubTotalsCount(); std::vector<OString> aSubtotalSequence; + bool bHasDefaultSubtotal = false; for (long nSubTotal = 0; nSubTotal < nSubTotalCount; ++nSubTotal) { ScGeneralFunction eFunc = pDim->GetSubTotalFunc(nSubTotal); aSubtotalSequence.push_back(GetSubtotalFuncName(eFunc)); sal_Int32 nAttToken = GetSubtotalAttrToken(eFunc); - if (!pAttList->hasAttribute(nAttToken)) + if (nAttToken == XML_defaultSubtotal) + bHasDefaultSubtotal = true; + else if (!pAttList->hasAttribute(nAttToken)) pAttList->add(nAttToken, ToPsz10(true)); } + // XML_defaultSubtotal is true by default; only write it if it's false + if (!bHasDefaultSubtotal) + pAttList->add(XML_defaultSubtotal, ToPsz10(false)); sax_fastparser::XFastAttributeListRef xAttributeList(pAttList); pPivotStrm->startElement(XML_pivotField, xAttributeList); @@ -742,11 +759,14 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP XML_count, OString::number(static_cast<long>(aMemberSequence.size() + aSubtotalSequence.size())), FSEND); - for (size_t nMember : aMemberSequence) + for (const auto & nMember : aMemberSequence) { - pPivotStrm->singleElement(XML_item, - XML_x, OString::number(static_cast<long>(nMember)), - FSEND); + auto pItemAttList = sax_fastparser::FastSerializerHelper::createAttrList(); + if (nMember.second) + pItemAttList->add(XML_h, ToPsz10(true)); + pItemAttList->add(XML_x, OString::number(static_cast<long>(nMember.first))); + sax_fastparser::XFastAttributeListRef xItemAttributeList(pItemAttList); + pPivotStrm->singleElement(XML_item, xItemAttributeList); } for (const OString& sSubtotal : aSubtotalSequence) |