sc/inc/dpobject.hxx                                         |    4 
 sc/inc/dpoutput.hxx                                         |    8 
 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                            |   50 +++--
 sc/source/core/data/dpoutput.cxx                            |   56 +++---
 sc/source/filter/excel/xepivotxml.cxx                       |    4 
 sc/source/filter/oox/pivottablebuffer.cxx                   |    2 
 8 files changed, 130 insertions(+), 99 deletions(-)

New commits:
commit 8423a7a21a52c224d5299a952ff7db25c01cad94
Author:     Jaume Pujantell <[email protected]>
AuthorDate: Tue Aug 13 20:30:56 2024 +0200
Commit:     Jaume Pujantell <[email protected]>
CommitDate: Wed Aug 14 15:29:55 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 <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>

diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx
index 0e4cf882b529..a750e48d7030 100644
--- a/sc/inc/dpobject.hxx
+++ b/sc/inc/dpobject.hxx
@@ -106,6 +106,7 @@ private:
     bool                    bAllowMove:1;
     bool                    bSettingsChanged:1;
     bool                    mbEnableGetPivotData:1;
+    bool mbHideHeader : 1;
 
     SAL_DLLPRIVATE ScDPTableData*    GetTableData();
     SAL_DLLPRIVATE void              CreateObjects();
@@ -146,6 +147,9 @@ public:
     void                SetHeaderLayout(bool bUseGrid);
     bool                GetHeaderLayout() const { return mbHeaderLayout;}
 
+    void SetHideHeader(bool bHideHeader);
+    bool GetHideHeader() const { return mbHideHeader; }
+
     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 94decfa44466..de2adf9e51bc 100644
--- a/sc/inc/dpoutput.hxx
+++ b/sc/inc/dpoutput.hxx
@@ -85,6 +85,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 );
@@ -109,10 +110,9 @@ private:
     sal_Int32       GetRowFieldCompact(SCCOL nColQuery, SCROW nRowQuery) const;
 
 public:
-                    ScDPOutput( ScDocument* pD,
-                                css::uno::Reference< 
css::sheet::XDimensionsSupplier> xSrc,
-                                const ScAddress& rPos, bool bFilter, bool 
bExpandCollapse );
-                    ~ScDPOutput();
+    ScDPOutput(ScDocument* pD, 
css::uno::Reference<css::sheet::XDimensionsSupplier> xSrc,
+               const ScAddress& rPos, bool bFilter, bool bExpandCollapse, bool 
bHideHeader);
+    ~ScDPOutput();
 
     void            SetPosition( const ScAddress& rPos );
 
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 31fb49351c8c..8c9c5ab401c9 100644
--- a/sc/qa/unit/pivottable_filters_test.cxx
+++ b/sc/qa/unit/pivottable_filters_test.cxx
@@ -330,22 +330,22 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, 
testPivotTableSharedGroupXLSX)
 
     // Check whether right group names are imported for both tables
     // First table
-    CPPUNIT_ASSERT_EQUAL(OUString("a2"), pDoc->GetString(ScAddress(0, 1, 0)));
-    CPPUNIT_ASSERT_EQUAL(OUString("Csoport1"), pDoc->GetString(ScAddress(0, 2, 
0)));
-    CPPUNIT_ASSERT_EQUAL(OUString("Csoport2"), pDoc->GetString(ScAddress(0, 3, 
0)));
-    CPPUNIT_ASSERT_EQUAL(OUString("Csoport3"), pDoc->GetString(ScAddress(0, 4, 
0)));
-    CPPUNIT_ASSERT_EQUAL(OUString("16"), pDoc->GetString(ScAddress(0, 5, 0)));
-    CPPUNIT_ASSERT_EQUAL(OUString("17"), pDoc->GetString(ScAddress(0, 6, 0)));
-    CPPUNIT_ASSERT_EQUAL(OUString("18"), pDoc->GetString(ScAddress(0, 7, 0)));
+    CPPUNIT_ASSERT_EQUAL(OUString("a2"), pDoc->GetString(ScAddress(0, 0, 0)));
+    CPPUNIT_ASSERT_EQUAL(OUString("Csoport1"), pDoc->GetString(ScAddress(0, 1, 
0)));
+    CPPUNIT_ASSERT_EQUAL(OUString("Csoport2"), pDoc->GetString(ScAddress(0, 2, 
0)));
+    CPPUNIT_ASSERT_EQUAL(OUString("Csoport3"), pDoc->GetString(ScAddress(0, 3, 
0)));
+    CPPUNIT_ASSERT_EQUAL(OUString("16"), pDoc->GetString(ScAddress(0, 4, 0)));
+    CPPUNIT_ASSERT_EQUAL(OUString("17"), pDoc->GetString(ScAddress(0, 5, 0)));
+    CPPUNIT_ASSERT_EQUAL(OUString("18"), pDoc->GetString(ScAddress(0, 6, 0)));
 
     // Second table
