diff --git a/HISTORY.md b/HISTORY.md index c02639d..de2ab9d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -13,6 +13,10 @@ - Fixed minimal openpyxl dependency version to 2.6.0 (#457). - Dates from xls files are now read as Python datetime objects (#373). +### Improvements + +- When importing an xlsx file, Tablib will now read cell values instead of formulas (#462). + ## 1.1.0 (2020-02-13) ### Deprecations diff --git a/docs/formats.rst b/docs/formats.rst index 9db94ce..12ea52d 100644 --- a/docs/formats.rst +++ b/docs/formats.rst @@ -206,6 +206,15 @@ Import/export data in Excel 07+ Spreadsheet representation. This format is optional, install Tablib with ``pip install tablib[xlsx]`` to make the format available. +.. note:: + + When reading an ``xlsx`` file containing formulas in its cells, Tablib will + read the cell values, not the cell formulas. + +.. versionchanged:: 2.0.0 + + Reads cell values instead of formulas. + .. admonition:: Binary Warning The ``xlsx`` file format is binary, so make sure to write in binary mode:: diff --git a/src/tablib/formats/_xlsx.py b/src/tablib/formats/_xlsx.py index 2e08a54..dffc192 100644 --- a/src/tablib/formats/_xlsx.py +++ b/src/tablib/formats/_xlsx.py @@ -63,7 +63,7 @@ class XLSXFormat: dset.wipe() - xls_book = load_workbook(in_stream, read_only=True) + xls_book = load_workbook(in_stream, read_only=True, data_only=True) sheet = xls_book.active dset.title = sheet.title @@ -81,7 +81,7 @@ class XLSXFormat: dbook.wipe() - xls_book = load_workbook(in_stream, read_only=True) + xls_book = load_workbook(in_stream, read_only=True, data_only=True) for sheet in xls_book.worksheets: data = tablib.Dataset() diff --git a/tests/files/xlsx_cell_values.xlsx b/tests/files/xlsx_cell_values.xlsx new file mode 100644 index 0000000..0f72e9c Binary files /dev/null and b/tests/files/xlsx_cell_values.xlsx differ diff --git a/tests/test_tablib.py b/tests/test_tablib.py index 6a2fbc2..ca57d00 100755 --- a/tests/test_tablib.py +++ b/tests/test_tablib.py @@ -1023,6 +1023,13 @@ class XLSXTests(BaseTestCase): data.append(('string', b'\x0cf')) data.xlsx + def test_xlsx_cell_values(self): + """Test cell values are read and not formulas""" + xls_source = Path(__file__).parent / 'files' / 'xlsx_cell_values.xlsx' + with xls_source.open('rb') as fh: + data = tablib.Dataset().load(fh) + self.assertEqual(data.headers[0], 'Hello World') + class JSONTests(BaseTestCase): def test_json_format_detect(self):