Skip to content

Commit b0abeff

Browse files
Add support for dates
1 parent 4f31dab commit b0abeff

File tree

4 files changed

+60
-22
lines changed

4 files changed

+60
-22
lines changed

pandas/io/excel/_odfreader.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ def get_sheet_data(self, sheet, convert_float: bool) -> List[List[Scalar]]:
118118
if len(row) < max_row_len:
119119
row.extend([self.empty_value] * (max_row_len - len(row)))
120120

121+
# print(table)
121122
return table
122123

123124
def _get_row_repeat(self, row) -> int:
@@ -148,7 +149,11 @@ def _is_empty_row(self, row) -> bool:
148149
def _get_cell_value(self, cell, convert_float: bool) -> Scalar:
149150
from odf.namespaces import OFFICENS
150151

152+
# print("cell: ", cell, convert_float)
153+
151154
cell_type = cell.attributes.get((OFFICENS, "value-type"))
155+
cell_value = cell.attributes.get((OFFICENS, "value"))
156+
# print("type=", cell_type, "value=", repr(cell_value))
152157
if cell_type == "boolean":
153158
if str(cell) == "TRUE":
154159
return True
@@ -157,14 +162,16 @@ def _get_cell_value(self, cell, convert_float: bool) -> Scalar:
157162
return self.empty_value
158163
elif cell_type == "float":
159164
# GH5394
160-
cell_value = float(cell.attributes.get((OFFICENS, "value")))
161-
162-
if cell_value == 0.0: # NA handling
163-
return str(cell)
164165

166+
value = cell.attributes.get((OFFICENS, "value"))
167+
if value == "": # NA handling
168+
return ""
169+
cell_value = float(cell_value)
165170
if convert_float:
171+
# print("convert", cell_value, int(cell_value))
166172
val = int(cell_value)
167173
if val == cell_value:
174+
# print("return the int")
168175
return val
169176
return cell_value
170177
elif cell_type == "percentage":

pandas/io/excel/_odswriter.py

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
from collections import defaultdict
2+
import datetime
23

3-
import pandas._libs.json as json
4+
# import pandas._libs.json as json
45

56
from pandas.io.excel._base import ExcelWriter
6-
from pandas.io.excel._util import _validate_freeze_panes
7+
# from pandas.io.excel._util import _validate_freeze_panes
78

89
from odf.opendocument import OpenDocumentSpreadsheet
910
from odf.table import Table, TableRow, TableCell
1011
from odf.text import P
1112

13+
1214
class _ODSWriter(ExcelWriter):
1315
engine = "odf"
1416
supported_extensions = (".ods",)
@@ -24,8 +26,9 @@ def __init__(self, path, engine=None, encoding=None, mode="w", **engine_kwargs):
2426
if encoding is None:
2527
encoding = "ascii"
2628
self.book = OpenDocumentSpreadsheet()
27-
# self.fm_datetime = xlwt.easyxf(num_format_str=self.datetime_format)
28-
# self.fm_date = xlwt.easyxf(num_format_str=self.date_format)
29+
30+
# self.fm_datetime = xlwt.easyxf(num_format_str=self.datetime_format)
31+
# self.fm_date = xlwt.easyxf(num_format_str=self.date_format)
2932

