summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2024-03-01 14:14:33 +0100
committerCaolán McNamara <caolan.mcnamara@collabora.com>2024-03-05 11:19:24 +0100
commitc2c4b8aac06601e958ba8b6512c4f5e0efa6cdd7 (patch)
treef80537119cfce8a802d6c48f2dcfee13f6976578 /sc
parent2d6a0e2a354ffeba10f69634835a48d65e601846 (diff)
tdf#159483 sc HTML copy: handle data-sheets-value attribute for the num case
Type 1000 and 2000 into cells in Calc, format them as e.g. a HUF currency, the resulting formatted strings can be copied to google sheets, but the SUM() on them will be 0 (and not 3000). Our own import knows how to read metadata to get the original float value, but our exporter didn't emit these. Fix the problem by adding support for non-boolean float values + number formats in the HTML export. This is more or less export equivalent of commit 789964785a61daab5f8065f006dd7aaf843c7236 (tdf#159483 sc HTML import: handle data-sheets-value attribute for the num case, 2024-02-09). (cherry picked from commit 17581e684ca701bfd96ed2bf16aa14c3903b74d4) Change-Id: I5acb3724367ce38bd96056dbe4f846cd7bbc5fe2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164409 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Diffstat (limited to 'sc')
-rw-r--r--sc/qa/filter/html/html.cxx37
-rw-r--r--sc/source/filter/html/htmlexp.cxx22
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