-    CPPUNIT_ASSERT_EQUAL(OUString("a2"), pDoc->GetString(ScAddress(0, 11, 0)));
-    CPPUNIT_ASSERT_EQUAL(OUString("Csoport1"), pDoc->GetString(ScAddress(0, 
12, 0)));
-    CPPUNIT_ASSERT_EQUAL(OUString("Csoport2"), pDoc->GetString(ScAddress(0, 
13, 0)));
-    CPPUNIT_ASSERT_EQUAL(OUString("Csoport3"), pDoc->GetString(ScAddress(0, 
14, 0)));
-    CPPUNIT_ASSERT_EQUAL(OUString("16"), pDoc->GetString(ScAddress(0, 15, 0)));
-    CPPUNIT_ASSERT_EQUAL(OUString("17"), pDoc->GetString(ScAddress(0, 16, 0)));
-    CPPUNIT_ASSERT_EQUAL(OUString("18"), pDoc->GetString(ScAddress(0, 17, 0)));
+    CPPUNIT_ASSERT_EQUAL(OUString("a2"), pDoc->GetString(ScAddress(0, 10, 0)));
+    CPPUNIT_ASSERT_EQUAL(OUString("Csoport1"), pDoc->GetString(ScAddress(0, 
11, 0)));
+    CPPUNIT_ASSERT_EQUAL(OUString("Csoport2"), pDoc->GetString(ScAddress(0, 
12, 0)));
+    CPPUNIT_ASSERT_EQUAL(OUString("Csoport3"), pDoc->GetString(ScAddress(0, 
13, 0)));
+    CPPUNIT_ASSERT_EQUAL(OUString("16"), pDoc->GetString(ScAddress(0, 14, 0)));
+    CPPUNIT_ASSERT_EQUAL(OUString("17"), pDoc->GetString(ScAddress(0, 15, 0)));
+    CPPUNIT_ASSERT_EQUAL(OUString("18"), pDoc->GetString(ScAddress(0, 16, 0)));
 
     // There should be exactly 2 pivot tables and 1 cache.
     ScDPCollection* pDPs = pDoc->GetDPCollection();
