Skip to content

Commit

Permalink
Fixes #527 - Export integers/floats as numbers in ODS format (#528)
Browse files Browse the repository at this point in the history
Co-authored-by: Hugo van Kemenade <[email protected]>
  • Loading branch information
claudep and hugovk authored Oct 31, 2022
1 parent 93f4741 commit 3617859
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 37 deletions.
6 changes: 6 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# History

## unreleased

### Improvements

- ODS export: integers/floats/decimals are exported as numbers (#527).

## 3.2.1 (2022-04-09)

### Bugfixes
Expand Down
48 changes: 11 additions & 37 deletions src/tablib/formats/_ods.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
""" Tablib - ODF Support.
"""

import numbers
from io import BytesIO

from odf import opendocument, style, table, text
Expand Down Expand Up @@ -53,45 +54,18 @@ def dset_sheet(cls, dataset, ws):
_offset = i
_package.insert((sep[0] + _offset), (sep[1],))

for i, row in enumerate(_package):
row_number = i + 1
odf_row = table.TableRow(stylename=bold, defaultcellstylename='bold')
for row_number, row in enumerate(_package, start=1):
is_header = row_number == 1 and dataset.headers
style = bold if is_header else None
odf_row = table.TableRow(stylename=style)
ws.addElement(odf_row)
for j, col in enumerate(row):
try:
col = str(col, errors='ignore')
except TypeError:
# col is already str
pass
ws.addElement(table.TableColumn())

# bold headers
if (row_number == 1) and dataset.headers:
odf_row.setAttribute('stylename', bold)
ws.addElement(odf_row)
cell = table.TableCell()
p = text.P()
p.addElement(text.Span(text=col, stylename=bold))
cell.addElement(p)
odf_row.addElement(cell)

# wrap the rest
if isinstance(col, numbers.Number):
cell = table.TableCell(valuetype="float", value=col)
else:
try:
if '\n' in col:
ws.addElement(odf_row)
cell = table.TableCell()
cell.addElement(text.P(text=col))
odf_row.addElement(cell)
else:
ws.addElement(odf_row)
cell = table.TableCell()
cell.addElement(text.P(text=col))
odf_row.addElement(cell)
except TypeError:
ws.addElement(odf_row)
cell = table.TableCell()
cell.addElement(text.P(text=col))
odf_row.addElement(cell)
cell = table.TableCell(valuetype="string")
cell.addElement(text.P(text=str(col), stylename=style))
odf_row.addElement(cell)

@classmethod
def detect(cls, stream):
Expand Down
11 changes: 11 additions & 0 deletions tests/test_tablib.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import pickle
import unittest
from collections import OrderedDict
from decimal import Decimal
from io import BytesIO, StringIO
from pathlib import Path
from uuid import uuid4
Expand Down Expand Up @@ -990,6 +991,16 @@ def test_tsv_export(self):
self.assertEqual(tsv, self.founders.tsv)


class ODSTests(BaseTestCase):
def test_ods_export_datatypes(self):
date_time = datetime.datetime(2019, 10, 4, 12, 30, 8)
data.append(('string', '004', 42, 21.55, Decimal('34.5'), date_time))
data.headers = ('string', 'start0', 'integer', 'float', 'decimal', 'date/time')
# ODS is currently write-only, just test that output doesn't crash.
assert data.ods is not None
assert len(data.ods)


class XLSTests(BaseTestCase):
def test_xls_format_detect(self):
"""Test the XLS format detection."""
Expand Down

0 comments on commit 3617859

Please sign in to comment.