diff options
-rw-r--r-- | sc/qa/unit/data/ods/different-column-width.ods | bin | 0 -> 7295 bytes | |||
-rw-r--r-- | sc/qa/unit/data/xlsx/different-column-width-excel2010.xlsx | bin | 0 -> 5818 bytes | |||
-rw-r--r-- | sc/qa/unit/subsequent_export-test.cxx | 112 | ||||
-rw-r--r-- | sc/source/filter/oox/worksheethelper.cxx | 22 |
4 files changed, 111 insertions, 23 deletions
diff --git a/sc/qa/unit/data/ods/different-column-width.ods b/sc/qa/unit/data/ods/different-column-width.ods Binary files differnew file mode 100644 index 000000000000..3f2e34ce88dc --- /dev/null +++ b/sc/qa/unit/data/ods/different-column-width.ods diff --git a/sc/qa/unit/data/xlsx/different-column-width-excel2010.xlsx b/sc/qa/unit/data/xlsx/different-column-width-excel2010.xlsx Binary files differnew file mode 100644 index 000000000000..93f133f8db49 --- /dev/null +++ b/sc/qa/unit/data/xlsx/different-column-width-excel2010.xlsx diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx index ab80b095db55..50bb2a62ea13 100644 --- a/sc/qa/unit/subsequent_export-test.cxx +++ b/sc/qa/unit/subsequent_export-test.cxx @@ -110,6 +110,8 @@ public: void testCustomColumnWidthExportXLSX(); void testXfDefaultValuesXLSX(); + void testColumnWidthResaveXLSX(); + void testColumnWidthExportFromODStoXLSX(); void testOutlineExportXLSX(); void testHiddenEmptyRowsXLSX(); void testEmptyRowsWithBackgroundColorXLSX(); @@ -209,6 +211,8 @@ public: CPPUNIT_TEST(testCustomColumnWidthExportXLSX); CPPUNIT_TEST(testXfDefaultValuesXLSX); + CPPUNIT_TEST(testColumnWidthResaveXLSX); + CPPUNIT_TEST(testColumnWidthExportFromODStoXLSX); CPPUNIT_TEST(testOutlineExportXLSX); CPPUNIT_TEST(testHiddenEmptyRowsXLSX); CPPUNIT_TEST(testEmptyRowsWithBackgroundColorXLSX); @@ -505,7 +509,7 @@ void ScExportTest::testCustomColumnWidthExportXLSX() xmlDocPtr pSheet = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml"); CPPUNIT_ASSERT(pSheet); - // First column, has everything default + // First column, has everything default (width in Calc: 1280) assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "hidden", "false"); assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "outlineLevel", "0"); assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "customWidth", "false"); @@ -513,7 +517,7 @@ void ScExportTest::testCustomColumnWidthExportXLSX() assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "min", "1"); assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "max", "1"); - // Second column, has custom width + // Second column, has custom width (width in Calc: 1225) assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "hidden", "false"); assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "outlineLevel", "0"); assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "customWidth", "true"); @@ -521,7 +525,7 @@ void ScExportTest::testCustomColumnWidthExportXLSX() assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "min", "2"); assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "max", "2"); - // Third column, has everything default + // Third column, has everything default (width in Calc: 1280) assertXPath(pSheet, "/x:worksheet/x:cols/x:col[3]", "hidden", "false"); assertXPath(pSheet, "/x:worksheet/x:cols/x:col[3]", "outlineLevel", "0"); assertXPath(pSheet, "/x:worksheet/x:cols/x:col[3]", "customWidth", "false"); @@ -611,6 +615,108 @@ void ScExportTest::testXfDefaultValuesXLSX() assertXPath(pSheet, "/x:styleSheet/x:cellXfs/x:xf", 14); } +void ScExportTest::testColumnWidthResaveXLSX() +{ + // tdf#91475 FILESAVE: Column width is not preserved in XLSX / after round trip. + // Test if after resave .xlsx file, columns width is identical with with previous one + ScDocShellRef xShell = loadDoc("different-column-width-excel2010.", FORMAT_XLSX); + 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); + + // In original Excel document the width is "24" + assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "width", "24"); + assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "customWidth", "true"); + + // In original Excel document the width is "12" + assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "width", "12"); + assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "customWidth", "true"); + + // In original Excel document the width is "6" + assertXPath(pSheet, "/x:worksheet/x:cols/x:col[3]", "width", "6"); + assertXPath(pSheet, "/x:worksheet/x:cols/x:col[3]", "customWidth", "true"); + + // In original Excel document the width is "1" + assertXPath(pSheet, "/x:worksheet/x:cols/x:col[4]", "width", "1"); + assertXPath(pSheet, "/x:worksheet/x:cols/x:col[4]", "customWidth", "true"); + + // In original Excel document the width is "250" + assertXPath(pSheet, "/x:worksheet/x:cols/x:col[5]", "width", "250"); + assertXPath(pSheet, "/x:worksheet/x:cols/x:col[5]", "customWidth", "true"); + + // The last column [6] is not existing in Excel sheet, and it is added only by LibreOffice. + // This column width is default and it is depended on operating system. + + assertXPath(pSheet, "/x:worksheet/x:cols/x:col", 6); +} + + +void ScExportTest::testColumnWidthExportFromODStoXLSX() +{ + // tdf#91475 FILESAVE: Column width is not preserved in XLSX / after round trip. + // Test if after export .ods to .xlsx format, displayed columns width + // is identical with with previous (.ods) one + + ScDocShellRef xShell = loadDoc("different-column-width.", FORMAT_ODS); + + CPPUNIT_ASSERT( xShell.Is() ); + + ScDocument& rOdsDoc = xShell->GetDocument(); + + // Col 1, Tab 0 (Column width 2.00 in) + sal_uInt16 nExpectedColumn0Width = rOdsDoc.GetColWidth(static_cast<SCCOL>(0), static_cast<SCTAB>(0), false); + CPPUNIT_ASSERT_EQUAL( static_cast< sal_uInt16 >( 2880 ), nExpectedColumn0Width ); + + // Col 2, Tab 0 (Column width 1.00 in) + sal_uInt16 nExpectedColumn1Width = rOdsDoc.GetColWidth(static_cast<SCCOL>(1), static_cast<SCTAB>(0), false); + CPPUNIT_ASSERT_EQUAL( static_cast< sal_uInt16 >( 1440 ), nExpectedColumn1Width ); + + // Col 3, Tab 0 (Column width 0.50 in) + sal_uInt16 nExpectedColumn2Width = rOdsDoc.GetColWidth(static_cast<SCCOL>(2), static_cast<SCTAB>(0), false); + CPPUNIT_ASSERT_EQUAL( static_cast< sal_uInt16 >( 720 ), nExpectedColumn2Width ); + + // Col 4, Tab 0 (Column width 0.25 in) + sal_uInt16 nExpectedColumn3Width = rOdsDoc.GetColWidth(static_cast<SCCOL>(3), static_cast<SCTAB>(0), false); + CPPUNIT_ASSERT_EQUAL( static_cast< sal_uInt16 >( 360 ), nExpectedColumn3Width ); + + // Col 5, Tab 0 (Column width 13.57 in) + sal_uInt16 nExpectedColumn4Width = rOdsDoc.GetColWidth(static_cast<SCCOL>(4), static_cast<SCTAB>(0), false); + CPPUNIT_ASSERT_EQUAL( static_cast< sal_uInt16 >( 19539 ), nExpectedColumn4Width ); + + // Export to .xlsx and compare column width with the .ods + // We expect that column width from .ods will be exactly the same as imported from .xlsx + + ScDocShellRef xXlsxDocSh = saveAndReload( xShell.get(), FORMAT_XLSX ); + CPPUNIT_ASSERT( xXlsxDocSh.Is() ); + + ScDocument& rDoc = xXlsxDocSh->GetDocument(); + + // Col 1, Tab 0 + sal_uInt16 nCalcWidth; + nCalcWidth = rDoc.GetColWidth(static_cast<SCCOL>(0), static_cast<SCTAB>(0), false); + CPPUNIT_ASSERT_EQUAL( nExpectedColumn0Width, nCalcWidth ); + + // Col 2, Tab 0 + nCalcWidth = rDoc.GetColWidth(static_cast<SCCOL>(1), static_cast<SCTAB>(0), false); + CPPUNIT_ASSERT_EQUAL( nExpectedColumn1Width, nCalcWidth ); + + // Col 3, Tab 0 + nCalcWidth = rDoc.GetColWidth(static_cast<SCCOL>(2), static_cast<SCTAB>(0), false); + CPPUNIT_ASSERT_EQUAL( nExpectedColumn2Width, nCalcWidth ); + + // Col 4, Tab 0 + nCalcWidth = rDoc.GetColWidth(static_cast<SCCOL>(3), static_cast<SCTAB>(0), false); + CPPUNIT_ASSERT_EQUAL( nExpectedColumn3Width, nCalcWidth ); + + // Col 5, Tab 0 + nCalcWidth = rDoc.GetColWidth(static_cast<SCCOL>(4), static_cast<SCTAB>(0), false); + CPPUNIT_ASSERT_EQUAL( nExpectedColumn4Width, nCalcWidth ); + + xXlsxDocSh->DoClose(); +} + void ScExportTest::testOutlineExportXLSX() { //tdf#100347 FILESAVE FILEOPEN after exporting to .xlsx format grouping are lost diff --git a/sc/source/filter/oox/worksheethelper.cxx b/sc/source/filter/oox/worksheethelper.cxx index 4fd1af0e7494..db9ae6e421cd 100644 --- a/sc/source/filter/oox/worksheethelper.cxx +++ b/sc/source/filter/oox/worksheethelper.cxx @@ -1173,30 +1173,12 @@ void WorksheetGlobals::convertColumns() convertOutlines( aColLevels, nMaxCol + 1, 0, false, false ); } -namespace { - -sal_Int32 getColumnWidth(UnitConverter& rConverter, double nWidth) -{ - double nCoeff = rConverter.getCoefficient(UNIT_DIGIT); - ScopedVclPtrInstance<VirtualDevice> aDev; - - long nPixel = aDev->LogicToPixel(Point(nCoeff, 0), MapMode(MapUnit::Map100thMM)).getX(); - - // the 1.047 has been experimentally chosen based on measurements with a screen ruler - // TODO: fix the display of cells so that it no longer requires this hack - // algorithm from OOXML spec part1: 18.3.1.13 - sal_Int32 nColWidthPixel= std::floor( ( ( 256 * nWidth + std::floor( 128.0 / nPixel ) ) / 256.0 ) * nPixel ) * 1.047; - - return aDev->PixelToLogic(Point(nColWidthPixel, 0), MapMode(MapUnit::Map100thMM)).getX(); -} - -} - void WorksheetGlobals::convertColumns( OutlineLevelVec& orColLevels, const ValueRange& rColRange, const ColumnModel& rModel ) { // column width: convert 'number of characters' to column width in 1/100 mm - sal_Int32 nWidth = getColumnWidth(getUnitConverter(), rModel.mfWidth); + sal_Int32 nWidth = getUnitConverter().scaleToMm100( rModel.mfWidth, UNIT_DIGIT ); + // macro sheets have double width if( meSheetType == SHEETTYPE_MACROSHEET ) nWidth *= 2; |