@@ -365,22 +365,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(OUString("a"), rDoc.GetString(ScAddress(0, 3, 
1)));
-        CPPUNIT_ASSERT_EQUAL(OUString("1965"), rDoc.GetString(ScAddress(0, 4, 
1)));
-        CPPUNIT_ASSERT_EQUAL(OUString("1989"), rDoc.GetString(ScAddress(0, 5, 
1)));
-        CPPUNIT_ASSERT_EQUAL(OUString("2000"), rDoc.GetString(ScAddress(0, 6, 
1)));
-        CPPUNIT_ASSERT_EQUAL(OUString("2004"), rDoc.GetString(ScAddress(0, 7, 
1)));
+        CPPUNIT_ASSERT_EQUAL(OUString("a"), rDoc.GetString(ScAddress(0, 2, 
1)));
+        CPPUNIT_ASSERT_EQUAL(OUString("1965"), rDoc.GetString(ScAddress(0, 3, 
1)));
+        CPPUNIT_ASSERT_EQUAL(OUString("1989"), rDoc.GetString(ScAddress(0, 4, 
1)));
+        CPPUNIT_ASSERT_EQUAL(OUString("2000"), rDoc.GetString(ScAddress(0, 5, 
1)));
+        CPPUNIT_ASSERT_EQUAL(OUString("2004"), 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(OUString("a"), rDoc.GetString(ScAddress(5, 3, 
1)));
-        CPPUNIT_ASSERT_EQUAL(OUString("1965"), rDoc.GetString(ScAddress(5, 4, 
1)));
-        CPPUNIT_ASSERT_EQUAL(OUString("1989"), rDoc.GetString(ScAddress(5, 5, 
1)));
-        CPPUNIT_ASSERT_EQUAL(OUString("2000"), rDoc.GetString(ScAddress(5, 6, 
1)));
-        CPPUNIT_ASSERT_EQUAL(OUString("2004"), rDoc.GetString(ScAddress(5, 7, 
1)));
+        CPPUNIT_ASSERT_EQUAL(OUString("a"), rDoc.GetString(ScAddress(5, 2, 
1)));
+        CPPUNIT_ASSERT_EQUAL(OUString("1965"), rDoc.GetString(ScAddress(5, 3, 
1)));
+        CPPUNIT_ASSERT_EQUAL(OUString("1989"), rDoc.GetString(ScAddress(5, 4, 
1)));
+        CPPUNIT_ASSERT_EQUAL(OUString("2000"), rDoc.GetString(ScAddress(5, 5, 
1)));
+        CPPUNIT_ASSERT_EQUAL(OUString("2004"), 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();
@@ -406,19 +406,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(OUString("1965"), rDoc.GetString(ScAddress(0, 4, 
1)));
-        CPPUNIT_ASSERT_EQUAL(OUString("1989"), rDoc.GetString(ScAddress(0, 11, 
1)));
-        CPPUNIT_ASSERT_EQUAL(OUString("2000"), rDoc.GetString(ScAddress(0, 18, 
1)));
-        CPPUNIT_ASSERT_EQUAL(OUString("2004"), rDoc.GetString(ScAddress(0, 21, 
1)));
+        CPPUNIT_ASSERT_EQUAL(OUString("1965"), rDoc.GetString(ScAddress(0, 3, 
1)));
+        CPPUNIT_ASSERT_EQUAL(OUString("1989"), rDoc.GetString(ScAddress(0, 10, 
1)));
+        CPPUNIT_ASSERT_EQUAL(OUString("2000"), rDoc.GetString(ScAddress(0, 17, 
1)));
+        CPPUNIT_ASSERT_EQUAL(OUString("2004"), 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(OUString("1965"), rDoc.GetString(ScAddress(6, 4, 
1)));
-        CPPUNIT_ASSERT_EQUAL(OUString("1989"), rDoc.GetString(ScAddress(6, 11, 
1)));
-        CPPUNIT_ASSERT_EQUAL(OUString("2000"), rDoc.GetString(ScAddress(6, 18, 
1)));
-        CPPUNIT_ASSERT_EQUAL(OUString("2004"), rDoc.GetString(ScAddress(6, 21, 
1)));
+        CPPUNIT_ASSERT_EQUAL(OUString("1965"), rDoc.GetString(ScAddress(6, 3, 
1)));
+        CPPUNIT_ASSERT_EQUAL(OUString("1989"), rDoc.GetString(ScAddress(6, 10, 
1)));
+        CPPUNIT_ASSERT_EQUAL(OUString("2000"), rDoc.GetString(ScAddress(6, 17, 
1)));
+        CPPUNIT_ASSERT_EQUAL(OUString("2004"), 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)));
 
@@ -450,20 +450,20 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, 
testPivotTableSharedNumGroupXLSX)
 
     // Check whether right number groups are imported for both tables
     // First table
-    CPPUNIT_ASSERT_EQUAL(OUString("f"), pDoc->GetString(ScAddress(0, 3, 1)));
-    CPPUNIT_ASSERT_EQUAL(OUString("32674-47673"), pDoc->GetString(ScAddress(0, 
4, 1)));
-    CPPUNIT_ASSERT_EQUAL(OUString("47674-62673"), pDoc->GetString(ScAddress(0, 
5, 1)));
-    CPPUNIT_ASSERT_EQUAL(OUString("62674-77673"), pDoc->GetString(ScAddress(0, 
6, 1)));
-    CPPUNIT_ASSERT_EQUAL(OUString("77674-92673"), pDoc->GetString(ScAddress(0, 
7, 1)));
-    CPPUNIT_ASSERT_EQUAL(OUString("92674-107673"), 
pDoc->GetString(ScAddress(0, 8, 1)));
+    CPPUNIT_ASSERT_EQUAL(OUString("f"), pDoc->GetString(ScAddress(0, 2, 1)));
+    CPPUNIT_ASSERT_EQUAL(OUString("32674-47673"), pDoc->GetString(ScAddress(0, 
3, 1)));
+    CPPUNIT_ASSERT_EQUAL(OUString("47674-62673"), pDoc->GetString(ScAddress(0, 
4, 1)));
+    CPPUNIT_ASSERT_EQUAL(OUString("62674-77673"), pDoc->GetString(ScAddress(0, 
5, 1)));
+    CPPUNIT_ASSERT_EQUAL(OUString("77674-92673"), pDoc->GetString(ScAddress(0, 
6, 1)));
+    CPPUNIT_ASSERT_EQUAL(OUString("92674-107673"), 
pDoc->GetString(ScAddress(0, 7, 1)));
 
     // Second table
-    CPPUNIT_ASSERT_EQUAL(OUString("f"), pDoc->GetString(ScAddress(5, 3, 1)));
-    CPPUNIT_ASSERT_EQUAL(OUString("32674-47673"), pDoc->GetString(ScAddress(5, 
4, 1)));
-    CPPUNIT_ASSERT_EQUAL(OUString("47674-62673"), pDoc->GetString(ScAddress(5, 
5, 1)));
-    CPPUNIT_ASSERT_EQUAL(OUString("62674-77673"), pDoc->GetString(ScAddress(5, 
6, 1)));
-    CPPUNIT_ASSERT_EQUAL(OUString("77674-92673"), pDoc->GetString(ScAddress(5, 
7, 1)));
-    CPPUNIT_ASSERT_EQUAL(OUString("92674-107673"), 
pDoc->GetString(ScAddress(5, 8, 1)));
+    CPPUNIT_ASSERT_EQUAL(OUString("f"), pDoc->GetString(ScAddress(5, 2, 1)));
+    CPPUNIT_ASSERT_EQUAL(OUString("32674-47673"), pDoc->GetString(ScAddress(5, 
3, 1)));
+    CPPUNIT_ASSERT_EQUAL(OUString("47674-62673"), pDoc->GetString(ScAddress(5, 
4, 1)));
+    CPPUNIT_ASSERT_EQUAL(OUString("62674-77673"), pDoc->GetString(ScAddress(5, 
5, 1)));
+    CPPUNIT_ASSERT_EQUAL(OUString("77674-92673"), pDoc->GetString(ScAddress(5, 
6, 1)));
+    CPPUNIT_ASSERT_EQUAL(OUString("92674-107673"), 
pDoc->GetString(ScAddress(5, 7, 1)));
 
     // There should be exactly 2 pivot tables and 1 cache.
     ScDPCollection* pDPs = pDoc->GetDPCollection();
@@ -2710,6 +2710,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 37a7bf73d35a..5d32c24b2dff 100644
--- a/sc/source/core/data/dpobject.cxx
+++ b/sc/source/core/data/dpobject.cxx
@@ -307,27 +307,29 @@ bool ScDPServiceDesc::operator== ( const ScDPServiceDesc& 
rOther ) const
         aParPass == rOther.aParPass;
 }
 
