[Libreoffice-commits] core.git: Branch 'distro/lhm/libreoffice-5-2+backports' - sc/qa sc/source
Mike Kaganski (via logerrit)
logerrit at kemper.freedesktop.org
Fri May 10 10:33:27 UTC 2019
sc/qa/unit/data/xlsx/tdf89139_pivot_table.xlsx |binary
sc/qa/unit/subsequent_export-test.cxx | 18 ++
sc/source/filter/excel/xepivotxml.cxx | 152 +++++++++++++++++++++----
3 files changed, 150 insertions(+), 20 deletions(-)
New commits:
commit 9cad0ab61f066caed34a9792c3026c334fe711dd
Author: Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Thu Aug 24 13:18:44 2017 +0300
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Fri May 10 12:32:50 2019 +0200
tdf#89139: list all items in pivot table definition, incl. hidden
Reviewed-on: https://gerrit.libreoffice.org/41509
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
Reviewed-on: https://gerrit.libreoffice.org/41588
Tested-by: Mike Kaganski <mike.kaganski at collabora.com>
(cherry picked from commit 711cdc36c42a3a9b8d0369c6fd853b8c071bb71a)
Change-Id: I14ce935185a6e0e3739fcf01fdefa031d814e821
Reviewed-on: https://gerrit.libreoffice.org/72059
Reviewed-by: Ilhan Yesil <ilhanyesil at gmx.de>
Tested-by: Ilhan Yesil <ilhanyesil at gmx.de>
diff --git a/sc/qa/unit/data/xlsx/tdf89139_pivot_table.xlsx b/sc/qa/unit/data/xlsx/tdf89139_pivot_table.xlsx
new file mode 100644
index 000000000000..83d5b3dc1556
Binary files /dev/null and b/sc/qa/unit/data/xlsx/tdf89139_pivot_table.xlsx differ
diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx
index ba3e5dc610af..93ae6ba4184a 100644
--- a/sc/qa/unit/subsequent_export-test.cxx
+++ b/sc/qa/unit/subsequent_export-test.cxx
@@ -110,6 +110,7 @@ public:
void testCellNoteExportXLS();
void testFormatExportODS();
+ void testPivotTableExportXLSX();
void testCustomColumnWidthExportXLSX();
void testXfDefaultValuesXLSX();
void testColumnWidthResaveXLSX();
@@ -199,6 +200,7 @@ public:
CPPUNIT_TEST(testCellNoteExportXLS);
CPPUNIT_TEST(testFormatExportODS);
+ CPPUNIT_TEST(testPivotTableExportXLSX);
CPPUNIT_TEST(testCustomColumnWidthExportXLSX);
CPPUNIT_TEST(testXfDefaultValuesXLSX);
CPPUNIT_TEST(testColumnWidthResaveXLSX);
@@ -483,6 +485,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::testCustomColumnWidthExportXLSX()
{
//tdf#100946 FILESAVE Excel on OS X ignored column widths in XLSX last saved by LO
diff --git a/sc/source/filter/excel/xepivotxml.cxx b/sc/source/filter/excel/xepivotxml.cxx
index 31e46b70cf46..e8a520092a07 100644
--- a/sc/source/filter/excel/xepivotxml.cxx
+++ b/sc/source/filter/excel/xepivotxml.cxx
@@ -441,6 +441,47 @@ struct DataField
DataField( long nPos, const ScDPSaveDimension* pDim ) : mnPos(nPos), mpDim(pDim) {}
};
+/** Returns a OOXML subtotal function name string. See ECMA-376-1:2016 18.18.43 */
+OString GetSubtotalFuncName(sal_uInt16 eFunc)
+{
+ switch (eFunc)
+ {
+ case sheet::GeneralFunction_SUM: return "sum";
+ case sheet::GeneralFunction_COUNT: return "count";
+ case sheet::GeneralFunction_AVERAGE: return "avg";
+ case sheet::GeneralFunction_MAX: return "max";
+ case sheet::GeneralFunction_MIN: return "min";
+ case sheet::GeneralFunction_PRODUCT: return "product";
+ case sheet::GeneralFunction_COUNTNUMS: return "countA";
+ case sheet::GeneralFunction_STDEV: return "stdDev";
+ case sheet::GeneralFunction_STDEVP: return "stdDevP";
+ case sheet::GeneralFunction_VAR: return "var";
+ case sheet::GeneralFunction_VARP: return "varP";
+ default:;
+ }
+ return "default";
+}
+
+sal_Int32 GetSubtotalAttrToken(sal_uInt16 eFunc)
+{
+ switch (eFunc)
+ {
+ case sheet::GeneralFunction_SUM: return XML_sumSubtotal;
+ case sheet::GeneralFunction_COUNT: return XML_countSubtotal;
+ case sheet::GeneralFunction_AVERAGE: return XML_avgSubtotal;
+ case sheet::GeneralFunction_MAX: return XML_maxSubtotal;
+ case sheet::GeneralFunction_MIN: return XML_minSubtotal;
+ case sheet::GeneralFunction_PRODUCT: return XML_productSubtotal;
+ case sheet::GeneralFunction_COUNTNUMS: return XML_countASubtotal;
+ case sheet::GeneralFunction_STDEV: return XML_stdDevSubtotal;
+ case sheet::GeneralFunction_STDEVP: return XML_stdDevPSubtotal;
+ case sheet::GeneralFunction_VAR: return XML_varSubtotal;
+ case sheet::GeneralFunction_VARP: return XML_varPSubtotal;
+ default:;
+ }
+ return XML_defaultSubtotal;
+}
+
}
void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDPObject& rDPObj, sal_Int32 nCacheId )
@@ -528,18 +569,18 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP
XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
XML_name, XclXmlUtils::ToOString(rDPObj.GetName()).getStr(),
XML_cacheId, OString::number(nCacheId).getStr(),
- XML_applyNumberFormats, BS(false),
- XML_applyBorderFormats, BS(false),
- XML_applyFontFormats, BS(false),
- XML_applyPatternFormats, BS(false),
- XML_applyAlignmentFormats, BS(false),
- XML_applyWidthHeightFormats, BS(false),
+ XML_applyNumberFormats, XclXmlUtils::ToPsz10(false),
+ XML_applyBorderFormats, XclXmlUtils::ToPsz10(false),
+ XML_applyFontFormats, XclXmlUtils::ToPsz10(false),
+ XML_applyPatternFormats, XclXmlUtils::ToPsz10(false),
+ XML_applyAlignmentFormats, XclXmlUtils::ToPsz10(false),
+ XML_applyWidthHeightFormats, XclXmlUtils::ToPsz10(false),
XML_dataCaption, "Values",
- XML_useAutoFormatting, BS(false),
- XML_itemPrintTitles, BS(true),
- XML_indent, BS(false),
- XML_outline, BS(true),
- XML_outlineData, BS(true),
+ XML_useAutoFormatting, XclXmlUtils::ToPsz10(false),
+ XML_itemPrintTitles, XclXmlUtils::ToPsz10(true),
+ XML_indent, XclXmlUtils::ToPsz10(false),
+ XML_outline, XclXmlUtils::ToPsz10(true),
+ XML_outlineData, XclXmlUtils::ToPsz10(true),
FSEND);
// NB: Excel's range does not include page field area (if any).
@@ -582,12 +623,13 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP
XML_count, OString::number(static_cast<long>(aCachedDims.size())).getStr(),
FSEND);
- for (const ScDPSaveDimension* pDim : aCachedDims)
+ for (size_t i = 0; i < nFieldCount; ++i)
{
+ const ScDPSaveDimension* pDim = aCachedDims[i];
if (!pDim)
{
pPivotStrm->singleElement(XML_pivotField,
- XML_showAll, BS(false),
+ XML_showAll, XclXmlUtils::ToPsz10(false),
FSEND);
continue;
}
@@ -598,7 +640,7 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP
if (eOrient == sheet::DataPilotFieldOrientation_HIDDEN)
{
pPivotStrm->singleElement(XML_pivotField,
- XML_showAll, BS(false),
+ XML_showAll, XclXmlUtils::ToPsz10(false),
FSEND);
continue;
}
@@ -606,20 +648,90 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP
if (eOrient == sheet::DataPilotFieldOrientation_DATA)
{
pPivotStrm->singleElement(XML_pivotField,
- XML_dataField, BS(true),
- XML_showAll, BS(false),
+ XML_dataField, XclXmlUtils::ToPsz10(true),
+ XML_showAll, XclXmlUtils::ToPsz10(false),
FSEND);
continue;
}
- pPivotStrm->startElement(XML_pivotField,
- XML_axis, toOOXMLAxisType(eOrient),
- XML_showAll, BS(false),
+ // Dump field items.
+ 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.GetMembers(i, dpo.GetUsedHierarchy(i), aMembers);
+ }
+
+ const ScDPCache::ScDPItemDataVec& rCacheFieldItems = rCache.GetDimMemberValues(i);
+ 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(iCacheFieldItems_begin, iCacheFieldItems_end,
+ [&rMember](const ScDPItemData& arg) -> bool { return arg.GetString() == rMember.maName; });
+ if (it != iCacheFieldItems_end)
+ {
+ 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));
+ pAttList->add(XML_showAll, XclXmlUtils::ToPsz10(false));
+
+ long nSubTotalCount = pDim->GetSubTotalsCount();
+ std::vector<OString> aSubtotalSequence;
+ bool bHasDefaultSubtotal = false;
+ for (long nSubTotal = 0; nSubTotal < nSubTotalCount; ++nSubTotal)
+ {
+ sal_uInt16 eFunc = pDim->GetSubTotalFunc(nSubTotal);
+ aSubtotalSequence.push_back(GetSubtotalFuncName(eFunc));
+ sal_Int32 nAttToken = GetSubtotalAttrToken(eFunc);
+ if (nAttToken == XML_defaultSubtotal)
+ bHasDefaultSubtotal = true;
+ else if (!pAttList->hasAttribute(nAttToken))
+ pAttList->add(nAttToken, XclXmlUtils::ToPsz10(true));
+ }
+ // XML_defaultSubtotal is true by default; only write it if it's false
+ if (!bHasDefaultSubtotal)
+ pAttList->add(XML_defaultSubtotal, XclXmlUtils::ToPsz10(false));
+
+ sax_fastparser::XFastAttributeListRef xAttributeList(pAttList);
+ pPivotStrm->startElement(XML_pivotField, xAttributeList);
+
+ pPivotStrm->startElement(XML_items,
+ XML_count, OString::number(static_cast<long>(aMemberSequence.size() + aSubtotalSequence.size())),
FSEND);
- // TODO : Dump field items.
+ for (const auto & nMember : aMemberSequence)
+ {
+ auto pItemAttList = sax_fastparser::FastSerializerHelper::createAttrList();
+ if (nMember.second)
+ pItemAttList->add(XML_h, XclXmlUtils::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)
+ {
+ pPivotStrm->singleElement(XML_item,
+ XML_t, sSubtotal,
+ FSEND);
+ }
+ pPivotStrm->endElement(XML_items);
pPivotStrm->endElement(XML_pivotField);
}
More information about the Libreoffice-commits
mailing list