diff options
-rw-r--r-- | sc/qa/filter/html/html.cxx | 37 | ||||
-rw-r--r-- | sc/source/filter/html/htmlexp.cxx | 22 |
2 files changed, 59 insertions, 0 deletions
diff --git a/sc/qa/filter/html/html.cxx b/sc/qa/filter/html/html.cxx index fb9a436c72a0..916dd23981ec 100644 --- a/sc/qa/filter/html/html.cxx +++ b/sc/qa/filter/html/html.cxx @@ -239,6 +239,43 @@ CPPUNIT_TEST_FIXTURE(Test, testCopyBoolean) assertXPath(pHtmlDoc, "(//td)[1]"_ostr, "data-sheets-value"_ostr, "{ \"1\": 4, \"4\": 1}"); assertXPath(pHtmlDoc, "(//td)[2]"_ostr, "data-sheets-value"_ostr, "{ \"1\": 4, \"4\": 0}"); } + +CPPUNIT_TEST_FIXTURE(Test, testCopyFormattedNumber) +{ + // Given a document with formatted numbers in A1-A2: + createScDoc(); + ScDocument* pDoc = getScDoc(); + sal_Int32 nCheckPos; + SvNumFormatType nType; + sal_uInt32 nFormat; + OUString aNumberFormat("#,##0.00"); + SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); + pFormatter->PutEntry(aNumberFormat, nCheckPos, nType, nFormat); + ScAddress aCellPos1(/*nColP=*/0, /*nRowP=*/0, /*nTabP=*/0); + pDoc->SetNumberFormat(aCellPos1, nFormat); + pDoc->SetString(aCellPos1, "1000"); + ScAddress aCellPos2(/*nColP=*/0, /*nRowP=*/1, /*nTabP=*/0); + pDoc->SetNumberFormat(aCellPos2, nFormat); + pDoc->SetString(aCellPos2, "2000"); + + // When copying those values: + ScImportExport aExporter(*pDoc, ScRange(aCellPos1, aCellPos2)); + SvMemoryStream aStream; + CPPUNIT_ASSERT(aExporter.ExportStream(aStream, OUString(), SotClipboardFormatId::HTML)); + + // Then make sure the values are numbers: + aStream.Seek(0); + htmlDocUniquePtr pHtmlDoc = parseHtmlStream(&aStream); + // Without the accompanying fix in place, this test would have failed with: + // - XPath '(//td)[1]' no attribute 'data-sheets-value' exist + // i.e. only a formatted number string was written, without a float value. + assertXPath(pHtmlDoc, "(//td)[1]"_ostr, "data-sheets-value"_ostr, "{ \"1\": 3, \"3\": 1000}"); + assertXPath(pHtmlDoc, "(//td)[1]"_ostr, "data-sheets-numberformat"_ostr, + "{ \"1\": 2, \"2\": \"#,##0.00\", \"3\": 1}"); + assertXPath(pHtmlDoc, "(//td)[2]"_ostr, "data-sheets-value"_ostr, "{ \"1\": 3, \"3\": 2000}"); + assertXPath(pHtmlDoc, "(//td)[2]"_ostr, "data-sheets-numberformat"_ostr, + "{ \"1\": 2, \"2\": \"#,##0.00\", \"3\": 1}"); +} } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sc/source/filter/html/htmlexp.cxx b/sc/source/filter/html/htmlexp.cxx index 1e5dcf24b6c5..c2554b7612f1 100644 --- a/sc/source/filter/html/htmlexp.cxx +++ b/sc/source/filter/html/htmlexp.cxx @@ -1146,6 +1146,7 @@ void ScHTMLExport::WriteCell( sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, SC nFormat, *pFormatter, &aNonConvertibleChars)); std::optional<tools::JsonWriter> oJson; + const SvNumberformat* pNumberFormat = nullptr; if (bValueData) { if (nFormat) @@ -1161,6 +1162,14 @@ void ScHTMLExport::WriteCell( sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, SC oJson->put("1", static_cast<sal_Int32>(4)); oJson->put("4", static_cast<sal_Int32>(fVal)); } + else + { + // 3 is number. + oJson.emplace(); + oJson->put("1", static_cast<sal_Int32>(3)); + oJson->put("3", static_cast<sal_Int32>(fVal)); + pNumberFormat = pFormatEntry; + } } } } @@ -1179,6 +1188,19 @@ void ScHTMLExport::WriteCell( sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, SC + HTMLOutFuncs::ConvertStringToHTML(aJsonString) + "\""); } + if (pNumberFormat) + { + // 2 is a number format. + oJson.emplace(); + oJson->put("1", static_cast<sal_Int32>(2)); + oJson->put("2", pNumberFormat->GetFormatstring()); + // The number format is for a number. + oJson->put("3", static_cast<sal_Int32>(1)); + OUString aJsonString = OUString::fromUtf8(oJson->finishAndGetAsOString()); + aStrTD.append(" " OOO_STRING_SVTOOLS_HTML_O_DSnum "=\"" + + HTMLOutFuncs::ConvertStringToHTML(aJsonString) + "\""); + } + TAG_ON(aStrTD.makeStringAndClear()); //write the note for this as the first thing in the tag |