From ca071ce7fd7143ad0404fd78c7d079695efa0761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=C5=BE=20Vajngerl?= Date: Tue, 2 Dec 2025 14:31:11 +0900 Subject: [PATCH] sc: fix exporting of row / column items of a pivot table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current row and column items export implementation was quite naive, where it added jsut one level of items and not understood why t="grand" needs to be added. This fixes the implementation so it now gathers the row / column items correctly. There are many scenarios we need to take into account, like grant totals, subtotals, filters and sorts. Those are covered by tests using different pivot tables. If the row / column items are not correctly set, the pivot table in MSOffice is not shown correctly in the sheet until you actually refresh the pivot table, so the data refreshes. In recent MSOffice version it also marks the pivot table as corrupt and removes the pivot table from the document. With this fix it now accepts the pivot table and show it correctly. Change-Id: I1fbe05b4b5a2051ec9d527f5243c84c2e8818b72 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194940 Reviewed-by: Tomaž Vajngerl Tested-by: Jenkins --- sc/CppunitTest_sc_pivottable_filters_test.mk | 1 + sc/Library_sc.mk | 1 + sc/inc/miscuno.hxx | 8 +- sc/inc/pivot/PivotTableResultTraverser.hxx | 73 ++ .../unit/PivotTable_FieldsAndItemsExport.cxx | 840 ++++++++++++++++++ sc/qa/unit/data/xlsx/pivot/Pivot1_Row.xlsx | Bin 0 -> 12707 bytes .../data/xlsx/pivot/Pivot1_Row_Grand.xlsx | Bin 0 -> 12709 bytes .../pivot/Pivot1_Row_Grand_Subtotals.xlsx | Bin 0 -> 12845 bytes sc/qa/unit/data/xlsx/pivot/Pivot2_Row.xlsx | Bin 0 -> 12590 bytes .../data/xlsx/pivot/Pivot2_Row_Compact.xlsx | Bin 0 -> 12877 bytes .../data/xlsx/pivot/Pivot2_Row_Grand.xlsx | Bin 0 -> 12615 bytes .../pivot/Pivot2_Row_Grand_Subtotals.xlsx | Bin 0 -> 12670 bytes .../data/xlsx/pivot/Pivot2_Row_Subtotals.xlsx | Bin 0 -> 12656 bytes ...ivot2_Row_Subtotals_SortDescendingAll.xlsx | Bin 0 -> 12677 bytes .../pivot/Pivot3_Column_Grand_Subtotals.xlsx | Bin 0 -> 12716 bytes ...Column_Grand_Subtotals_SortDescending.xlsx | Bin 0 -> 12734 bytes sc/qa/unit/pivottable_filters_test.cxx | 131 --- .../data/pivot/PivotTableResultTraverser.cxx | 125 +++ sc/source/filter/excel/xepivotxml.cxx | 333 +++++-- 19 files changed, 1308 insertions(+), 204 deletions(-) create mode 100644 sc/inc/pivot/PivotTableResultTraverser.hxx create mode 100644 sc/qa/unit/PivotTable_FieldsAndItemsExport.cxx create mode 100644 sc/qa/unit/data/xlsx/pivot/Pivot1_Row.xlsx create mode 100644 sc/qa/unit/data/xlsx/pivot/Pivot1_Row_Grand.xlsx create mode 100644 sc/qa/unit/data/xlsx/pivot/Pivot1_Row_Grand_Subtotals.xlsx create mode 100644 sc/qa/unit/data/xlsx/pivot/Pivot2_Row.xlsx create mode 100644 sc/qa/unit/data/xlsx/pivot/Pivot2_Row_Compact.xlsx create mode 100644 sc/qa/unit/data/xlsx/pivot/Pivot2_Row_Grand.xlsx create mode 100644 sc/qa/unit/data/xlsx/pivot/Pivot2_Row_Grand_Subtotals.xlsx create mode 100644 sc/qa/unit/data/xlsx/pivot/Pivot2_Row_Subtotals.xlsx create mode 100644 sc/qa/unit/data/xlsx/pivot/Pivot2_Row_Subtotals_SortDescendingAll.xlsx create mode 100644 sc/qa/unit/data/xlsx/pivot/Pivot3_Column_Grand_Subtotals.xlsx create mode 100644 sc/qa/unit/data/xlsx/pivot/Pivot4_Column_Grand_Subtotals_SortDescending.xlsx create mode 100644 sc/source/core/data/pivot/PivotTableResultTraverser.cxx diff --git a/sc/CppunitTest_sc_pivottable_filters_test.mk b/sc/CppunitTest_sc_pivottable_filters_test.mk index 45ceded3698e..a2134039cdb0 100644 --- a/sc/CppunitTest_sc_pivottable_filters_test.mk +++ b/sc/CppunitTest_sc_pivottable_filters_test.mk @@ -13,6 +13,7 @@ $(eval $(call gb_CppunitTest_use_common_precompiled_header,sc_pivottable_filters $(eval $(call gb_CppunitTest_add_exception_objects,sc_pivottable_filters_test, \ sc/qa/unit/pivottable_filters_test \ + sc/qa/unit/PivotTable_FieldsAndItemsExport \ )) $(eval $(call gb_CppunitTest_use_externals,sc_pivottable_filters_test, \ diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk index 2567f7f21735..5960a50e1fa4 100644 --- a/sc/Library_sc.mk +++ b/sc/Library_sc.mk @@ -213,6 +213,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ sc/source/core/data/types \ sc/source/core/data/userdat \ sc/source/core/data/validat \ + sc/source/core/data/pivot/PivotTableResultTraverser \ sc/source/core/tool/addincfg \ sc/source/core/tool/addincol \ sc/source/core/tool/addinhelpid \ diff --git a/sc/inc/miscuno.hxx b/sc/inc/miscuno.hxx index 71cd9390de49..075bf0046185 100644 --- a/sc/inc/miscuno.hxx +++ b/sc/inc/miscuno.hxx @@ -107,7 +107,7 @@ public: }; // new (uno 3) variant -class ScNameToIndexAccess final : public cppu::WeakImplHelper< +class SC_DLLPUBLIC ScNameToIndexAccess final : public cppu::WeakImplHelper< css::container::XIndexAccess, css::lang::XServiceInfo > { @@ -134,7 +134,7 @@ public: virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; }; -class ScUnoHelpFunctions +class SC_DLLPUBLIC ScUnoHelpFunctions { public: static bool GetBoolProperty( const css::uno::Reference< css::beans::XPropertySet>& xProp, @@ -152,8 +152,8 @@ public: const css::uno::Reference& xProp, const OUString& rName, const OUString& rDefault ); - SC_DLLPUBLIC static bool GetBoolFromAny( const css::uno::Any& aAny ); - SC_DLLPUBLIC static sal_Int16 GetInt16FromAny( const css::uno::Any& aAny ); + static bool GetBoolFromAny( const css::uno::Any& aAny ); + static sal_Int16 GetInt16FromAny( const css::uno::Any& aAny ); static sal_Int32 GetInt32FromAny( const css::uno::Any& aAny ); static sal_Int32 GetEnumFromAny( const css::uno::Any& aAny ); diff --git a/sc/inc/pivot/PivotTableResultTraverser.hxx b/sc/inc/pivot/PivotTableResultTraverser.hxx new file mode 100644 index 000000000000..3ecd7c0c8c4a --- /dev/null +++ b/sc/inc/pivot/PivotTableResultTraverser.hxx @@ -0,0 +1,73 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include +#include +#include + +#include +#include + +namespace sc +{ +namespace pivot +{ +SC_DLLPUBLIC css::uno::Any +getMemberForLevel(css::uno::Reference const& xLevel, OUString const& rName); +} + +class SC_DLLPUBLIC PivotTableResultVisitor +{ +public: + virtual bool filterOrientation(css::sheet::DataPilotFieldOrientation eOrientation) + { + return eOrientation == css::sheet::DataPilotFieldOrientation_HIDDEN; + } + + virtual void startDimension(sal_Int32 /*nDimensionIndex*/, + css::uno::Reference const& /*xDimension*/, + css::sheet::DataPilotFieldOrientation /*eOrientation*/) + { + } + + virtual void endDimension() {} + + virtual void startLevel(sal_Int32 /*nLevelIndex*/, + css::uno::Reference const& /*xLevel*/, + OUString const& /*rLevelName*/) + { + } + + virtual void endLevel() {} + + virtual void memberResult(css::sheet::MemberResult const& rResult, sal_Int32 nIndex, + sal_Int32 nSize) + = 0; +}; + +class SC_DLLPUBLIC PivotTableResultTraverser +{ +private: + ScDPObject& mrDPObject; + PivotTableResultVisitor& mrVisitor; + +public: + PivotTableResultTraverser(ScDPObject& rDPObject, PivotTableResultVisitor& rVisitor) + : mrDPObject(rDPObject) + , mrVisitor(rVisitor) + { + } + + void traverse(); +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/qa/unit/PivotTable_FieldsAndItemsExport.cxx b/sc/qa/unit/PivotTable_FieldsAndItemsExport.cxx new file mode 100644 index 000000000000..dbbaf3c8f3ff --- /dev/null +++ b/sc/qa/unit/PivotTable_FieldsAndItemsExport.cxx @@ -0,0 +1,840 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include + +#include "helper/qahelper.hxx" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace ::com::sun::star; + +class PivotTableFieldsAndItemsExport : public ScModelTestBase +{ +public: + PivotTableFieldsAndItemsExport() + : ScModelTestBase(u"sc/qa/unit/data"_ustr) + { + } +}; + +CPPUNIT_TEST_FIXTURE(PivotTableFieldsAndItemsExport, testTdf123225PivotTableRowColItems) +{ + createScDoc("ods/tdf123225_pivotTable_row_col_items.ods"); + save(TestFilter::XLSX); + + xmlDocUniquePtr pSheet = parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr); + CPPUNIT_ASSERT(pSheet); + + /* Make sure that we have and element under after export of the .ods to .xlsx */ + /* otherwise: + - Excel will fail to open the xlsx document, you will get an error message. + - Excel will open the file without any errors but: + * context menu -by right clicking on the pivot table- will have less or more items than it should have after "refresh". + * if e.g. trying to sort the items you will get "Cannot determine which PivotTable field to sort by" warning. + */ + + // Row items + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", 1); + // check if + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", "count", u"8"); + // check if has enough depending on count attribute value + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i", 8); + // check if first has single element + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x", 1); + // check if of the first element, exists (note the v=0 is default) + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x", 1); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x", "v"); + + // Column items + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", 1); + // check if + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", "count", u"5"); + // check if has enough depending on count attribute value + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i", 5); + // check if first has single element + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x", 1); + // check if of the first element, exists (note the v=0 is default) + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x", 1); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x", "v"); +} + +CPPUNIT_TEST_FIXTURE(PivotTableFieldsAndItemsExport, testTdf123225_CheckGrandTotalIsSet) +{ + createScDoc("ods/tdf123225_pivotTable_no_col_items.ods"); + save(TestFilter::XLSX); + + xmlDocUniquePtr pSheet = parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr); + CPPUNIT_ASSERT(pSheet); + + /* If there is a grand (Total result) there needs to be a row/column item with t="grand"*/ + + // Row items + + // check if + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", "count", u"3"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i", 3); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x[1]", "v", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x[1]", "v", u"2"); + + // check if last element, has t="grand" + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]", "t", u"grand"); + // check element + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x", 1); + + // Column items + + // check if + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", "count", u"1"); + // check if has only a single element + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i", 1); + // check there is no attribute "t" + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:colItems/x:i", "t"); + // check that it doesn't contain any elements + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x", 0); +} + +CPPUNIT_TEST_FIXTURE(PivotTableFieldsAndItemsExport, testTdf123225PivotTableEmptyRowColItems) +{ + // this doc contains blank row/col items + // (xl/pivotCache/pivotCacheDefinition1.xml) + createScDoc("ods/tdf123225_pivotTable_empty_row_col_items.ods"); + save(TestFilter::XLSX); + + xmlDocUniquePtr pSheet = parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr); + CPPUNIT_ASSERT(pSheet); + + // Row items + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", 1); + // check if + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", "count", u"4"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i", 4); + + // Column items + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", 1); + // check if + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", "count", u"5"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i", 5); +} + +CPPUNIT_TEST_FIXTURE(PivotTableFieldsAndItemsExport, testPivotTable_RowColumnItems_Row1) +{ + /* Input document rowItems: + + + + + + + + */ + createScDoc("xlsx/pivot/Pivot1_Row.xlsx"); + save(TestFilter::XLSX); + + xmlDocUniquePtr pSheet = parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr); + CPPUNIT_ASSERT(pSheet); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", 1); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", "count", u"5"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i", 5); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x", 2); + + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x[1]", "v"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x[2]", "v", u"2"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x[1]", "v", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x[2]", "v", u"1"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x[1]", "v", u"2"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x[2]", "v", u"1"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x[1]", "v", u"3"); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x[2]", "v"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x[1]", "v", u"4"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x[2]", "v", u"2"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", "count", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x", 0); +} + +CPPUNIT_TEST_FIXTURE(PivotTableFieldsAndItemsExport, testPivotTable_RowColumnItems_Row1_Grand) +{ + /* Input document rowItems: + + + + + + + + + */ + createScDoc("xlsx/pivot/Pivot1_Row_Grand.xlsx"); + save(TestFilter::XLSX); + + xmlDocUniquePtr pSheet = parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr); + CPPUNIT_ASSERT(pSheet); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", 1); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", "count", u"6"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i", 6); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x", 2); + + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x[1]", "v"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x[2]", "v", u"2"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x[1]", "v", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x[2]", "v", u"1"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x[1]", "v", u"2"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x[2]", "v", u"1"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x[1]", "v", u"3"); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x[2]", "v"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x[1]", "v", u"4"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x[2]", "v", u"2"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]", "t", u"grand"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]/x:x", 1); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]/x:x", "v"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", "count", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x", 0); +} + +CPPUNIT_TEST_FIXTURE(PivotTableFieldsAndItemsExport, + testPivotTable_RowColumnItems_Row1_Grand_Subtotals) +{ + /* Input document rowItems: + + + + + + + + + + + + + + */ + createScDoc("xlsx/pivot/Pivot1_Row_Grand_Subtotals.xlsx"); + save(TestFilter::XLSX); + + xmlDocUniquePtr pSheet = parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr); + CPPUNIT_ASSERT(pSheet); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", 1); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", "count", u"11"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i", 11); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[7]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[8]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[9]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[10]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[11]/x:x", 1); + + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x[1]", "v"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x[2]", "v", u"2"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]", "t", u"default"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x", 1); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x", "v"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x[1]", "v", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x[2]", "v", u"1"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]", "t", u"default"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x", "v", u"1"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x[1]", "v", u"2"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x[2]", "v", u"1"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]", "t", u"default"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]/x:x", "v", u"2"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[7]/x:x[1]", "v", u"3"); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[7]/x:x[2]", "v"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[8]", "t", u"default"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[8]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[8]/x:x", "v", u"3"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[9]/x:x[1]", "v", u"4"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[9]/x:x[2]", "v", u"2"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[10]", "t", u"default"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[10]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[10]/x:x", "v", u"4"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[11]", "t", u"grand"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[11]/x:x", 1); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[11]/x:x", "v"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", "count", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x", 0); +} + +CPPUNIT_TEST_FIXTURE(PivotTableFieldsAndItemsExport, testPivotTable_RowColumnItems_Row2) +{ + /* Input document rowItems: + + + + + + + + */ + createScDoc("xlsx/pivot/Pivot2_Row.xlsx"); + save(TestFilter::XLSX); + + xmlDocUniquePtr pSheet = parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr); + CPPUNIT_ASSERT(pSheet); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", 1); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", "count", u"5"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i", 5); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x", 2); + + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x[1]", "v"); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x[2]", "v"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]", "r", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x[1]", "v", u"4"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x[1]", "v", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x[2]", "v", u"1"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]", "r", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x[1]", "v", u"2"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x[1]", "v", u"2"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x[2]", "v", u"3"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", "count", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x", 0); +} + +CPPUNIT_TEST_FIXTURE(PivotTableFieldsAndItemsExport, testPivotTable_RowColumnItems_Row2_Grand) +{ + /* Input document rowItems: + + + + + + + + + */ + createScDoc("xlsx/pivot/Pivot2_Row_Grand.xlsx"); + save(TestFilter::XLSX); + + xmlDocUniquePtr pSheet = parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr); + CPPUNIT_ASSERT(pSheet); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", 1); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", "count", u"6"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i", 6); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]/x:x", 1); + + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x[1]", "v"); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x[2]", "v"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]", "r", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x[1]", "v", u"4"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x[1]", "v", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x[2]", "v", u"1"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]", "r", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x[1]", "v", u"2"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x[1]", "v", u"2"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x[2]", "v", u"3"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]", "t", u"grand"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]/x:x", 1); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]/x:x", "v"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", "count", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x", 0); +} + +CPPUNIT_TEST_FIXTURE(PivotTableFieldsAndItemsExport, testPivotTable_RowColumnItems_Row2_Subtotals) +{ + /* Input document rowItems: + + + + + + + + + + + */ + createScDoc("xlsx/pivot/Pivot2_Row_Subtotals.xlsx"); + save(TestFilter::XLSX); + + xmlDocUniquePtr pSheet = parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr); + CPPUNIT_ASSERT(pSheet); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", 1); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", "count", u"8"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i", 8); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[7]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[8]/x:x", 1); + + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x[1]", "v"); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x[2]", "v"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]", "r", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x[1]", "v", u"4"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]", "t", u"default"); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x", "v"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x[1]", "v", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x[2]", "v", u"1"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]", "r", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x[1]", "v", u"2"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]", "t", u"default"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]/x:x", "v", u"1"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[7]/x:x[1]", "v", u"2"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[7]/x:x[2]", "v", u"3"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[8]", "t", u"default"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[8]/x:x", "v", u"2"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", "count", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x", 0); +} + +CPPUNIT_TEST_FIXTURE(PivotTableFieldsAndItemsExport, + testPivotTable_RowColumnItems_Row2_Grand_Subtotals) +{ + /* Input document rowItems: + + + + + + + + + + + + */ + createScDoc("xlsx/pivot/Pivot2_Row_Grand_Subtotals.xlsx"); + save(TestFilter::XLSX); + + xmlDocUniquePtr pSheet = parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr); + CPPUNIT_ASSERT(pSheet); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", 1); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", "count", u"9"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i", 9); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[7]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[8]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[9]/x:x", 1); + + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x[1]", "v"); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x[2]", "v"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]", "r", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x[1]", "v", u"4"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]", "t", u"default"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x", 1); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x", "v"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x[1]", "v", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x[2]", "v", u"1"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]", "r", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x[1]", "v", u"2"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]", "t", u"default"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]/x:x", "v", u"1"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[7]/x:x[1]", "v", u"2"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[7]/x:x[2]", "v", u"3"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[8]", "t", u"default"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[8]/x:x", "v", u"2"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[9]", "t", u"grand"); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[9]/x:x", "v"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", "count", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x", 0); +} + +CPPUNIT_TEST_FIXTURE(PivotTableFieldsAndItemsExport, testPivotTable_RowColumnItems_Row2_Compact) +{ + /* Input document rowItems: + + + + + + + + + + + */ + createScDoc("xlsx/pivot/Pivot2_Row_Compact.xlsx"); + save(TestFilter::XLSX); + + xmlDocUniquePtr pSheet = parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr); + CPPUNIT_ASSERT(pSheet); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", 1); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", "count", u"8"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i", 8); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[7]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[8]/x:x", 1); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x", 1); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x[1]", "v"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]", "r", u"1"); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x[1]", "v"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]", "r", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x", "v", u"4"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x[1]", "v", u"1"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]", "r", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x[1]", "v", u"1"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]", "r", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]/x:x[1]", "v", u"2"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[7]/x:x[1]", "v", u"2"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[8]", "r", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[8]/x:x[1]", "v", u"3"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", "count", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x", 0); +} + +CPPUNIT_TEST_FIXTURE(PivotTableFieldsAndItemsExport, + testPivotTable_RowColumnItems_Row2_Subtotals_SortDescendingAll) +{ + /* Input document rowItems: + + + + + + + + + + + */ + createScDoc("xlsx/pivot/Pivot2_Row_Subtotals_SortDescendingAll.xlsx"); + save(TestFilter::XLSX); + + xmlDocUniquePtr pSheet = parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr); + CPPUNIT_ASSERT(pSheet); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", 1); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", "count", u"8"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i", 8); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[7]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[8]/x:x", 1); + + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x[1]", "v"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x[2]", "v", u"1"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]", "t", u"default"); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[2]/x:x", "v"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x[1]", "v", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[3]/x:x[2]", "v", u"2"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]", "r", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[4]/x:x[1]", "v", u"3"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]", "t", u"default"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[5]/x:x", "v", u"1"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]/x:x[1]", "v", u"2"); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[6]/x:x[2]", "v"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[7]", "r", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[7]/x:x[1]", "v", u"4"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[8]", "t", u"default"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[8]/x:x", "v", u"2"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", "count", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x", 0); +} + +CPPUNIT_TEST_FIXTURE(PivotTableFieldsAndItemsExport, + testPivotTable_RowColumnItems_Column3_Grand_Subtotals) +{ + /* Input colItems should be the same as output + + + + + + + + + + + + */ + createScDoc("xlsx/pivot/Pivot3_Column_Grand_Subtotals.xlsx"); + save(TestFilter::XLSX); + + xmlDocUniquePtr pSheet = parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr); + CPPUNIT_ASSERT(pSheet); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", "count", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x", 0); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", "count", u"9"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i", 9); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[2]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[3]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[4]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[5]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[6]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[7]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[8]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[9]/x:x", 1); + + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x[1]", "v"); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x[2]", "v"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[2]", "r", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[2]/x:x[1]", "v", u"4"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[3]", "t", u"default"); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[3]/x:x", "v"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[4]/x:x[1]", "v", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[4]/x:x[2]", "v", u"1"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[5]", "r", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[5]/x:x[1]", "v", u"2"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[6]", "t", u"default"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[6]/x:x", "v", u"1"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[7]/x:x[1]", "v", u"2"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[7]/x:x[2]", "v", u"3"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[8]", "t", u"default"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[8]/x:x", "v", u"2"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[9]", "t", u"grand"); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[9]/x:x", "v"); +} +CPPUNIT_TEST_FIXTURE(PivotTableFieldsAndItemsExport, + testPivotTable_RowColumnItems_Column4_Grand_Subtotals_SortDescending) +{ + /* Input colItems should be the same as output + + + + + + + + + + + + */ + createScDoc("xlsx/pivot/Pivot4_Column_Grand_Subtotals_SortDescending.xlsx"); + save(TestFilter::XLSX); + + xmlDocUniquePtr pSheet = parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr); + CPPUNIT_ASSERT(pSheet); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", "count", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x", 0); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", "count", u"9"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i", 9); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[2]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[3]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[4]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[5]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[6]/x:x", 2); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[7]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[8]/x:x", 1); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[9]/x:x", 1); + + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x[1]", "v"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x[2]", "v", u"3"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[2]", "t", u"default"); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[2]/x:x", "v"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[3]/x:x[1]", "v", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[3]/x:x[2]", "v", u"1"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[4]", "r", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[4]/x:x[1]", "v", u"2"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[5]", "t", u"default"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[5]/x:x", "v", u"1"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[6]/x:x[1]", "v", u"2"); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[6]/x:x[2]", "v"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[7]", "r", u"1"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[7]/x:x[1]", "v", u"4"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[8]", "t", u"default"); + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[8]/x:x", "v", u"2"); + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[9]", "t", u"grand"); + assertXPathNoAttribute(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[9]/x:x", "v"); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/qa/unit/data/xlsx/pivot/Pivot1_Row.xlsx b/sc/qa/unit/data/xlsx/pivot/Pivot1_Row.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..77df731a56025afb2d44c20314ed9c9bb01fd906 GIT binary patch literal 12707 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 literal 0 HcmV?d00001 diff --git a/sc/qa/unit/data/xlsx/pivot/Pivot2_Row.xlsx b/sc/qa/unit/data/xlsx/pivot/Pivot2_Row.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..de44fa7c6420ca683d27bd35a18f740498e40464 GIT binary patch literal 12590 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 I_<8n!0N&vhWdHyG literal 0 HcmV?d00001 diff --git a/sc/qa/unit/data/xlsx/pivot/Pivot2_Row_Grand.xlsx b/sc/qa/unit/data/xlsx/pivot/Pivot2_Row_Grand.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..6e81ddc7d4869bd210dae28d49c98f67a11a691a GIT binary patch literal 12615 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 literal 0 HcmV?d00001 diff --git a/sc/qa/unit/data/xlsx/pivot/Pivot2_Row_Grand_Subtotals.xlsx b/sc/qa/unit/data/xlsx/pivot/Pivot2_Row_Grand_Subtotals.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..848c30e02a545dabe40c67626f8b0574d508b3b0 GIT binary patch literal 12670 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 literal 0 HcmV?d00001 diff --git a/sc/qa/unit/data/xlsx/pivot/Pivot2_Row_Subtotals.xlsx b/sc/qa/unit/data/xlsx/pivot/Pivot2_Row_Subtotals.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..043e31185f03d50247682e775a10c38d0b8c14e5 GIT binary patch literal 12656 zcmeHtWmsHU(=86cgS)%CySuvvcXxM5a8Gde;I2Uf32wpN12hgnZ%=04Co^Qed+-16 zJwKXm&Z*VsR9CI4T6-(Wf_CBlpn|}F>54koyPDa% z8mf6Ynz`sRc-q+#=;Iw4sJoneOeb)V#!DW`AHE(~q&4eZR59yCr8czs(MN8N zhf)p?c#}tG@EU6CBjVK%07`xZReUQs)RHDM01e&f)NObzMz;gIUg|okK`EV26I&{Y zo>qoP_`8r49f+?wMV>rO-eqk2XwJKmF|9%@{D-VJX{!48x+q|K=)M$<-x7+~w-v*^ z6Um22J2M(Y*@i@?0bJMK93iJ&GrC+*&;3TTUvA&#jt+LWHAEz9T8%TU7|7!k9`L!4lH)d~;?^&$E#TaOp4PiZ=`DTpq zeAWDf;8zitFT8jJ{wf7Xz-WAa1_x34M@l!UGm%~b&&UBY77m!whR$ZTE{qI+y#6

_V|dz~lN&S*g>$NeQ{_hgYxmi!+3OFIGG0{f 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 literal 0 HcmV?d00001 diff --git a/sc/qa/unit/data/xlsx/pivot/Pivot2_Row_Subtotals_SortDescendingAll.xlsx b/sc/qa/unit/data/xlsx/pivot/Pivot2_Row_Subtotals_SortDescendingAll.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..ade6310b8c03a938f5fc9950da4a1608bfb32ac5 GIT binary patch literal 12677 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 RPm2QR25xfg(Eai0e*n^S+E)Mo literal 0 HcmV?d00001 diff --git a/sc/qa/unit/pivottable_filters_test.cxx b/sc/qa/unit/pivottable_filters_test.cxx index b874bdd398b8..12a360790d13 100644 --- a/sc/qa/unit/pivottable_filters_test.cxx +++ b/sc/qa/unit/pivottable_filters_test.cxx @@ -122,137 +122,6 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testPivotTableBasicODS) sal_uInt16(pDim->GetFunction())); } -CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testTdf123225PivotTableRowColItems) -{ - createScDoc("ods/tdf123225_pivotTable_row_col_items.ods"); - save(TestFilter::XLSX); - - xmlDocUniquePtr pSheet = parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr); - CPPUNIT_ASSERT(pSheet); - - /* - - be sure that we have and element - under after export of the .ods to .xlsx - - otherwise: - 1) Excel will fail to open the xlsx document, you will get an error message. - 2) Excel will open the file without any errors but: - 2.1) context menu -by right clicking on the pivot table- will have - less or more items than it should have after "refresh". - 2.2) if e.g. trying to sort the items you will get "Cannot determine - which PivotTable field to sort by" warning. - - - after exporting the .ods as .xlsx and opening the .xlsx document in Excel: - the count attribute of rowItems(or colItems) should have the expected value. - otherwise, context menu on the pivot table will have less/more items - than it should have after "refresh". we shouldn't need "refresh" to use all - functions/items in the context menu. - */ - - // Row items - - assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", 1); - // check if - assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", "count", u"8"); - // check if has enough depending on count attribute value - assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i", 8); - // check if first has single element - assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x", 1); - // check if of the first element, has v="0" attribute value - assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[1]/x:x", "v", u"0"); - - // Column items - - assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", 1); - // check if - assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", "count", u"5"); - // check if has enough depending on count attribute value - assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i", 5); - // check if first has single element - assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x", 1); - // check if of the first element, has v="0" attribute value - assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x", "v", u"0"); -} - -CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testTdf123225PivotTableNoColItems) -{ - createScDoc("ods/tdf123225_pivotTable_no_col_items.ods"); - save(TestFilter::XLSX); - - xmlDocUniquePtr pSheet = parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr); - CPPUNIT_ASSERT(pSheet); - - /* - - after exporting the .ods to .xlsx, we should have t="grand" in the - last element of the and . Otherwise, Excel will not - have all functions in the context menu of the pivot table. Especially for the - "Grand Total" column/row cells. - - - additionally, we should always export a single and regardless of - whether the document has row/col items. Otherwise, in Excel, context menu on some - cells of the pivot table, will not have the expected context menu items. - - - this tdf123225_pivotTable_no_col_items.ods document does not have - axisCol (DataPilotFieldOrientation_COLUMN) and that means should not exist - during export. But in Excel, if pivot table refreshed, there will be - - - - - - in the xl/pivotTables/pivotTable1.xml. So, that means we should export - without checking the existence of it. - For the sake of completeness, exported as: - - - - - - - */ - - // Row items - - // check if - assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", "count", u"3"); - // check if last element, has t="grand" - assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[last()]", "t", u"grand"); - - // Column items - - // check if - assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", "count", u"1"); - // check if has only a single element - assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i", 1); - // check if element has t="grand" - assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i", "t", u"grand"); - // check if has - assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i/x:x", "v", u"0"); -} - -CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testTdf123225PivotTableEmptyRowColItems) -{ - // this doc contains blank row/col items - // (xl/pivotCache/pivotCacheDefinition1.xml) - createScDoc("ods/tdf123225_pivotTable_empty_row_col_items.ods"); - save(TestFilter::XLSX); - - xmlDocUniquePtr pSheet = parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr); - CPPUNIT_ASSERT(pSheet); - - // Row items - - assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", 1); - // check if - assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems", "count", u"4"); - - // Column items - - assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", 1); - // check if - assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems", "count", u"5"); -} - CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testPivotTableNamedRangeSourceODS) { createScDoc("ods/pivot-table-named-range-source.ods"); diff --git a/sc/source/core/data/pivot/PivotTableResultTraverser.cxx b/sc/source/core/data/pivot/PivotTableResultTraverser.cxx new file mode 100644 index 000000000000..90037e6684e3 --- /dev/null +++ b/sc/source/core/data/pivot/PivotTableResultTraverser.cxx @@ -0,0 +1,125 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace css; + +namespace sc +{ +namespace pivot +{ +uno::Any getMemberForLevel(uno::Reference const& xLevel, OUString const& rName) +{ + uno::Reference xMembersSupplier(xLevel, uno::UNO_QUERY); + if (xMembersSupplier.is()) + { + uno::Reference xMembers = xMembersSupplier->getMembers(); + if (xMembers.is()) + { + if (xMembers->hasByName(rName)) + return xMembers->getByName(rName); + } + } + return uno::Any(); +} +} + +// PivotTableResultTraverser + +void PivotTableResultTraverser::traverse() +{ + uno::Reference xDimensionsSupplier(mrDPObject.GetSource()); + uno::Reference xDimensions + = new ScNameToIndexAccess(xDimensionsSupplier->getDimensions()); + + for (sal_Int32 nDimension = 0; nDimension < xDimensions->getCount(); nDimension++) + { + uno::Reference xDimension(xDimensions->getByIndex(nDimension), + uno::UNO_QUERY); + uno::Reference xDimensionPropertySet(xDimension, uno::UNO_QUERY); + uno::Reference xDimensionSupplier(xDimension, uno::UNO_QUERY); + + if (xDimensionPropertySet.is() && xDimensionSupplier.is()) + { + sheet::DataPilotFieldOrientation eDimensionOrientation + = ScUnoHelpFunctions::GetEnumProperty(xDimensionPropertySet, SC_UNO_DP_ORIENTATION, + sheet::DataPilotFieldOrientation_HIDDEN); + mrVisitor.startDimension(nDimension, xDimension, eDimensionOrientation); + + if (!mrVisitor.filterOrientation(eDimensionOrientation)) + { + uno::Reference xHierarchies + = new ScNameToIndexAccess(xDimensionSupplier->getHierarchies()); + sal_Int32 nHierarchy = ScUnoHelpFunctions::GetLongProperty(xDimensionPropertySet, + SC_UNO_DP_USEDHIERARCHY); + if (nHierarchy >= xHierarchies->getCount()) + nHierarchy = 0; + + uno::Reference xLevelsSupplier( + xHierarchies->getByIndex(nHierarchy), uno::UNO_QUERY); + if (xLevelsSupplier.is()) + { + uno::Reference xLevels + = new ScNameToIndexAccess(xLevelsSupplier->getLevels()); + if (xLevels.is()) + { + for (sal_Int32 nLevel = 0; nLevel < xLevels->getCount(); nLevel++) + { + uno::Reference xLevel(xLevels->getByIndex(nLevel), + uno::UNO_QUERY); + uno::Reference xLevelName(xLevel, uno::UNO_QUERY); + uno::Reference xLevelResult( + xLevel, uno::UNO_QUERY); + + if (xLevelName.is() && xLevelResult.is()) + { + mrVisitor.startLevel(nLevel, xLevel, xLevelName->getName()); + + const uno::Sequence aSequence + = xLevelResult->getResults(); + sal_Int32 nCurrent = 0; + sal_Int32 nSize = aSequence.getLength(); + for (sheet::MemberResult const& rMemberResult : aSequence) + { + mrVisitor.memberResult(rMemberResult, nCurrent, nSize); + nCurrent++; + } + mrVisitor.endLevel(); + } + } + } + } + } + mrVisitor.endDimension(); + } + } +} + +} // end sc + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/filter/excel/xepivotxml.cxx b/sc/source/filter/excel/xepivotxml.cxx index 0667ef11347c..5b2596289de0 100644 --- a/sc/source/filter/excel/xepivotxml.cxx +++ b/sc/source/filter/excel/xepivotxml.cxx @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,7 @@ #include #include #include +#include #include #include @@ -37,8 +39,15 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include +#include using namespace oox; using namespace com::sun::star; @@ -711,12 +720,233 @@ sal_Int32 GetSubtotalAttrToken(ScGeneralFunction eFunc) return XML_defaultSubtotal; } +struct RowOrColumnItemsData +{ + bool mbSet = false; + bool mbContinue = false; + bool mbSubtotal = false; + bool mbGrandTotal = false; + OUString msName; + OUString maLevelName; +}; + +struct RowOrColumnMemberResultData +{ + std::vector maFieldOrder; + std::vector> maItemsData; + std::unordered_map> maLookUpIndexForMemberName; + + void ensureItemData(sal_Int32 nSize) + { + if (maItemsData.size() < o3tl::make_unsigned(nSize)) + maItemsData.resize(nSize); + } + + RowOrColumnItemsData& addItemsData(OUString const& sName, sal_Int32 nIndex) + { + auto& rItemsMap = maItemsData[nIndex]; + + if (!rItemsMap.contains(sName)) + rItemsMap.emplace(sName, RowOrColumnItemsData()); + + return rItemsMap[sName]; + } + + void initLookupFor(OUString const& sDimensionName) + { + maLookUpIndexForMemberName.emplace(sDimensionName, std::unordered_map{}); + } + + void addLookupEntryFor(OUString const& sDimensionName, OUString const& sMemberName, sal_Int32 nIndex) + { + maLookUpIndexForMemberName[sDimensionName].emplace(sMemberName, nIndex); + } + + sal_Int32 lookup(OUString const& sDimensionName, OUString const& sMemberName) + { + return maLookUpIndexForMemberName[sDimensionName][sMemberName]; + } +}; + +class RowColumnItemsDataVisitor : public sc::PivotTableResultVisitor +{ + RowOrColumnMemberResultData& mrRowMemberResultData; + RowOrColumnMemberResultData& mrColumnMemberResultData; + +public: + RowColumnItemsDataVisitor(RowOrColumnMemberResultData& rRowMemberResultData, RowOrColumnMemberResultData& rColumnMemberResultData) + : mrRowMemberResultData(rRowMemberResultData) + , mrColumnMemberResultData(rColumnMemberResultData) + {} + + sheet::DataPilotFieldOrientation meCurrentOrientation = sheet::DataPilotFieldOrientation_HIDDEN; + OUString maLevelName; + + bool filterOrientation(sheet::DataPilotFieldOrientation eOrientation) override + { + return eOrientation == sheet::DataPilotFieldOrientation_HIDDEN; + } + + void startDimension(sal_Int32 /*nDimensionIndex*/, uno::Reference const& /*xDimension*/, sheet::DataPilotFieldOrientation eOrientation) override + { + meCurrentOrientation = eOrientation; + } + + void endDimension() override + { + meCurrentOrientation = sheet::DataPilotFieldOrientation_HIDDEN; + } + + void startLevel(sal_Int32 /*nLevelIndex*/, uno::Reference const& /*xLevel*/, OUString const& rLevelName) override + { + maLevelName = rLevelName; + } + + void endLevel() override + { + maLevelName = OUString(); + } + + void memberResult(sheet::MemberResult const& rResult, sal_Int32 nIndex, sal_Int32 nSize) override + { + if (meCurrentOrientation == sheet::DataPilotFieldOrientation_ROW) + { + mrRowMemberResultData.ensureItemData(nSize); + gatherFieldsData(mrRowMemberResultData, rResult, nIndex); + } + else if (meCurrentOrientation == sheet::DataPilotFieldOrientation_COLUMN) + { + mrColumnMemberResultData.ensureItemData(nSize); + gatherFieldsData(mrColumnMemberResultData, rResult, nIndex); + } + } + + void gatherFieldsData(RowOrColumnMemberResultData& rMemberResultData, sheet::MemberResult const& rResult, sal_Int32 nIndex) + { + auto& rItemsData = rMemberResultData.addItemsData(maLevelName, nIndex); + assert(!rItemsData.mbSet); + + rItemsData.mbSet = true; + rItemsData.maLevelName = maLevelName; + + bool bHasContinueFlag = rResult.Flags & sheet::MemberResultFlags::CONTINUE; + bool bIsGrandTotal = rResult.Flags & sheet::MemberResultFlags::GRANDTOTAL; + bool bIsSubtotal = rResult.Flags & sheet::MemberResultFlags::SUBTOTAL; + + if (bIsGrandTotal) + { + rItemsData.mbGrandTotal = true; + } + else if (bIsSubtotal) + { + rItemsData.mbSubtotal = true; + rItemsData.msName = rResult.Name; + } + else if (bHasContinueFlag) + { + rItemsData.mbContinue = true; + } + else + { + rItemsData.msName = rResult.Name; + } + } +}; + +void writeRowColumnItems(sal_Int32 nItemElement, RowOrColumnMemberResultData& rMemberResultData, sax_fastparser::FSHelperPtr& pStream) +{ + if (rMemberResultData.maItemsData.empty() || rMemberResultData.maFieldOrder.empty()) + { + pStream->startElement(nItemElement, XML_count, "1"); + pStream->singleElement(XML_i); + pStream->endElement(nItemElement); + return; + } + + pStream->startElement(nItemElement, XML_count, OString::number(rMemberResultData.maItemsData.size())); + for (auto& rItemMap : rMemberResultData.maItemsData) + { + bool bIsGrandTotal = false; + bool bIsSubtotal = false; + + for (OUString const& rFieldName : rMemberResultData.maFieldOrder) + { + RowOrColumnItemsData const& rData = rItemMap[rFieldName]; + if (rData.mbSubtotal) + bIsSubtotal = true; + if (rData.mbGrandTotal) + bIsGrandTotal = true; + } + + { + OUString const& rFieldName = rMemberResultData.maFieldOrder[0]; + RowOrColumnItemsData const& rData = rItemMap[rFieldName]; + sal_Int32 nIndex = -1; + if (!rData.msName.isEmpty()) + nIndex = rMemberResultData.lookup(rFieldName, rData.msName); + if (bIsGrandTotal) + { + pStream->startElement(XML_i, XML_t, "grand"); + pStream->singleElement(XML_x); + } + else if (bIsSubtotal) + { + pStream->startElement(XML_i, XML_t, "default"); + + if (nIndex == 0) // 0 is the default + pStream->singleElement(XML_x); + else + pStream->singleElement(XML_x, XML_v, OString::number(nIndex)); + } + else if (rData.mbContinue) + { + pStream->startElement(XML_i, XML_r, "1"); + } + else if (nIndex >= 0) + { + pStream->startElement(XML_i); + if (nIndex == 0) // 0 is the default + pStream->singleElement(XML_x); + else + pStream->singleElement(XML_x, XML_v, OString::number(nIndex)); + } + else + { + pStream->startElement(XML_i); + } + } + + for (size_t i = 1; i < rMemberResultData.maFieldOrder.size(); i++) + { + OUString const& rItemName = rMemberResultData.maFieldOrder[i]; + RowOrColumnItemsData const& rData = rItemMap[rItemName]; + + sal_Int32 nIndex = -1; + if (!rData.msName.isEmpty()) + nIndex = rMemberResultData.lookup(rItemName, rData.msName); + + if (nIndex >= 0) + { + if (nIndex == 0) // 0 is the default + pStream->singleElement(XML_x); + else + pStream->singleElement(XML_x, XML_v, OString::number(nIndex)); + } + } + + pStream->endElement(XML_i); + } + pStream->endElement(nItemElement); } +} // end anonymous namespace + void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDPObject& rDPObj, sal_Int32 nCacheId ) { typedef std::unordered_map NameToIdMapType; + auto& rDPObjectModifiable = const_cast(rDPObj); + const XclExpXmlPivotCaches::Entry* pCacheEntry = mrCaches.GetCache(nCacheId); if (!pCacheEntry) // Something is horribly wrong. Check your logic. @@ -744,11 +974,9 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP std::vector aPageFields; std::vector aDataFields; - // we should always export and , even if the pivot table - // does not contain col/row items. otherwise, in Excel, pivot table will not - // have all context menu items. - tools::Long nRowItemsCount = 1; // for of pivotTable*.xml - tools::Long nColItemsCount = 1; // for of pivotTable*.xml + RowOrColumnMemberResultData aRowMemberResultData; + RowOrColumnMemberResultData aColumnMemberResultData; + tools::Long nDataDimCount = rSaveData.GetDataDimensionCount(); // Use dimensions in the save data to get their correct ordering. // Dimension order here is significant as they specify the order of @@ -785,9 +1013,11 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP if (nPos == -2 && nDataDimCount <= 1) break; aColFields.push_back(nPos); + aColumnMemberResultData.maFieldOrder.push_back(rDim.GetName()); break; case sheet::DataPilotFieldOrientation_ROW: aRowFields.push_back(nPos); + aRowMemberResultData.maFieldOrder.push_back(rDim.GetName()); break; case sheet::DataPilotFieldOrientation_PAGE: aPageFields.push_back(nPos); @@ -833,9 +1063,6 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP // normalize the order to prevent negative row/col counts - just in case. aOutRange.PutInOrder(); - // both start and end cells are included. subtraction excludes the start cells, therefore add +1. - SCROW pivotTableRowCount = aOutRange.aEnd.Row() - aOutRange.aStart.Row() + 1; - SCCOL pivotTableColCount = aOutRange.aEnd.Col() - aOutRange.aStart.Col() + 1; sal_Int32 nFirstHeaderRow = rDPObj.GetHideHeader() ? 0 : (rDPObj.GetHeaderLayout() ? 2 : 1); sal_Int32 nFirstDataRow = rDPObj.GetHideHeader() ? 1 : 2; @@ -901,8 +1128,8 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP { pPivotStrm->singleElement(XML_pivotField, XML_compact, ToPsz10(false), - XML_showAll, ToPsz10(false), - XML_outline, ToPsz10(false)); + XML_outline, ToPsz10(false), + XML_showAll, ToPsz10(false)); } else { @@ -924,8 +1151,8 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP pPivotStrm->singleElement(XML_pivotField, XML_dataField, ToPsz10(true), XML_compact, ToPsz10(false), - XML_showAll, ToPsz10(false), - XML_outline, ToPsz10(false)); + XML_outline, ToPsz10(false), + XML_showAll, ToPsz10(false)); } else { @@ -946,8 +1173,7 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP std::vector aMembers; { // We need to get the members in actual order, getting which requires non-const reference here - auto& dpo = const_cast(rDPObj); - dpo.GetMembers(i, dpo.GetUsedHierarchy(i), aMembers); + rDPObjectModifiable.GetMembers(i, rDPObjectModifiable.GetUsedHierarchy(i), aMembers); } std::vector aCacheFieldItems; @@ -968,9 +1194,16 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP { aCacheFieldItems = SortGroupItems(rCache, i); } + + if (eOrient == sheet::DataPilotFieldOrientation_ROW) + aRowMemberResultData.initLookupFor(pDim->GetName()); + else if (eOrient == sheet::DataPilotFieldOrientation_COLUMN) + aColumnMemberResultData.initLookupFor(pDim->GetName()); + // The pair contains the member index in cache and if it is hidden std::vector< std::pair > aMemberSequence; std::set aUsedCachePositions; + sal_Int32 nIndex = 0; for (const auto & rMember : aMembers) { auto it = std::find(aCacheFieldItems.begin(), aCacheFieldItems.end(), rMember.maName); @@ -979,7 +1212,14 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP size_t nCachePos = static_cast(std::distance(aCacheFieldItems.begin(), it)); auto aInserted = aUsedCachePositions.insert(nCachePos); if (aInserted.second) + { aMemberSequence.emplace_back(std::make_pair(nCachePos, !rMember.mbVisible)); + if (eOrient == sheet::DataPilotFieldOrientation_ROW) + aRowMemberResultData.addLookupEntryFor(pDim->GetName(), rMember.maName, nIndex); + else if (eOrient == sheet::DataPilotFieldOrientation_COLUMN) + aColumnMemberResultData.addLookupEntryFor(pDim->GetName(), rMember.maName, nIndex); + nIndex++; + } } } // Now add all remaining cache items as hidden @@ -1011,6 +1251,9 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP if (!bDimInCompactMode) pAttList->add(XML_compact, ToPsz10(false)); + if(bDimInTabularMode) + pAttList->add(XML_outline, ToPsz10(false)); + pAttList->add(XML_showAll, ToPsz10(false)); tools::Long nSubTotalCount = pDim->GetSubTotalsCount(); @@ -1030,8 +1273,7 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP if (!bHasDefaultSubtotal) pAttList->add(XML_defaultSubtotal, ToPsz10(false)); - if(bDimInTabularMode) - pAttList->add( XML_outline, ToPsz10(false)); + pPivotStrm->startElement(XML_pivotField, pAttList); sal_uInt32 nItems = aMemberSequence.size() + aSubtotalSequence.size(); @@ -1049,11 +1291,6 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP pPivotStrm->singleElement(XML_item, pItemAttList); } - if (strcmp(toOOXMLAxisType(eOrient), "axisCol") == 0) - nColItemsCount = pivotTableColCount - nFirstDataCol; - else if (strcmp(toOOXMLAxisType(eOrient), "axisRow") == 0) - nRowItemsCount = pivotTableRowCount - nFirstDataRow; - for (const OString& sSubtotal : aSubtotalSequence) { pPivotStrm->singleElement(XML_item, XML_t, sSubtotal); @@ -1081,32 +1318,13 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP pPivotStrm->endElement(XML_rowFields); } + RowColumnItemsDataVisitor aVisitor(aRowMemberResultData, aColumnMemberResultData); + sc::PivotTableResultTraverser aTraverser(rDPObjectModifiable, aVisitor); + aTraverser.traverse(); + // - if (nRowItemsCount > 0) - { - pPivotStrm->startElement(XML_rowItems, XML_count, OString::number(nRowItemsCount)); - // export nRowItemsCount times and elements - for (tools::Long nCount = 0; nCount < nRowItemsCount; ++nCount) - { - /* we should add t="grand" to the last element. Otherwise, Excel will not - have all functions in the context menu of the pivot table. Especially for the - "Grand Total" column/row cells. - - note: it is not completely clear that the last element always gets t="grand". - however, testing on the same docs indicate that t="grand" should be - in the last element, so let's try this here. */ - if (nCount == nRowItemsCount - 1) - pPivotStrm->startElement(XML_i, XML_t, "grand"); - else - pPivotStrm->startElement(XML_i); - - pPivotStrm->singleElement(XML_x, XML_v, OString::number(nCount)); - pPivotStrm->endElement(XML_i); - } - - pPivotStrm->endElement(XML_rowItems); - } + writeRowColumnItems(XML_rowItems, aRowMemberResultData, pPivotStrm); // @@ -1124,31 +1342,8 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP } // - if (nColItemsCount > 0) - { - pPivotStrm->startElement(XML_colItems, XML_count, OString::number(nColItemsCount)); - // export nColItemsCount times and elements - for (tools::Long nCount = 0; nCount < nColItemsCount; ++nCount) - { - /* we should add t="grand" to the last element. Otherwise, Excel will not - have all functions in the context menu of the pivot table. Especially for the - "Grand Total" column/row cells. - - note: it is not completely clear that the last element always gets t="grand". - however, testing on the some docs indicate that t="grand" should be - in the last element, so let's try this here. */ - if (nCount == nColItemsCount - 1) - pPivotStrm->startElement(XML_i, XML_t, "grand"); - else - pPivotStrm->startElement(XML_i); - - pPivotStrm->singleElement(XML_x, XML_v, OString::number(nCount)); - pPivotStrm->endElement(XML_i); - } - - pPivotStrm->endElement(XML_colItems); - } + writeRowColumnItems(XML_colItems, aColumnMemberResultData, pPivotStrm); //