3033
def save(self):
3134
"""
@@ -46,31 +49,49 @@ def write_cells(
4649
wks = self.sheets[sheet_name]
4750
else:
4851
wks = Table(name=sheet_name)
49-
# wks = self.book.add_sheet(sheet_name) (do at the end or immediately? FIXME)
52+
# wks = self.book.add_sheet(sheet_name) (do at the end or immediately? FIXME)
5053
self.sheets[sheet_name] = wks
5154

52-
# if _validate_freeze_panes(freeze_panes):
53-
# wks.set_panes_frozen(True)
54-
# wks.set_horz_split_pos(freeze_panes[0])
55-
# wks.set_vert_split_pos(freeze_panes[1])
55+
# if _validate_freeze_panes(freeze_panes):
56+
# wks.set_panes_frozen(True)
57+
# wks.set_horz_split_pos(freeze_panes[0])
58+
# wks.set_vert_split_pos(freeze_panes[1])
5659

5760
style_dict = {}
5861

5962
rows = defaultdict(TableRow)
6063
col_count = defaultdict(int)
6164

6265
for cell in cells:
63-
print(cell.row, cell.col, cell.val)
66+
# print(cell.row, cell.col, cell.val)
6467
# fill with empty cells if needed
6568
for _ in range(cell.col - col_count[cell.row]):
6669
rows[cell.row].addElement(TableCell())
6770
col_count[cell.row] += 1
68-
class_to_cell_type = { str: "string", int: "float", float: "float", bool: "boolean" }
71+
class_to_cell_type = {
72+
str: "string",
73+
int: "float",
74+
float: "float",
75+
bool: "boolean",
76+
}
6977
val, fmt = self._value_with_fmt(cell.val)
70-
tc = TableCell(valuetype=class_to_cell_type[type(val)], value=val)
78+
# print("type", type(val), "value", val)
79+
value = val
80+
if isinstance(val, bool):
81+
value = str(val).lower()
82+
# if isinstance(val, datetime.date):
83+
# tc = TableCell(valuetype="date",
84+
if isinstance(val, datetime.date):
85+
print('date', val.strftime("%Y-%m-%d"), val.strftime("%x"))
86+
value = val.strftime("%Y-%m-%d")
87+
tc = TableCell(valuetype="date", datevalue=value)
88+
else:
89+
tc = TableCell(valuetype=class_to_cell_type[type(val)], value=value)
7190
rows[cell.row].addElement(tc)
7291
col_count[cell.row] += 1
73-
p = P(text=val)
92+
if isinstance(val, bool):
93+
value = str(val).upper()
94+
p = P(text=value)
7495
tc.addElement(p)
7596
"""
7697
stylekey = json.dumps(cell.style)

pandas/io/excel/_util.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,12 @@ def _get_default_writer(ext):
3535
str
3636
The default engine for the extension.
3737
"""
38-
_default_writers = {"xlsx": "openpyxl", "xlsm": "openpyxl", "xls": "xlwt", "ods": "odf"}
38+
_default_writers = {
39+
"xlsx": "openpyxl",
40+
"xlsm": "openpyxl",
41+
"xls": "xlwt",
42+
"ods": "odf",
43+
}
3944
xlsxwriter = import_optional_dependency(
4045
"xlsxwriter", raise_on_missing=False, on_version="warn"
4146
)

pandas/tests/io/excel/test_writers.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ def test_excel_sheet_size(self, path):
323323
with pytest.raises(ValueError, match=msg):
324324
col_df.to_excel(path)
325325

326-
def test_excel_sheet_by_name_raise(self, path):
326+
def test_excel_sheet_by_name_raise(self, path, engine):
327327
import xlrd
328328

329329
gt = DataFrame(np.random.randn(10, 2))
@@ -334,9 +334,14 @@ def test_excel_sheet_by_name_raise(self, path):
334334

335335
tm.assert_frame_equal(gt, df)
336336

337-
msg = "No sheet named <'0'>"
338-
with pytest.raises(xlrd.XLRDError, match=msg):
339-
pd.read_excel(xl, "0")
337+
if engine == "odf":
338+
msg = "sheet 0 not found"
339+
with pytest.raises(ValueError, match=msg):
340+
pd.read_excel(xl, "0")
341+
else:
342+
msg = "No sheet named <'0'>"
343+
with pytest.raises(xlrd.XLRDError, match=msg):
344+
pd.read_excel(xl, "0")
340345

341346
def test_excel_writer_context_manager(self, frame, path):
342347
with ExcelWriter(path) as writer:

0 commit comments

Comments
 (0)