-ScDPObject::ScDPObject( ScDocument* pD ) :
-    pDoc( pD ),
-    nHeaderRows( 0 ),
-    mbHeaderLayout(false),
-    bAllowMove(false),
-    bSettingsChanged(false),
-    mbEnableGetPivotData(true)
-{
-}
-
-ScDPObject::ScDPObject(const ScDPObject& r) :
-    pDoc( r.pDoc ),
-    aTableName( r.aTableName ),
-    aTableTag( r.aTableTag ),
-    aOutRange( r.aOutRange ),
-    maInteropGrabBag(r.maInteropGrabBag),
-    nHeaderRows( r.nHeaderRows ),
-    mbHeaderLayout( r.mbHeaderLayout ),
-    bAllowMove(false),
-    bSettingsChanged(false),
-    mbEnableGetPivotData(r.mbEnableGetPivotData)
+ScDPObject::ScDPObject(ScDocument* pD)
+    : pDoc(pD)
+    , nHeaderRows(0)
+    , mbHeaderLayout(false)
+    , bAllowMove(false)
+    , bSettingsChanged(false)
+    , mbEnableGetPivotData(true)
+    , mbHideHeader(false)
+{
+}
+
+ScDPObject::ScDPObject(const ScDPObject& r)
+    : pDoc(r.pDoc)
+    , aTableName(r.aTableName)
+    , aTableTag(r.aTableTag)
+    , aOutRange(r.aOutRange)
+    , maInteropGrabBag(r.maInteropGrabBag)
+    , nHeaderRows(r.nHeaderRows)
+    , mbHeaderLayout(r.mbHeaderLayout)
+    , bAllowMove(false)
+    , bSettingsChanged(false)
+    , mbEnableGetPivotData(r.mbEnableGetPivotData)
+    , mbHideHeader(r.mbHideHeader)
 {
     if (r.pSaveData)
         pSaveData.reset( new ScDPSaveData(*r.pSaveData) );
@@ -361,6 +363,7 @@ ScDPObject& ScDPObject::operator= (const ScDPObject& r)
         bAllowMove = false;
         bSettingsChanged = false;
         mbEnableGetPivotData = r.mbEnableGetPivotData;
+        mbHideHeader = r.mbHideHeader;
 
         if (r.pSaveData)
             pSaveData.reset( new ScDPSaveData(*r.pSaveData) );
@@ -399,6 +402,8 @@ void ScDPObject::SetHeaderLayout (bool bUseGrid)
     mbHeaderLayout = bUseGrid;
 }
 
+void ScDPObject::SetHideHeader(bool bHideHeader) { mbHideHeader = bHideHeader; 
}
+
 void ScDPObject::SetOutRange(const ScRange& rRange)
 {
     aOutRange = rRange;
@@ -526,7 +531,8 @@ void ScDPObject::CreateOutput()
         return;
 
     bool bFilterButton = IsSheetData() && pSaveData && 
pSaveData->GetFilterButton();
-    pOutput.reset( new ScDPOutput( pDoc, xSource, aOutRange.aStart, 
bFilterButton, pSaveData ? pSaveData->GetExpandCollapse() : false ) );
+    pOutput.reset(new ScDPOutput(pDoc, xSource, aOutRange.aStart, 
bFilterButton,
+                                 pSaveData ? pSaveData->GetExpandCollapse() : 
false, mbHideHeader));
     pOutput->SetHeaderLayout ( mbHeaderLayout );
 
     sal_Int32 nOldRows = nHeaderRows;
diff --git a/sc/source/core/data/dpoutput.cxx b/sc/source/core/data/dpoutput.cxx
index c74f43d10bd7..4cd4a414170a 100644
--- a/sc/source/core/data/dpoutput.cxx
+++ b/sc/source/core/data/dpoutput.cxx
@@ -506,25 +506,26 @@ uno::Sequence<sheet::MemberResult> 
getVisiblePageMembersAsResults( const uno::Re
 
 }
 
-ScDPOutput::ScDPOutput( ScDocument* pD, 
uno::Reference<sheet::XDimensionsSupplier> xSrc,
-                        const ScAddress& rPos, bool bFilter, bool 
bExpandCollapse ) :
-    pDoc( pD ),
-    xSource(std::move( xSrc )),
-    aStartPos( rPos ),
-    nColFmtCount( 0 ),
-    nRowFmtCount( 0 ),
-    nSingleNumFmt( 0 ),
-    nRowDims( 0 ),
-    nColCount(0),
-    nRowCount(0),
-    nHeaderSize(0),
-    bDoFilter(bFilter),
-    bResultsError(false),
-    bSizesValid(false),
-    bSizeOverflow(false),
-    mbHeaderLayout(false),
-    mbHasCompactRowField(false),
-    mbExpandCollapse(bExpandCollapse)
+ScDPOutput::ScDPOutput(ScDocument* pD, 
uno::Reference<sheet::XDimensionsSupplier> xSrc,
+                       const ScAddress& rPos, bool bFilter, bool 
bExpandCollapse, bool bHideHeader)
+    : pDoc(pD)
+    , xSource(std::move(xSrc))
+    , aStartPos(rPos)
+    , nColFmtCount(0)
+    , nRowFmtCount(0)
+    , nSingleNumFmt(0)
+    , nRowDims(0)
+    , nColCount(0)
+    , nRowCount(0)
+    , nHeaderSize(0)
+    , bDoFilter(bFilter)
+    , bResultsError(false)
+    , bSizesValid(false)
+    , bSizeOverflow(false)
+    , mbHeaderLayout(false)
+    , mbHasCompactRowField(false)
+    , mbExpandCollapse(bExpandCollapse)
+    , mbHideHeader(bHideHeader)
 {
     nTabStartCol = nMemberStartCol = nDataStartCol = nTabEndCol = 0;
     nTabStartRow = nMemberStartRow = nDataStartRow = nTabEndRow = 0;
@@ -906,7 +907,9 @@ void ScDPOutput::CalcSizes()
     nColCount = nRowCount ? ( pRowAry[0].getLength() ) : 0;
 
     nHeaderSize = 1;
-    if (GetHeaderLayout() && pColFields.empty())
+    if (mbHideHeader)
+        nHeaderSize = 0;
+    else if (GetHeaderLayout() && pColFields.empty())
         // Insert an extra header row only when there is no column field.
         nHeaderSize = 2;
 
@@ -1063,10 +1066,13 @@ void ScDPOutput::Output()
     for (size_t nField=0; nField<nNumColFields; nField++)
     {
         SCCOL nHdrCol = nDataStartCol + static_cast<SCCOL>(nField);            
  //TODO: check for overflow
-        if (!mbHasCompactRowField || nNumColFields == 1)
-            FieldCell(nHdrCol, nTabStartRow, nTab, pColFields[nField], true);
-        else if (!nField)
-            MultiFieldCell(nHdrCol, nTabStartRow, nTab, false /* bRowField */);
+        if (nMemberStartRow > nTabStartRow)
+        {
+            if (!mbHasCompactRowField || nNumColFields == 1)
+                FieldCell(nHdrCol, nTabStartRow, nTab, pColFields[nField], 
true);
+            else if (!nField)
+                MultiFieldCell(nHdrCol, nTabStartRow, nTab, false /* bRowField 
*/);
+        }
 
         SCROW nRowPos = nMemberStartRow + static_cast<SCROW>(nField);          
      //TODO: check for overflow
         const uno::Sequence<sheet::MemberResult> rSequence = 
pColFields[nField].maResult;
@@ -1106,7 +1112,7 @@ void ScDPOutput::Output()
             // Apply the same number format as in data source.
             pDoc->ApplyAttr(nColPos, nRowPos, nTab, 
SfxUInt32Item(ATTR_VALUE_FORMAT, pColFields[nField].mnSrcNumFmt));
         }
-        if ( nField== 0 && pColFields.size() == 1 )
+        if (nField == 0 && pColFields.size() == 1 && nMemberStartRow > 
nTabStartRow)
             outputimp.OutputBlockFrame( nDataStartCol,nTabStartRow, 
nTabEndCol,nRowPos-1 );
     }
 
diff --git a/sc/source/filter/excel/xepivotxml.cxx 
b/sc/source/filter/excel/xepivotxml.cxx
index fc8b118eae41..7f08b3bb6e7f 100644
--- a/sc/source/filter/excel/xepivotxml.cxx
+++ b/sc/source/filter/excel/xepivotxml.cxx
@@ -856,8 +856,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 f434780d2756..0d8025cbf8f5 100644
--- a/sc/source/filter/oox/pivottablebuffer.cxx
+++ b/sc/source/filter/oox/pivottablebuffer.cxx
@@ -1278,6 +1278,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);
 

Reply via email to