From 17569561bfa348dd11c9111d922f04838f689028 Mon Sep 17 00:00:00 2001 From: Dmitry S Date: Mon, 13 Feb 2023 22:52:48 -0500 Subject: [PATCH] (core) Fix issue that ints would be imported with a trailing ".0" from Google Sheets. Summary: Whole numbers, when imported from Excel into a Text column show up without decimals (e.g. "300"), but when imported from Google Sheets show up with decimals (e.g. "300.0"). The decimals are hard for end-users to remove. Fix by treating whole numbers consistently as ints. Test Plan: Added a fixture reproducing the issue, and a test case. Reviewers: georgegevoian Reviewed By: georgegevoian Differential Revision: https://phab.getgrist.com/D3800 --- .../imports/fixtures/test_excel_numeric_gs.xlsx | Bin 0 -> 4852 bytes sandbox/grist/imports/import_xls_test.py | 8 ++++++++ sandbox/grist/parse_data.py | 6 ++++++ 3 files changed, 14 insertions(+) create mode 100644 sandbox/grist/imports/fixtures/test_excel_numeric_gs.xlsx diff --git a/sandbox/grist/imports/fixtures/test_excel_numeric_gs.xlsx b/sandbox/grist/imports/fixtures/test_excel_numeric_gs.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..09c03225f59b2ae729abde2525d9922c939e2adc GIT binary patch literal 4852 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 T64GOIO8hGYPlXzE$9Mk+rtI7x literal 0 HcmV?d00001 diff --git a/sandbox/grist/imports/import_xls_test.py b/sandbox/grist/imports/import_xls_test.py index b176f0ad..aa0e9027 100644 --- a/sandbox/grist/imports/import_xls_test.py +++ b/sandbox/grist/imports/import_xls_test.py @@ -97,6 +97,14 @@ class TestImportXLS(unittest.TestCase): [-10.25, -8.00, -5.75, -3.50, "n/a", ' 1. ', " ??? ", 5.50, None, "-", 12.25, 0.00, None, 0.00, "--", 23.50, "NA", 28.00, 30.25, 32.50]) + def test_excel_numeric_gs(self): + # openpyxl sometimes sees floats for int values when those values come from Google Sheets (if + # saved via Excel, they'll look like ints). Check that they don't get imported with ".0" suffix. + parsed_file = import_xls.parse_file(*_get_fixture('test_excel_numeric_gs.xlsx')) + sheet = parsed_file[1][0] + self._check_col(sheet, 0, "TagId", "Numeric", [10, 20, 30, 40.5]) + self._check_col(sheet, 1, "TagName", "Any", ["foo", "300", "bar", "300.1"]) + def test_excel_single_merged_cell(self): # An older version had a bug where a single cell marked as 'merged' would cause an exception. parsed_file = import_xls.parse_file(*_get_fixture('test_single_merged_cell.xlsx')) diff --git a/sandbox/grist/parse_data.py b/sandbox/grist/parse_data.py index f0168623..133d091a 100644 --- a/sandbox/grist/parse_data.py +++ b/sandbox/grist/parse_data.py @@ -195,6 +195,12 @@ class ColumnConverter(object): # For some reason, we get 'str' type rather than 'unicode' for empty strings. # Correct this, since all text should be unicode. value = u"" if value == "" else value + + # Integer values sometimes show up as ints (from Excel), sometimes as floats (from Google). + # Make them consistently ints; this avoid addition of ".0" suffix when converting to text. + if type(value) == float and value.is_integer(): + value = int(value) + try: conv = self._converter.convert(value) self._converted_values.append(conv)