sc/inc/dpobject.hxx | 4 sc/inc/dpoutput.hxx | 3 sc/qa/unit/PivotTableFormatsImportExport.cxx | 60 +++--- sc/qa/unit/data/xlsx/pivot-table/first_header_row_zero.xlsx |binary sc/qa/unit/pivottable_filters_test.cxx | 105 ++++++------ sc/source/core/data/dpobject.cxx | 7 sc/source/core/data/dpoutput.cxx | 20 +- sc/source/filter/excel/xepivotxml.cxx | 4 sc/source/filter/oox/pivottablebuffer.cxx | 2 9 files changed, 118 insertions(+), 87 deletions(-)
New commits: commit cd4498d32867af26e95de84836b724b4f85ba1b0 Author: Jaume Pujantell <jaume.pujant...@collabora.com> AuthorDate: Tue Aug 13 20:30:56 2024 +0200 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Sun Aug 18 22:35:50 2024 +0200 tdf#162466 calc: added handling of firstHeaderRow="0" on xlsx files Calc ignored the firstHeaderRow attibute on xlsx pivot tables causing it to add an extra row when firstHeaderRow="0". And then changed the value to "1" on export. Some xlsx pivot table filter tests have been changed because removing this extra row changed the position of the values. Change-Id: I95b722e4f4cc40083c752a045df4ffe37e7159c5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171836 Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171869 Tested-by: Jenkins diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx index 06ffc0085cf2..ce05a46f7c6b 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -107,6 +107,7 @@ private: bool mbAllowMove : 1; bool mbSettingsChanged : 1; bool mbEnableGetPivotData : 1; + bool mbHideHeader : 1 = false; void CreateObjects(); void CreateOutput(); @@ -148,6 +149,9 @@ public: SC_DLLPUBLIC void SetHeaderLayout(bool bUseGrid); bool GetHeaderLayout() const { return mbHeaderLayout;} + SC_DLLPUBLIC void SetHideHeader(bool bHideHeader); + bool GetHideHeader() const { return mbHideHeader; } + SC_DLLPUBLIC void SetSheetDesc(const ScSheetSourceDesc& rDesc); void SetImportDesc(const ScImportSourceDesc& rDesc); void SetServiceData(const ScDPServiceDesc& rDesc); diff --git a/sc/inc/dpoutput.hxx b/sc/inc/dpoutput.hxx index 11251afd4fdf..29423ab66c57 100644 --- a/sc/inc/dpoutput.hxx +++ b/sc/inc/dpoutput.hxx @@ -88,6 +88,7 @@ private: bool mbHeaderLayout:1; // true : grid, false : standard bool mbHasCompactRowField:1; // true: at least one of the row fields has compact layout. bool mbExpandCollapse:1; // true: show expand/collapse buttons + bool mbHideHeader : 1; void DataCell( SCCOL nCol, SCROW nRow, SCTAB nTab, const css::sheet::DataResult& rData ); @@ -120,7 +121,7 @@ public: ScDPOutput(ScDocument* pDocument, css::uno::Reference<css::sheet::XDimensionsSupplier> xSource, const ScAddress& rPosition, bool bFilter, bool bExpandCollapse, - ScDPObject& rObject); + ScDPObject& rObject, bool bHideHeader); ~ScDPOutput(); void SetPosition( const ScAddress& rPos ); diff --git a/sc/qa/unit/PivotTableFormatsImportExport.cxx b/sc/qa/unit/PivotTableFormatsImportExport.cxx index 3c3b9414d29e..22d56c0f11d6 100644 --- a/sc/qa/unit/PivotTableFormatsImportExport.cxx +++ b/sc/qa/unit/PivotTableFormatsImportExport.cxx @@ -122,13 +122,13 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport, static void assertDataFieldInColumn_ColumnLabelColor(ScDocument& rDoc) { - CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, getFontColor(rDoc, u"H5"_ustr)); - CPPUNIT_ASSERT_EQUAL(Color(0x92D050), getBackgroundColor(rDoc, u"I5"_ustr)); + CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, getFontColor(rDoc, u"H4"_ustr)); + CPPUNIT_ASSERT_EQUAL(Color(0x92D050), getBackgroundColor(rDoc, u"I4"_ustr)); // Make sure the other cells have the font color or background set to default std::vector<OUString> aEmptyAddresses{ - u"G5"_ustr, u"G6"_ustr, u"H6"_ustr, u"I6"_ustr, u"G7"_ustr, u"H7"_ustr, u"I7"_ustr, - u"G8"_ustr, u"H8"_ustr, u"I8"_ustr, u"G9"_ustr, u"H9"_ustr, u"I9"_ustr, + u"G4"_ustr, u"G5"_ustr, u"H5"_ustr, u"I5"_ustr, u"G6"_ustr, u"H6"_ustr, u"I6"_ustr, + u"G7"_ustr, u"H7"_ustr, u"I7"_ustr, u"G8"_ustr, u"H8"_ustr, u"I8"_ustr, }; CPPUNIT_ASSERT_EQUAL(OUString(), checkNonEmptyAddresses(rDoc, aEmptyAddresses)); } @@ -145,12 +145,12 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport, static void assertDataFieldInColumn_DataColor(ScDocument& rDoc) { - CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, getFontColor(rDoc, u"H7"_ustr)); - CPPUNIT_ASSERT_EQUAL(Color(0x92D050), getBackgroundColor(rDoc, u"I9"_ustr)); + CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, getFontColor(rDoc, u"H6"_ustr)); + CPPUNIT_ASSERT_EQUAL(Color(0x92D050), getBackgroundColor(rDoc, u"I8"_ustr)); std::vector<OUString> aEmptyAddresses{ - u"G5"_ustr, u"H5"_ustr, u"I5"_ustr, u"G6"_ustr, u"H6"_ustr, u"I6"_ustr, u"G7"_ustr, - u"I7"_ustr, u"G8"_ustr, u"H8"_ustr, u"I8"_ustr, u"G9"_ustr, u"H9"_ustr, + u"G4"_ustr, u"H4"_ustr, u"I4"_ustr, u"G5"_ustr, u"H5"_ustr, u"I5"_ustr, u"G6"_ustr, + u"I6"_ustr, u"G7"_ustr, u"H7"_ustr, u"I7"_ustr, u"G8"_ustr, u"H8"_ustr, }; CPPUNIT_ASSERT_EQUAL(OUString(), checkNonEmptyAddresses(rDoc, aEmptyAddresses)); } @@ -166,17 +166,17 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport, static void assertDataFieldInColumnAndTwoRowFields_DataColor(ScDocument& rDoc) { - CPPUNIT_ASSERT_EQUAL(COL_YELLOW, getBackgroundColor(rDoc, u"I8"_ustr)); - CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, getBackgroundColor(rDoc, u"I11"_ustr)); - CPPUNIT_ASSERT_EQUAL(Color(0x0070C0), getBackgroundColor(rDoc, u"J13"_ustr)); + CPPUNIT_ASSERT_EQUAL(COL_YELLOW, getBackgroundColor(rDoc, u"I7"_ustr)); + CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, getBackgroundColor(rDoc, u"I10"_ustr)); + CPPUNIT_ASSERT_EQUAL(Color(0x0070C0), getBackgroundColor(rDoc, u"J12"_ustr)); std::vector<OUString> aEmptyAddresses{ - u"G5"_ustr, u"H5"_ustr, u"I5"_ustr, u"J5"_ustr, u"G6"_ustr, u"H6"_ustr, u"I6"_ustr, - u"J6"_ustr, u"G7"_ustr, u"H7"_ustr, u"I7"_ustr, u"J7"_ustr, u"G8"_ustr, u"H8"_ustr, - u"J8"_ustr, u"G9"_ustr, u"H9"_ustr, u"I9"_ustr, u"J9"_ustr, u"G10"_ustr, u"H10"_ustr, - u"I10"_ustr, u"J10"_ustr, u"G11"_ustr, u"H11"_ustr, u"J11"_ustr, u"G12"_ustr, u"H12"_ustr, - u"I12"_ustr, u"J12"_ustr, u"G13"_ustr, u"H13"_ustr, u"I13"_ustr, u"G14"_ustr, u"H14"_ustr, - u"I14"_ustr, u"J14"_ustr, + u"G4"_ustr, u"H4"_ustr, u"I4"_ustr, u"J4"_ustr, u"G5"_ustr, u"H5"_ustr, u"I5"_ustr, + u"J5"_ustr, u"G6"_ustr, u"H6"_ustr, u"I6"_ustr, u"J6"_ustr, u"G7"_ustr, u"H7"_ustr, + u"J7"_ustr, u"G8"_ustr, u"H8"_ustr, u"I8"_ustr, u"J8"_ustr, u"G9"_ustr, u"H9"_ustr, + u"I9"_ustr, u"J9"_ustr, u"G10"_ustr, u"H10"_ustr, u"J10"_ustr, u"G11"_ustr, u"H11"_ustr, + u"I11"_ustr, u"J11"_ustr, u"G12"_ustr, u"H12"_ustr, u"I12"_ustr, u"G13"_ustr, u"H13"_ustr, + u"I13"_ustr, u"J13"_ustr, }; CPPUNIT_ASSERT_EQUAL(OUString(), checkNonEmptyAddresses(rDoc, aEmptyAddresses)); } @@ -251,9 +251,9 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport, static void assertMultipleSelections(ScDocument& rDoc) { + CPPUNIT_ASSERT_EQUAL(COL_YELLOW, getBackgroundColor(rDoc, u"I5"_ustr)); CPPUNIT_ASSERT_EQUAL(COL_YELLOW, getBackgroundColor(rDoc, u"I6"_ustr)); CPPUNIT_ASSERT_EQUAL(COL_YELLOW, getBackgroundColor(rDoc, u"I7"_ustr)); - CPPUNIT_ASSERT_EQUAL(COL_YELLOW, getBackgroundColor(rDoc, u"I8"_ustr)); } CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport, @@ -363,17 +363,17 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport, static void assertTwoRowsDataFieldInColumn_LabelColor(ScDocument& rDoc) { - CPPUNIT_ASSERT_EQUAL(COL_YELLOW, getBackgroundColor(rDoc, u"I5"_ustr)); - CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, getBackgroundColor(rDoc, u"J5"_ustr)); + CPPUNIT_ASSERT_EQUAL(COL_YELLOW, getBackgroundColor(rDoc, u"I4"_ustr)); + CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, getBackgroundColor(rDoc, u"J4"_ustr)); // Make sure the other cells have the font color or background set to default std::vector<OUString> aEmptyAddresses{ - u"G5"_ustr, u"H5"_ustr, u"G6"_ustr, u"H6"_ustr, u"i6"_ustr, u"j6"_ustr, u"G7"_ustr, - u"H7"_ustr, u"i7"_ustr, u"j7"_ustr, u"G8"_ustr, u"H8"_ustr, u"i8"_ustr, u"j8"_ustr, - u"G9"_ustr, u"H9"_ustr, u"i9"_ustr, u"j9"_ustr, u"G10"_ustr, u"H10"_ustr, u"i10"_ustr, - u"j10"_ustr, u"G11"_ustr, u"H11"_ustr, u"i11"_ustr, u"j11"_ustr, u"G12"_ustr, u"H12"_ustr, - u"i12"_ustr, u"j12"_ustr, u"G13"_ustr, u"H13"_ustr, u"i13"_ustr, u"j13"_ustr, u"G14"_ustr, - u"H14"_ustr, u"i14"_ustr, u"j14"_ustr, + u"G4"_ustr, u"H4"_ustr, u"G5"_ustr, u"H5"_ustr, u"i5"_ustr, u"j5"_ustr, u"G6"_ustr, + u"H6"_ustr, u"i6"_ustr, u"j6"_ustr, u"G7"_ustr, u"H7"_ustr, u"i7"_ustr, u"j7"_ustr, + u"G8"_ustr, u"H8"_ustr, u"i8"_ustr, u"j8"_ustr, u"G9"_ustr, u"H9"_ustr, u"i9"_ustr, + u"j9"_ustr, u"G10"_ustr, u"H10"_ustr, u"i10"_ustr, u"j10"_ustr, u"G11"_ustr, u"H11"_ustr, + u"i11"_ustr, u"j11"_ustr, u"G12"_ustr, u"H12"_ustr, u"i12"_ustr, u"j12"_ustr, u"G13"_ustr, + u"H13"_ustr, u"i13"_ustr, u"j13"_ustr, }; CPPUNIT_ASSERT_EQUAL(OUString(), checkNonEmptyAddresses(rDoc, aEmptyAddresses)); } @@ -390,18 +390,18 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport, static void assertTwoDataFieldColumns_WholeDataColumnSelected(ScDocument& rDoc) { + CPPUNIT_ASSERT_EQUAL(COL_YELLOW, getBackgroundColor(rDoc, u"H2"_ustr)); CPPUNIT_ASSERT_EQUAL(COL_YELLOW, getBackgroundColor(rDoc, u"H3"_ustr)); CPPUNIT_ASSERT_EQUAL(COL_YELLOW, getBackgroundColor(rDoc, u"H4"_ustr)); CPPUNIT_ASSERT_EQUAL(COL_YELLOW, getBackgroundColor(rDoc, u"H5"_ustr)); CPPUNIT_ASSERT_EQUAL(COL_YELLOW, getBackgroundColor(rDoc, u"H6"_ustr)); CPPUNIT_ASSERT_EQUAL(COL_YELLOW, getBackgroundColor(rDoc, u"H7"_ustr)); - CPPUNIT_ASSERT_EQUAL(COL_YELLOW, getBackgroundColor(rDoc, u"H8"_ustr)); // Make sure the other cells have the font color or background set to default std::vector<OUString> aEmptyAddresses{ - u"F1"_ustr, u"G1"_ustr, u"H1"_ustr, u"F2"_ustr, u"G2"_ustr, u"H2"_ustr, - u"F3"_ustr, u"G3"_ustr, u"F4"_ustr, u"G4"_ustr, u"F5"_ustr, u"G5"_ustr, - u"F6"_ustr, u"G6"_ustr, u"F7"_ustr, u"G7"_ustr, u"F8"_ustr, u"G8"_ustr, + u"F1"_ustr, u"G1"_ustr, u"H1"_ustr, u"F2"_ustr, u"G2"_ustr, + u"F3"_ustr, u"G3"_ustr, u"F4"_ustr, u"G4"_ustr, u"F5"_ustr, + u"G5"_ustr, u"F6"_ustr, u"G6"_ustr, u"F7"_ustr, u"G7"_ustr, }; CPPUNIT_ASSERT_EQUAL(OUString(), checkNonEmptyAddresses(rDoc, aEmptyAddresses)); } diff --git a/sc/qa/unit/data/xlsx/pivot-table/first_header_row_zero.xlsx b/sc/qa/unit/data/xlsx/pivot-table/first_header_row_zero.xlsx new file mode 100644 index 000000000000..9660f6354b88 Binary files /dev/null and b/sc/qa/unit/data/xlsx/pivot-table/first_header_row_zero.xlsx differ diff --git a/sc/qa/unit/pivottable_filters_test.cxx b/sc/qa/unit/pivottable_filters_test.cxx index 17391890e4f6..e6b49591b9c3 100644 --- a/sc/qa/unit/pivottable_filters_test.cxx +++ b/sc/qa/unit/pivottable_filters_test.cxx @@ -329,22 +329,22 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testPivotTableSharedGroupXLSX) // Check whether right group names are imported for both tables // First table - CPPUNIT_ASSERT_EQUAL(u"a2"_ustr, pDoc->GetString(ScAddress(0, 1, 0))); - CPPUNIT_ASSERT_EQUAL(u"Csoport1"_ustr, pDoc->GetString(ScAddress(0, 2, 0))); - CPPUNIT_ASSERT_EQUAL(u"Csoport2"_ustr, pDoc->GetString(ScAddress(0, 3, 0))); - CPPUNIT_ASSERT_EQUAL(u"Csoport3"_ustr, pDoc->GetString(ScAddress(0, 4, 0))); - CPPUNIT_ASSERT_EQUAL(u"16"_ustr, pDoc->GetString(ScAddress(0, 5, 0))); - CPPUNIT_ASSERT_EQUAL(u"17"_ustr, pDoc->GetString(ScAddress(0, 6, 0))); - CPPUNIT_ASSERT_EQUAL(u"18"_ustr, pDoc->GetString(ScAddress(0, 7, 0))); + CPPUNIT_ASSERT_EQUAL(u"a2"_ustr, pDoc->GetString(ScAddress(0, 0, 0))); + CPPUNIT_ASSERT_EQUAL(u"Csoport1"_ustr, pDoc->GetString(ScAddress(0, 1, 0))); + CPPUNIT_ASSERT_EQUAL(u"Csoport2"_ustr, pDoc->GetString(ScAddress(0, 2, 0))); + CPPUNIT_ASSERT_EQUAL(u"Csoport3"_ustr, pDoc->GetString(ScAddress(0, 3, 0))); + CPPUNIT_ASSERT_EQUAL(u"16"_ustr, pDoc->GetString(ScAddress(0, 4, 0))); + CPPUNIT_ASSERT_EQUAL(u"17"_ustr, pDoc->GetString(ScAddress(0, 5, 0))); + CPPUNIT_ASSERT_EQUAL(u"18"_ustr, pDoc->GetString(ScAddress(0, 6, 0))); // Second table - CPPUNIT_ASSERT_EQUAL(u"a2"_ustr, pDoc->GetString(ScAddress(0, 11, 0))); - CPPUNIT_ASSERT_EQUAL(u"Csoport1"_ustr, pDoc->GetString(ScAddress(0, 12, 0))); - CPPUNIT_ASSERT_EQUAL(u"Csoport2"_ustr, pDoc->GetString(ScAddress(0, 13, 0))); - CPPUNIT_ASSERT_EQUAL(u"Csoport3"_ustr, pDoc->GetString(ScAddress(0, 14, 0))); - CPPUNIT_ASSERT_EQUAL(u"16"_ustr, pDoc->GetString(ScAddress(0, 15, 0))); - CPPUNIT_ASSERT_EQUAL(u"17"_ustr, pDoc->GetString(ScAddress(0, 16, 0))); - CPPUNIT_ASSERT_EQUAL(u"18"_ustr, pDoc->GetString(ScAddress(0, 17, 0))); + CPPUNIT_ASSERT_EQUAL(u"a2"_ustr, pDoc->GetString(ScAddress(0, 10, 0))); + CPPUNIT_ASSERT_EQUAL(u"Csoport1"_ustr, pDoc->GetString(ScAddress(0, 11, 0))); + CPPUNIT_ASSERT_EQUAL(u"Csoport2"_ustr, pDoc->GetString(ScAddress(0, 12, 0))); + CPPUNIT_ASSERT_EQUAL(u"Csoport3"_ustr, pDoc->GetString(ScAddress(0, 13, 0))); + CPPUNIT_ASSERT_EQUAL(u"16"_ustr, pDoc->GetString(ScAddress(0, 14, 0))); + CPPUNIT_ASSERT_EQUAL(u"17"_ustr, pDoc->GetString(ScAddress(0, 15, 0))); + CPPUNIT_ASSERT_EQUAL(u"18"_ustr, pDoc->GetString(ScAddress(0, 16, 0))); // There should be exactly 2 pivot tables and 1 cache. ScDPCollection* pDPs = pDoc->GetDPCollection(); @@ -364,22 +364,22 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testPivotTableSharedDateGroupXLSX) auto testThis = [](ScDocument& rDoc) { // Check whether right date labels are imported for both tables // First table - CPPUNIT_ASSERT_EQUAL(u"a"_ustr, rDoc.GetString(ScAddress(0, 3, 1))); - CPPUNIT_ASSERT_EQUAL(u"1965"_ustr, rDoc.GetString(ScAddress(0, 4, 1))); - CPPUNIT_ASSERT_EQUAL(u"1989"_ustr, rDoc.GetString(ScAddress(0, 5, 1))); - CPPUNIT_ASSERT_EQUAL(u"2000"_ustr, rDoc.GetString(ScAddress(0, 6, 1))); - CPPUNIT_ASSERT_EQUAL(u"2004"_ustr, rDoc.GetString(ScAddress(0, 7, 1))); + CPPUNIT_ASSERT_EQUAL(u"a"_ustr, rDoc.GetString(ScAddress(0, 2, 1))); + CPPUNIT_ASSERT_EQUAL(u"1965"_ustr, rDoc.GetString(ScAddress(0, 3, 1))); + CPPUNIT_ASSERT_EQUAL(u"1989"_ustr, rDoc.GetString(ScAddress(0, 4, 1))); + CPPUNIT_ASSERT_EQUAL(u"2000"_ustr, rDoc.GetString(ScAddress(0, 5, 1))); + CPPUNIT_ASSERT_EQUAL(u"2004"_ustr, rDoc.GetString(ScAddress(0, 6, 1))); // TODO: check why this fails with 2005 - // CPPUNIT_ASSERT_EQUAL(OUString("2007"), rDoc.GetString(ScAddress(0,8,1))); + // CPPUNIT_ASSERT_EQUAL(OUString("2007"), rDoc.GetString(ScAddress(0,7,1))); // Second table - CPPUNIT_ASSERT_EQUAL(u"a"_ustr, rDoc.GetString(ScAddress(5, 3, 1))); - CPPUNIT_ASSERT_EQUAL(u"1965"_ustr, rDoc.GetString(ScAddress(5, 4, 1))); - CPPUNIT_ASSERT_EQUAL(u"1989"_ustr, rDoc.GetString(ScAddress(5, 5, 1))); - CPPUNIT_ASSERT_EQUAL(u"2000"_ustr, rDoc.GetString(ScAddress(5, 6, 1))); - CPPUNIT_ASSERT_EQUAL(u"2004"_ustr, rDoc.GetString(ScAddress(5, 7, 1))); + CPPUNIT_ASSERT_EQUAL(u"a"_ustr, rDoc.GetString(ScAddress(5, 2, 1))); + CPPUNIT_ASSERT_EQUAL(u"1965"_ustr, rDoc.GetString(ScAddress(5, 3, 1))); + CPPUNIT_ASSERT_EQUAL(u"1989"_ustr, rDoc.GetString(ScAddress(5, 4, 1))); + CPPUNIT_ASSERT_EQUAL(u"2000"_ustr, rDoc.GetString(ScAddress(5, 5, 1))); + CPPUNIT_ASSERT_EQUAL(u"2004"_ustr, rDoc.GetString(ScAddress(5, 6, 1))); // TODO: check why this fails with 2005 - // CPPUNIT_ASSERT_EQUAL(OUString("2007"), rDoc.GetString(ScAddress(5,8,1))); + // CPPUNIT_ASSERT_EQUAL(OUString("2007"), rDoc.GetString(ScAddress(5,7,1))); // There should be exactly 2 pivot tables and 1 cache. ScDPCollection* pDPs = rDoc.GetDPCollection(); @@ -405,19 +405,19 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testPivotTableSharedNestedDateGrou // Check whether right date groups are imported for both tables // First table // Years, Quarters, 'a' have compact layout so the only header contains a multi-field filter. - CPPUNIT_ASSERT_EQUAL(u"1965"_ustr, rDoc.GetString(ScAddress(0, 4, 1))); - CPPUNIT_ASSERT_EQUAL(u"1989"_ustr, rDoc.GetString(ScAddress(0, 11, 1))); - CPPUNIT_ASSERT_EQUAL(u"2000"_ustr, rDoc.GetString(ScAddress(0, 18, 1))); - CPPUNIT_ASSERT_EQUAL(u"2004"_ustr, rDoc.GetString(ScAddress(0, 21, 1))); + CPPUNIT_ASSERT_EQUAL(u"1965"_ustr, rDoc.GetString(ScAddress(0, 3, 1))); + CPPUNIT_ASSERT_EQUAL(u"1989"_ustr, rDoc.GetString(ScAddress(0, 10, 1))); + CPPUNIT_ASSERT_EQUAL(u"2000"_ustr, rDoc.GetString(ScAddress(0, 17, 1))); + CPPUNIT_ASSERT_EQUAL(u"2004"_ustr, rDoc.GetString(ScAddress(0, 20, 1))); // TODO: check why this fails with the empty string //CPPUNIT_ASSERT_EQUAL(OUString("2007"), rDoc.GetString(ScAddress(0,32,1))); // Second table // Years, Quarters, 'a' have compact layout so the only row header contains a multi-field filter. - CPPUNIT_ASSERT_EQUAL(u"1965"_ustr, rDoc.GetString(ScAddress(6, 4, 1))); - CPPUNIT_ASSERT_EQUAL(u"1989"_ustr, rDoc.GetString(ScAddress(6, 11, 1))); - CPPUNIT_ASSERT_EQUAL(u"2000"_ustr, rDoc.GetString(ScAddress(6, 18, 1))); - CPPUNIT_ASSERT_EQUAL(u"2004"_ustr, rDoc.GetString(ScAddress(6, 21, 1))); + CPPUNIT_ASSERT_EQUAL(u"1965"_ustr, rDoc.GetString(ScAddress(6, 3, 1))); + CPPUNIT_ASSERT_EQUAL(u"1989"_ustr, rDoc.GetString(ScAddress(6, 10, 1))); + CPPUNIT_ASSERT_EQUAL(u"2000"_ustr, rDoc.GetString(ScAddress(6, 17, 1))); + CPPUNIT_ASSERT_EQUAL(u"2004"_ustr, rDoc.GetString(ScAddress(6, 20, 1))); // TODO: check why this fails with the empty string //CPPUNIT_ASSERT_EQUAL(OUString("2007"), rDoc.GetString(ScAddress(6,31,1))); @@ -449,20 +449,20 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testPivotTableSharedNumGroupXLSX) // Check whether right number groups are imported for both tables // First table - CPPUNIT_ASSERT_EQUAL(u"f"_ustr, pDoc->GetString(ScAddress(0, 3, 1))); - CPPUNIT_ASSERT_EQUAL(u"32674-47673"_ustr, pDoc->GetString(ScAddress(0, 4, 1))); - CPPUNIT_ASSERT_EQUAL(u"47674-62673"_ustr, pDoc->GetString(ScAddress(0, 5, 1))); - CPPUNIT_ASSERT_EQUAL(u"62674-77673"_ustr, pDoc->GetString(ScAddress(0, 6, 1))); - CPPUNIT_ASSERT_EQUAL(u"77674-92673"_ustr, pDoc->GetString(ScAddress(0, 7, 1))); - CPPUNIT_ASSERT_EQUAL(u"92674-107673"_ustr, pDoc->GetString(ScAddress(0, 8, 1))); + CPPUNIT_ASSERT_EQUAL(u"f"_ustr, pDoc->GetString(ScAddress(0, 2, 1))); + CPPUNIT_ASSERT_EQUAL(u"32674-47673"_ustr, pDoc->GetString(ScAddress(0, 3, 1))); + CPPUNIT_ASSERT_EQUAL(u"47674-62673"_ustr, pDoc->GetString(ScAddress(0, 4, 1))); + CPPUNIT_ASSERT_EQUAL(u"62674-77673"_ustr, pDoc->GetString(ScAddress(0, 5, 1))); + CPPUNIT_ASSERT_EQUAL(u"77674-92673"_ustr, pDoc->GetString(ScAddress(0, 6, 1))); + CPPUNIT_ASSERT_EQUAL(u"92674-107673"_ustr, pDoc->GetString(ScAddress(0, 7, 1))); // Second table - CPPUNIT_ASSERT_EQUAL(u"f"_ustr, pDoc->GetString(ScAddress(5, 3, 1))); - CPPUNIT_ASSERT_EQUAL(u"32674-47673"_ustr, pDoc->GetString(ScAddress(5, 4, 1))); - CPPUNIT_ASSERT_EQUAL(u"47674-62673"_ustr, pDoc->GetString(ScAddress(5, 5, 1))); - CPPUNIT_ASSERT_EQUAL(u"62674-77673"_ustr, pDoc->GetString(ScAddress(5, 6, 1))); - CPPUNIT_ASSERT_EQUAL(u"77674-92673"_ustr, pDoc->GetString(ScAddress(5, 7, 1))); - CPPUNIT_ASSERT_EQUAL(u"92674-107673"_ustr, pDoc->GetString(ScAddress(5, 8, 1))); + CPPUNIT_ASSERT_EQUAL(u"f"_ustr, pDoc->GetString(ScAddress(5, 2, 1))); + CPPUNIT_ASSERT_EQUAL(u"32674-47673"_ustr, pDoc->GetString(ScAddress(5, 3, 1))); + CPPUNIT_ASSERT_EQUAL(u"47674-62673"_ustr, pDoc->GetString(ScAddress(5, 4, 1))); + CPPUNIT_ASSERT_EQUAL(u"62674-77673"_ustr, pDoc->GetString(ScAddress(5, 5, 1))); + CPPUNIT_ASSERT_EQUAL(u"77674-92673"_ustr, pDoc->GetString(ScAddress(5, 6, 1))); + CPPUNIT_ASSERT_EQUAL(u"92674-107673"_ustr, pDoc->GetString(ScAddress(5, 7, 1))); // There should be exactly 2 pivot tables and 1 cache. ScDPCollection* pDPs = pDoc->GetDPCollection(); @@ -2714,6 +2714,19 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testThis(*getScDoc()); } +CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testFirstHeaderRowZero) +{ + // Test that an xlsx pivot table with `firstHeaderRow="0"` is shown and exported correctly + createScDoc("xlsx/pivot-table/first_header_row_zero.xlsx"); + // Check that the text under the table is visible + CPPUNIT_ASSERT_EQUAL(OUString("under"), getScDoc()->GetString(ScAddress(2, 6, 1))); + + save("Calc Office Open XML"); + xmlDocUniquePtr pDoc = parseExport("xl/pivotTables/pivotTable1.xml"); + CPPUNIT_ASSERT(pDoc); + assertXPath(pDoc, "/x:pivotTableDefinition/x:location"_ostr, "firstHeaderRow"_ostr, "0"); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index e4ef0c877850..c96ccaa7de74 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -314,6 +314,7 @@ ScDPObject::ScDPObject(ScDocument* pDocument) , mbAllowMove(false) , mbSettingsChanged(false) , mbEnableGetPivotData(true) + , mbHideHeader(false) { } @@ -328,6 +329,7 @@ ScDPObject::ScDPObject(const ScDPObject& rOther) , mbAllowMove(false) , mbSettingsChanged(false) , mbEnableGetPivotData(rOther.mbEnableGetPivotData) + , mbHideHeader(rOther.mbHideHeader) { if (rOther.mpSaveData) mpSaveData.reset(new ScDPSaveData(*rOther.mpSaveData)); @@ -361,6 +363,7 @@ ScDPObject& ScDPObject::operator= (const ScDPObject& rOther) mbAllowMove = false; mbSettingsChanged = false; mbEnableGetPivotData = rOther.mbEnableGetPivotData; + mbHideHeader = rOther.mbHideHeader; if (rOther.mpSaveData) mpSaveData.reset(new ScDPSaveData(*rOther.mpSaveData)); @@ -399,6 +402,8 @@ void ScDPObject::SetHeaderLayout (bool bUseGrid) mbHeaderLayout = bUseGrid; } +void ScDPObject::SetHideHeader(bool bHideHeader) { mbHideHeader = bHideHeader; } + void ScDPObject::SetOutRange(const ScRange& rRange) { maOutputRange = rRange; @@ -528,7 +533,7 @@ void ScDPObject::CreateOutput() bool bFilterButton = IsSheetData() && mpSaveData && mpSaveData->GetFilterButton(); bool bExpandCollapse = mpSaveData ? mpSaveData->GetExpandCollapse() : false; - mpOutput.reset(new ScDPOutput(mpDocument, mxSource, maOutputRange.aStart, bFilterButton, bExpandCollapse, *this)); + mpOutput.reset(new ScDPOutput(mpDocument, mxSource, maOutputRange.aStart, bFilterButton, bExpandCollapse, *this, mbHideHeader)); mpOutput->SetHeaderLayout(mbHeaderLayout); if (mpSaveData->hasFormats()) mpOutput->setFormats(mpSaveData->getFormats()); diff --git a/sc/source/core/data/dpoutput.cxx b/sc/source/core/data/dpoutput.cxx index 1b20d6fc3a56..83cf29066e5b 100644 --- a/sc/source/core/data/dpoutput.cxx +++ b/sc/source/core/data/dpoutput.cxx @@ -486,7 +486,7 @@ uno::Sequence<sheet::MemberResult> getVisiblePageMembersAsResults( const uno::Re } // end anonymous namespace ScDPOutput::ScDPOutput(ScDocument* pDocument, uno::Reference<sheet::XDimensionsSupplier> xSource, - const ScAddress& rPosition, bool bFilter, bool bExpandCollapse, ScDPObject& rObject) + const ScAddress& rPosition, bool bFilter, bool bExpandCollapse, ScDPObject& rObject, bool bHideHeader) : mpDocument(pDocument) , maFormatOutput(rObject) , mxSource(std::move(xSource)) @@ -505,6 +505,7 @@ ScDPOutput::ScDPOutput(ScDocument* pDocument, uno::Reference<sheet::XDimensionsS , mbHeaderLayout(false) , mbHasCompactRowField(false) , mbExpandCollapse(bExpandCollapse) + , mbHideHeader(bHideHeader) { mnTabStartCol = mnMemberStartCol = mnDataStartCol = mnTabEndCol = 0; mnTabStartRow = mnMemberStartRow = mnDataStartRow = mnTabEndRow = 0; @@ -879,7 +880,9 @@ void ScDPOutput::CalcSizes() mnColCount = mnRowCount ? ( pRowAry[0].getLength() ) : 0; mnHeaderSize = 1; - if (GetHeaderLayout() && mpColFields.empty()) + if (mbHideHeader) + mnHeaderSize = 0; + else if (GetHeaderLayout() && mpColFields.empty()) // Insert an extra header row only when there is no column field. mnHeaderSize = 2; @@ -1003,10 +1006,13 @@ void ScDPOutput::outputColumnHeaders(SCTAB nTab, ScDPOutputImpl& rOutputImpl) { SCCOL nHeaderCol = mnDataStartCol + SCCOL(nField); //TODO: check for overflow - if (!mbHasCompactRowField || nNumColFields == 1) - FieldCell(nHeaderCol, mnTabStartRow, nTab, mpColFields[nField], true); - else if (!nField) - MultiFieldCell(nHeaderCol, mnTabStartRow, nTab, false /* bRowField */); + if (mnMemberStartRow > mnTabStartRow) + { + if (!mbHasCompactRowField || nNumColFields == 1) + FieldCell(nHeaderCol, mnTabStartRow, nTab, mpColFields[nField], true); + else if (!nField) + MultiFieldCell(nHeaderCol, mnTabStartRow, nTab, false /* bRowField */); + } SCROW nRowPos = mnMemberStartRow + SCROW(nField); //TODO: check for overflow const uno::Sequence<sheet::MemberResult> rMemberSequence = mpColFields[nField].maResult; @@ -1060,7 +1066,7 @@ void ScDPOutput::outputColumnHeaders(SCTAB nTab, ScDPOutputImpl& rOutputImpl) // Apply the same number format as in data source. mpDocument->ApplyAttr(nColPos, nRowPos, nTab, SfxUInt32Item(ATTR_VALUE_FORMAT, mpColFields[nField].mnSrcNumFmt)); } - if (nField == 0 && mpColFields.size() == 1) + if (nField == 0 && mpColFields.size() == 1 && mnMemberStartRow > mnTabStartRow) rOutputImpl.OutputBlockFrame(mnDataStartCol, mnTabStartRow, mnTabEndCol, nRowPos - 1); } } diff --git a/sc/source/filter/excel/xepivotxml.cxx b/sc/source/filter/excel/xepivotxml.cxx index d6e8bad4d4b8..ddccb1cd36f6 100644 --- a/sc/source/filter/excel/xepivotxml.cxx +++ b/sc/source/filter/excel/xepivotxml.cxx @@ -858,8 +858,8 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP // NB: Excel's range does not include page field area (if any). ScRange aOutRange = rDPObj.GetOutputRangeByType(sheet::DataPilotOutputRangeType::TABLE); - sal_Int32 nFirstHeaderRow = rDPObj.GetHeaderLayout() ? 2 : 1; - sal_Int32 nFirstDataRow = 2; + sal_Int32 nFirstHeaderRow = rDPObj.GetHideHeader() ? 0 : (rDPObj.GetHeaderLayout() ? 2 : 1); + sal_Int32 nFirstDataRow = rDPObj.GetHideHeader() ? 1 : 2; sal_Int32 nFirstDataCol = 1; ScRange aResRange = rDPObj.GetOutputRangeByType(sheet::DataPilotOutputRangeType::RESULT); diff --git a/sc/source/filter/oox/pivottablebuffer.cxx b/sc/source/filter/oox/pivottablebuffer.cxx index 5439b1d58357..249176cf2b7b 100644 --- a/sc/source/filter/oox/pivottablebuffer.cxx +++ b/sc/source/filter/oox/pivottablebuffer.cxx @@ -1288,6 +1288,8 @@ void PivotTable::finalizeImport() aDescProp.setProperty( PROP_ShowFilterButton, false ); aDescProp.setProperty( PROP_DrillDownOnDoubleClick, maDefModel.mbEnableDrill ); + mpDPObject->SetHideHeader(maLocationModel.mnFirstHeaderRow == 0); + if (auto* pSaveData = mpDPObject->GetSaveData()) pSaveData->SetExpandCollapse(maDefModel.mbShowDrill);