Kaydet (Commit) 97af5809 authored tarafından Dennis Francis's avatar Dennis Francis Kaydeden (comit) Andras Timar

tdf#123421 : xlsx export : Don't write data field entry...

under colFields tag if there is only one data-field.

<colFields count=[*]>
    <field x="-2"/>  <--- -2 indicates data field.
</colFields>

Excel 2013/2016 seems to crash at the presence of '<field x="-2"/>'
in colFields when there is only one data-field.

Additionally, call GetOutputRangeByType(sheet::DataPilotOutputRangeType::TABLE)
on all ScDPObject's in non-const mode, so that the internal
pOuput member of ScDPObject is populated. Otherwise the
const GetOutputRangeByType(sheet::DataPilotOutputRangeType::TABLE)
call always return an invalid range.

This also adds 2 unit tests :-
1. To check the presence of <field x="-2"/> in colFields tag
   if there are more than one data-fields.
2. To ensure the absence of <field x="-2"/> in colFields tag
   if there is only one data-field.

Change-Id: I8f470bd1ab883f73586f04a3fcc30e3fbf948c4a
Reviewed-on: https://gerrit.libreoffice.org/70316
Tested-by: Jenkins
Reviewed-by: 's avatarAndras Timar <andras.timar@collabora.com>
üst ea3a1b07
...@@ -315,7 +315,7 @@ public: ...@@ -315,7 +315,7 @@ public:
ScDPSaveDimension* GetInnermostDimension(css::sheet::DataPilotFieldOrientation nOrientation); ScDPSaveDimension* GetInnermostDimension(css::sheet::DataPilotFieldOrientation nOrientation);
ScDPSaveDimension* GetFirstDimension(css::sheet::DataPilotFieldOrientation eOrientation); ScDPSaveDimension* GetFirstDimension(css::sheet::DataPilotFieldOrientation eOrientation);
long GetDataDimensionCount() const; SC_DLLPUBLIC long GetDataDimensionCount() const;
void SetPosition( ScDPSaveDimension* pDim, long nNew ); void SetPosition( ScDPSaveDimension* pDim, long nNew );
SC_DLLPUBLIC void SetColumnGrand( bool bSet ); SC_DLLPUBLIC void SetColumnGrand( bool bSet );
......
...@@ -58,6 +58,8 @@ public: ...@@ -58,6 +58,8 @@ public:
// Export // Export
void testPivotTableExportXLSX(); void testPivotTableExportXLSX();
void testPivotTableExportXLSXSingleDataField();
void testPivotTableExportXLSXMultipleDataFields();
void testPivotCacheExportXLSX(); void testPivotCacheExportXLSX();
void testPivotTableXLSX(); void testPivotTableXLSX();
void testPivotTableTwoDataFieldsXLSX(); void testPivotTableTwoDataFieldsXLSX();
...@@ -98,6 +100,8 @@ public: ...@@ -98,6 +100,8 @@ public:
CPPUNIT_TEST(testTdf112501); CPPUNIT_TEST(testTdf112501);
CPPUNIT_TEST(testPivotTableExportXLSX); CPPUNIT_TEST(testPivotTableExportXLSX);
CPPUNIT_TEST(testPivotTableExportXLSXSingleDataField);
CPPUNIT_TEST(testPivotTableExportXLSXMultipleDataFields);
CPPUNIT_TEST(testPivotCacheExportXLSX); CPPUNIT_TEST(testPivotCacheExportXLSX);
CPPUNIT_TEST(testPivotTableXLSX); CPPUNIT_TEST(testPivotTableXLSX);
CPPUNIT_TEST(testPivotTableTwoDataFieldsXLSX); CPPUNIT_TEST(testPivotTableTwoDataFieldsXLSX);
...@@ -758,6 +762,58 @@ void ScPivotTableFiltersTest::testPivotTableExportXLSX() ...@@ -758,6 +762,58 @@ void ScPivotTableFiltersTest::testPivotTableExportXLSX()
xShell->DoClose(); xShell->DoClose();
} }
void ScPivotTableFiltersTest::testPivotTableExportXLSXSingleDataField()
{
ScDocShellRef xShell = loadDoc("tdf123421_1datafield.", FORMAT_ODS);
CPPUNIT_ASSERT(xShell.is());
std::shared_ptr<utl::TempFile> pXPathFile
= ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
xmlDocPtr pTable
= XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/pivotTables/pivotTable1.xml");
CPPUNIT_ASSERT(pTable);
assertXPath(pTable, "/x:pivotTableDefinition/x:location", "ref", "A3:B6");
assertXPath(pTable, "/x:pivotTableDefinition/x:location", "firstHeaderRow", "1");
assertXPath(pTable, "/x:pivotTableDefinition/x:location", "firstDataRow", "1");
assertXPath(pTable, "/x:pivotTableDefinition/x:location", "firstDataCol", "1");
assertXPath(pTable, "/x:pivotTableDefinition/x:dataFields", "count", "1");
// There should not be any colFields tag, before the fix there used to be a singleton with
// <field x="-2"/> as child node.
assertXPath(pTable, "/x:pivotTableDefinition/x:colFields", 0);
xShell->DoClose();
}
void ScPivotTableFiltersTest::testPivotTableExportXLSXMultipleDataFields()
{
ScDocShellRef xShell = loadDoc("tdf123421_2datafields.", FORMAT_ODS);
CPPUNIT_ASSERT(xShell.is());
std::shared_ptr<utl::TempFile> pXPathFile
= ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
xmlDocPtr pTable
= XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/pivotTables/pivotTable1.xml");
CPPUNIT_ASSERT(pTable);
assertXPath(pTable, "/x:pivotTableDefinition/x:location", "ref", "A1:C6");
assertXPath(pTable, "/x:pivotTableDefinition/x:location", "firstHeaderRow", "1");
assertXPath(pTable, "/x:pivotTableDefinition/x:location", "firstDataRow", "2");
assertXPath(pTable, "/x:pivotTableDefinition/x:location", "firstDataCol", "1");
assertXPath(pTable, "/x:pivotTableDefinition/x:dataFields", "count", "2");
// There should be a single colFields tag with sole child node
// <field x="-2"/>.
assertXPath(pTable, "/x:pivotTableDefinition/x:colFields", 1);
assertXPath(pTable, "/x:pivotTableDefinition/x:colFields", "count", "1");
assertXPath(pTable, "/x:pivotTableDefinition/x:colFields/x:field", 1);
assertXPath(pTable, "/x:pivotTableDefinition/x:colFields/x:field", "x", "-2");
xShell->DoClose();
}
void ScPivotTableFiltersTest::testPivotCacheExportXLSX() void ScPivotTableFiltersTest::testPivotCacheExportXLSX()
{ {
// tdf#89139 FILESAVE xlsx pivot table corrupted after save with LO and re-open with MS Office // tdf#89139 FILESAVE xlsx pivot table corrupted after save with LO and re-open with MS Office
......
...@@ -426,6 +426,7 @@ void XclExpXmlPivotTableManager::Initialize() ...@@ -426,6 +426,7 @@ void XclExpXmlPivotTableManager::Initialize()
{ {
ScDPObject& rDPObj = (*pDPColl)[i]; ScDPObject& rDPObj = (*pDPColl)[i];
rDPObj.SyncAllDimensionMembers(); rDPObj.SyncAllDimensionMembers();
(void)rDPObj.GetOutputRangeByType(sheet::DataPilotOutputRangeType::TABLE);
} }
// Go through the caches first. // Go through the caches first.
...@@ -606,6 +607,7 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP ...@@ -606,6 +607,7 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP
std::vector<long> aPageFields; std::vector<long> aPageFields;
std::vector<DataField> aDataFields; std::vector<DataField> aDataFields;
long nDataDimCount = rSaveData.GetDataDimensionCount();
// Use dimensions in the save data to get their correct ordering. // Use dimensions in the save data to get their correct ordering.
// Dimension order here is significant as they specify the order of // Dimension order here is significant as they specify the order of
// appearance in each axis. // appearance in each axis.
...@@ -637,6 +639,8 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP ...@@ -637,6 +639,8 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP
switch (eOrient) switch (eOrient)
{ {
case sheet::DataPilotFieldOrientation_COLUMN: case sheet::DataPilotFieldOrientation_COLUMN:
if (nPos == -2 && nDataDimCount <= 1)
break;
aColFields.push_back(nPos); aColFields.push_back(nPos);
break; break;
case sheet::DataPilotFieldOrientation_ROW: case sheet::DataPilotFieldOrientation_ROW:
...@@ -684,15 +688,16 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP ...@@ -684,15 +688,16 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP
sal_Int32 nFirstDataRow = 2; sal_Int32 nFirstDataRow = 2;
sal_Int32 nFirstDataCol = 1; sal_Int32 nFirstDataCol = 1;
ScRange aResRange = rDPObj.GetOutputRangeByType(sheet::DataPilotOutputRangeType::RESULT); ScRange aResRange = rDPObj.GetOutputRangeByType(sheet::DataPilotOutputRangeType::RESULT);
if (!aOutRange.IsValid())
aOutRange = rDPObj.GetOutRange();
if (aOutRange.IsValid() && aResRange.IsValid()) if (aOutRange.IsValid() && aResRange.IsValid())
{ {
nFirstDataRow = aResRange.aStart.Row() - aOutRange.aStart.Row(); nFirstDataRow = aResRange.aStart.Row() - aOutRange.aStart.Row();
nFirstDataCol = aResRange.aStart.Col() - aOutRange.aStart.Col(); nFirstDataCol = aResRange.aStart.Col() - aOutRange.aStart.Col();
} }
if (!aOutRange.IsValid())
aOutRange = rDPObj.GetOutRange();
pPivotStrm->write("<")->writeId(XML_location); pPivotStrm->write("<")->writeId(XML_location);
rStrm.WriteAttributes(XML_ref, rStrm.WriteAttributes(XML_ref,
XclXmlUtils::ToOString(aOutRange), XclXmlUtils::ToOString(aOutRange),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment