ods: handle strings with comma as decimal separator as numbers (#47783)

This commit is contained in:
Frédéric Péters 2020-10-16 11:59:54 +02:00
parent 9d0ca1c090
commit b52e8c5e72
2 changed files with 19 additions and 1 deletions

View File

@ -1580,6 +1580,8 @@ def test_backoffice_ods(pub):
display_locations=['validation', 'summary', 'listings']))
formdef.fields.append(fields.StringField(id='9', label='string field', type='string',
display_locations=['validation', 'summary', 'listings']))
formdef.fields.append(fields.StringField(id='10', label='number with comma field', type='string',
display_locations=['validation', 'summary', 'listings']))
formdef.store()
formdata = formdef.data_class().select(lambda x: x.status == 'wf-new')[0]
@ -1590,6 +1592,7 @@ def test_backoffice_ods(pub):
formdata.data['7'] = '0102030405'
formdata.data['8'] = time.strptime('1871-03-18', '%Y-%m-%d')
formdata.data['9'] = 'plop\npl\x1dop' # with control characters
formdata.data['10'] = '123,45'
formdata.store()
resp = app.get('/backoffice/management/form-title/')
@ -1613,6 +1616,7 @@ def test_backoffice_ods(pub):
phone_column = all_texts.index('phone field')
old_column = all_texts.index('very old field')
string_column = all_texts.index('string field')
comma_number_column = all_texts.index('number with comma field')
for row in ods_sheet.findall('.//{%s}table-row' % ods.NS['table']):
if row.findall('.//{%s}table-cell/{%s}p' % (
@ -1641,6 +1645,8 @@ def test_backoffice_ods(pub):
'{%s}date-value' % ods.NS['office']] == '1871-03-18'
assert row.findall('.//{%s}table-cell' % ods.NS['table'])[
string_column].find('{%s}p' % ods.NS['text']).text == 'plop\nplop'
assert row.findall('.//{%s}table-cell' % ods.NS['table'])[comma_number_column].attrib[
'{%s}value' % ods.NS['office']] == '123.45'
@pytest.mark.skipif('xlwt is None')

View File

@ -52,7 +52,11 @@ def clean_text(value):
def is_number(value):
if value and (value.startswith('0') or value.startswith('+')):
# avoid phone numbers
return False
if isinstance(value, str):
# replace comma by dot, to handle decimal separator
value = value.replace(',', '.', 1)
try:
float(value)
except ValueError:
@ -60,6 +64,14 @@ def is_number(value):
return True
def get_as_string_number(value):
# to be called after value has been checked by is_number()
if isinstance(value, str):
# replace comma by dot, to handle decimal separator
return value.replace(',', '.', 1)
return str(value)
class Workbook(object):
def __init__(self, encoding='utf-8'):
self.sheets = []
@ -217,6 +229,6 @@ class WorkCell(object):
p.text = strftime(date_format(), make_datetime(self.native_value))
elif is_number(self.value):
root.attrib['{%s}value-type' % NS['office']] = 'float'
root.attrib['{%s}value' % NS['office']] = str(self.value)
root.attrib['{%s}value' % NS['office']] = get_as_string_number(self.value)
return root