summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartosz Kosiorek <gang65@poczta.onet.pl>2016-06-24 02:10:25 +0200
committerEike Rathke <erack@redhat.com>2016-12-05 17:40:59 +0000
commit21d340948d564c819e24edd96051c42a9ca2c78e (patch)
tree3709310053cad4339eaf857647a7e10dd0e3f17d
parent91328bab6f47dc9659a2124a73d88ff3d7ba4279 (diff)
tdf#100347 Fix Outline export into XLSX format
In previous XLSX export implementation the outline for column was not saved. Also rows without cell content was not saved if it was collapsed or outline level was set. This commit resolve all such issues Change-Id: I401f23e97f4803209fcd31c7d93baca3bd2a2385 Reviewed-on: https://gerrit.libreoffice.org/26625 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Markus Mohrhard <markus.mohrhard@googlemail.com> (cherry picked from commit cc503abb860c33a54a188640a5962dbdf7052284) Reviewed-on: https://gerrit.libreoffice.org/31642 Reviewed-by: Eike Rathke <erack@redhat.com> Tested-by: Eike Rathke <erack@redhat.com>
-rw-r--r--sc/qa/unit/data/ods/outline.odsbin7959 -> 7764 bytes
-rw-r--r--sc/qa/unit/subsequent_export-test.cxx81
-rw-r--r--sc/source/filter/excel/xetable.cxx18
-rw-r--r--sc/source/filter/inc/xetable.hxx3
4 files changed, 95 insertions, 7 deletions
diff --git a/sc/qa/unit/data/ods/outline.ods b/sc/qa/unit/data/ods/outline.ods
index bca7d14711d4..320e318fbba7 100644
--- a/sc/qa/unit/data/ods/outline.ods
+++ b/sc/qa/unit/data/ods/outline.ods
Binary files differ
diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx
index f9059eeb06e8..cf94ac53dbd8 100644
--- a/sc/qa/unit/subsequent_export-test.cxx
+++ b/sc/qa/unit/subsequent_export-test.cxx
@@ -110,6 +110,7 @@ public:
void testCellNoteExportXLS();
void testFormatExportODS();
+ void testOutlineExportXLSX();
void testHiddenEmptyRowsXLSX();
void testLandscapeOrientationXLSX();
@@ -194,6 +195,8 @@ public:
CPPUNIT_TEST(testCellNoteExportODS);
CPPUNIT_TEST(testCellNoteExportXLS);
CPPUNIT_TEST(testFormatExportODS);
+
+ CPPUNIT_TEST(testOutlineExportXLSX);
CPPUNIT_TEST(testHiddenEmptyRowsXLSX);
CPPUNIT_TEST(testLandscapeOrientationXLSX);
CPPUNIT_TEST(testInlineArrayXLS);
@@ -474,6 +477,84 @@ void ScExportTest::testFormatExportODS()
xDocSh->DoClose();
}
+void ScExportTest::testOutlineExportXLSX()
+{
+ //tdf#100347 FILESAVE FILEOPEN after exporting to xlsx format grouping are lost
+ ScDocShellRef xShell = loadDoc("outline.", FORMAT_ODS);
+ CPPUNIT_ASSERT(xShell.Is());
+
+ std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
+ xmlDocPtr pSheet = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
+ CPPUNIT_ASSERT(pSheet);
+
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "hidden", "false");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "outlineLevel", "1");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "collapsed", "false");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "hidden", "false");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "outlineLevel", "2");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "collapsed", "false");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[3]", "hidden", "true");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[3]", "outlineLevel", "3");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[3]", "collapsed", "false");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[4]", "hidden", "true");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[4]", "outlineLevel", "4");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[4]", "collapsed", "false");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[5]", "hidden", "true");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[5]", "outlineLevel", "3");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[5]", "collapsed", "false");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[6]", "hidden", "false");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[6]", "outlineLevel", "2");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[6]", "collapsed", "true");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[7]", "hidden", "false");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[7]", "outlineLevel", "2");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[7]", "collapsed", "false");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[8]", "hidden", "false");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[8]", "outlineLevel", "1");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[8]", "collapsed", "false");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[9]", "hidden", "false");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[9]", "outlineLevel", "0");
+ assertXPath(pSheet, "/x:worksheet/x:cols/x:col[9]", "collapsed", "false");
+
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[1]", "hidden", "false");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[1]", "outlineLevel", "0");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[1]", "collapsed", "false");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[2]", "hidden", "false");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[2]", "outlineLevel", "1");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[2]", "collapsed", "false");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[3]", "hidden", "false");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[3]", "outlineLevel", "2");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[3]", "collapsed", "false");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[4]", "hidden", "false");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[4]", "outlineLevel", "2");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[4]", "collapsed", "false");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[5]", "hidden", "false");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[5]", "outlineLevel", "3");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[5]", "collapsed", "false");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[6]", "hidden", "false");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[6]", "outlineLevel", "3");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[6]", "collapsed", "false");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[7]", "hidden", "true");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[7]", "outlineLevel", "4");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[7]", "collapsed", "false");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[8]", "hidden", "true");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[8]", "outlineLevel", "4");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[8]", "collapsed", "false");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[9]", "hidden", "true");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[9]", "outlineLevel", "4");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[9]", "collapsed", "false");
+ //next rows are the same as the previous one
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[21]", "hidden", "true");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[21]", "outlineLevel", "4");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[21]", "collapsed", "false");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[22]", "hidden", "false");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[22]", "outlineLevel", "3");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[22]", "collapsed", "true");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[23]", "hidden", "false");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[23]", "outlineLevel", "3");
+ assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[23]", "collapsed", "false");
+}
+
+
void ScExportTest::testHiddenEmptyRowsXLSX()
{
//tdf#98106 FILESAVE: Hidden and empty rows became visible when export to .XLSX
diff --git a/sc/source/filter/excel/xetable.cxx b/sc/source/filter/excel/xetable.cxx
index b668eb8f9df4..34cb7cb98cc2 100644
--- a/sc/source/filter/excel/xetable.cxx
+++ b/sc/source/filter/excel/xetable.cxx
@@ -1582,6 +1582,7 @@ XclExpColinfo::XclExpColinfo( const XclExpRoot& rRoot,
mnWidth( 0 ),
mnScWidth( 0 ),
mnFlags( 0 ),
+ mnOutlineLevel( 0 ),
mnFirstXclCol( static_cast< sal_uInt16 >( nScCol ) ),
mnLastXclCol( static_cast< sal_uInt16 >( nScCol ) )
{
@@ -1603,6 +1604,7 @@ XclExpColinfo::XclExpColinfo( const XclExpRoot& rRoot,
rOutlineBfr.Update( nScCol );
::set_flag( mnFlags, EXC_COLINFO_COLLAPSED, rOutlineBfr.IsCollapsed() );
::insert_value( mnFlags, rOutlineBfr.GetLevel(), 8, 3 );
+ mnOutlineLevel = rOutlineBfr.GetLevel();
}
void XclExpColinfo::ConvertXFIndexes()
@@ -1655,9 +1657,9 @@ void XclExpColinfo::SaveXml( XclExpXmlStream& rStrm )
XML_collapsed, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_COLINFO_COLLAPSED ) ),
// OOXTODO: XML_customWidth,
XML_hidden, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_COLINFO_HIDDEN ) ),
- XML_max, OString::number( (nLastXclCol+1) ).getStr(),
- XML_min, OString::number( (mnFirstXclCol+1) ).getStr(),
- // OOXTODO: XML_outlineLevel,
+ XML_outlineLevel, OString::number( mnOutlineLevel ).getStr(),
+ XML_max, OString::number( (nLastXclCol + 1) ).getStr(),
+ XML_min, OString::number( (mnFirstXclCol + 1) ).getStr(),
// OOXTODO: XML_phonetic,
XML_style, lcl_GetStyleId( rStrm, maXFId.mnXFIndex ).getStr(),
XML_width, OString::number( (double) (mnScWidth / (double)sc::TwipsToHMM( GetCharWidth() )) ).getStr(),
@@ -1998,7 +2000,8 @@ sal_uInt16 XclExpRow::GetFirstFreeXclCol() const
bool XclExpRow::IsDefaultable() const
{
const sal_uInt16 nFlagsAlwaysMarkedAsDefault = EXC_ROW_DEFAULTFLAGS | EXC_ROW_UNSYNCED;
- return !::get_flag( mnFlags, static_cast< sal_uInt16 >( ~nFlagsAlwaysMarkedAsDefault ) ) && IsEmpty();
+ return !::get_flag( mnFlags, static_cast< sal_uInt16 >( ~nFlagsAlwaysMarkedAsDefault ) ) &&
+ IsEmpty();
}
void XclExpRow::DisableIfDefault( const XclExpDefaultRowData& rDefRowData )
@@ -2328,10 +2331,13 @@ XclExpRow& XclExpRowBuffer::GetOrCreateRow( sal_uInt32 nXclRow, bool bRowAlwaysE
itr = maRowMap.find(nFrom);
if ( itr == maRowMap.end() )
{
- // only create RowMap entries for rows that differ from previous,
- // the row is hidden (tdf#98106) or if it is the desired row
+ // only create RowMap entries if it is first row in spreadsheet,
+ // if it is the desired row, for rows that height differ from previous,
+ // if row is collapsed, has outline level (tdf#100347), or row is hidden (tdf#98106).
if ( !nFrom || ( nFrom == nXclRow ) ||
( rDoc.GetRowHeight(nFrom, nScTab, false) != rDoc.GetRowHeight(nFrom - 1, nScTab, false) ) ||
+ ( maOutlineBfr.IsCollapsed() ) ||
+ ( maOutlineBfr.GetLevel() != 0 ) ||
( rDoc.RowHidden(nFrom, nScTab) ) )
{
RowRef p(new XclExpRow(GetRoot(), nFrom, maOutlineBfr, bRowAlwaysEmpty));
diff --git a/sc/source/filter/inc/xetable.hxx b/sc/source/filter/inc/xetable.hxx
index 7d8bc50a7af4..71c1ed99aff3 100644
--- a/sc/source/filter/inc/xetable.hxx
+++ b/sc/source/filter/inc/xetable.hxx
@@ -743,6 +743,7 @@ private:
sal_uInt16 mnWidth; /// Excel width of the column.
sal_uInt16 mnScWidth; /// Calc width of the column.
sal_uInt16 mnFlags; /// Additional column flags.
+ sal_uInt8 mnOutlineLevel; /// Outline Level of column (for OOXML)
sal_uInt16 mnFirstXclCol; /// Index to first column.
sal_uInt16 mnLastXclCol; /// Index to last column.
};
@@ -894,7 +895,7 @@ private:
sal_uInt16 mnHeight; /// Row height in twips.
sal_uInt16 mnFlags; /// Flags for the ROW record.
sal_uInt16 mnXFIndex; /// Default row formatting.
- sal_uInt16 mnOutlineLevel; /// Outline Level (for OOXML)
+ sal_uInt8 mnOutlineLevel; /// Outline Level of row (for OOXML)
sal_uInt32 mnXclRowRpt;
sal_uInt32 mnCurrentRow;
bool mbAlwaysEmpty; /// true = Do not add blank cells in Finalize().