Skip to content

Commit 620affd

Browse files
Refactor a bit to make a bit more readable
1 parent 3f3659b commit 620affd

File tree

1 file changed

+88
-48
lines changed

1 file changed

+88
-48
lines changed

pandas/io/excel/_odswriter.py

Lines changed: 88 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55

66
from pandas.io.excel._base import ExcelWriter
77

8-
# from pandas.io.excel._util import _validate_freeze_panes
8+
from pandas.io.excel._util import _validate_freeze_panes
99

1010
from odf.opendocument import OpenDocumentSpreadsheet
1111
from odf.style import Style, TextProperties, TableCellProperties, ParagraphProperties
1212
from odf.table import Table, TableRow, TableCell
1313
from odf.text import P
14+
from odf.config import ConfigItemSet, ConfigItemMapEntry, ConfigItemMapNamed, ConfigItem, ConfigItemMapIndexed
1415

1516

1617
class _ODSWriter(ExcelWriter):
@@ -36,11 +37,11 @@ def save(self):
3637
self.book.spreadsheet.addElement(sheet)
3738
return self.book.save(self.path)
3839

39-
def write_cells(
40-
self, cells, sheet_name=None, startrow=0, startcol=0, freeze_panes=None
41-
):
40+
def write_cells(self, cells, sheet_name=None, startrow=0, startcol=0,
41+
freeze_panes=None):
4242
# Write the frame cells using odf
43-
43+
# assert startrow == 0
44+
# assert startcol == 0
4445
sheet_name = self._get_sheet_name(sheet_name)
4546

4647
if sheet_name in self.sheets:
@@ -49,65 +50,69 @@ def write_cells(
4950
wks = Table(name=sheet_name)
5051
self.sheets[sheet_name] = wks
5152

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])
56-
53+
if _validate_freeze_panes(freeze_panes):
54+
self._create_freeze_panes(sheet_name, freeze_panes)
5755

5856
rows = defaultdict(TableRow)
5957
col_count = defaultdict(int)
6058

6159
for cell in sorted(cells, key=lambda cell: (cell.row, cell.col)):
62-
attributes = {}
63-
style_name = self._process_style(cell.style)
64-
if style_name is not None:
65-
attributes["stylename"] = style_name
66-
print(cell.row, cell.col, cell.val, cell.mergestart, cell.mergeend)
67-
if cell.mergestart is not None and cell.mergeend is not None:
68-
attributes["numberrowsspanned"] = max(1, cell.mergestart)
69-
attributes["numbercolumnsspanned"] = cell.mergeend
7060
# fill with empty cells if needed
7161
for _ in range(cell.col - col_count[cell.row]):
7262
rows[cell.row].addElement(TableCell())
7363
col_count[cell.row] += 1
74-
val, fmt = self._value_with_fmt(cell.val)
75-
# print("type", type(val), "value", val)
76-
pvalue = value = val
77-
if isinstance(val, bool):
78-
value = str(val).lower()
79-
pvalue = str(val).upper()
80-
if isinstance(val, datetime.datetime):
81-
if val.time():
82-
value = val.isoformat()
83-
pvalue = val.strftime("%c")
84-
else:
85-
value = val.strftime("%Y-%m-%d")
86-
pvalue = val.strftime("%x")
87-
tc = TableCell(valuetype="date", datevalue=value, attributes=attributes)
88-
elif isinstance(val, datetime.date):
89-
value = val.strftime("%Y-%m-%d")
90-
pvalue = val.strftime("%x")
91-
tc = TableCell(valuetype="date", datevalue=value, attributes=attributes)
92-
else:
93-
class_to_cell_type = {
94-
str: "string",
95-
int: "float",
96-
float: "float",
97-
bool: "boolean",
98-
}
99-
tc = TableCell(
100-
valuetype=class_to_cell_type[type(val)],
101-
value=value,
102-
attributes=attributes,
103-
)
64+
65+
pvalue, tc = self._make_table_cell(cell)
10466
rows[cell.row].addElement(tc)
10567
col_count[cell.row] += 1
10668
p = P(text=pvalue)
10769
tc.addElement(p)
70+
71+
# add all rows to the sheet
10872
for row_nr in range(max(rows.keys()) + 1):
10973
wks.addElement(rows[row_nr])
11074

75+
def _make_table_cell_attributes(self, cell):
76+
attributes = {}
77+
style_name = self._process_style(cell.style)
78+
if style_name is not None:
79+
attributes["stylename"] = style_name
80+
if cell.mergestart is not None and cell.mergeend is not None:
81+
attributes["numberrowsspanned"] = max(1, cell.mergestart)
82+
attributes["numbercolumnsspanned"] = cell.mergeend
83+
return attributes
84+
85+
def _make_table_cell(self, cell):
86+
attributes = self._make_table_cell_attributes(cell)
87+
val, fmt = self._value_with_fmt(cell.val)
88+
pvalue = value = val
89+
if isinstance(val, bool):
90+
value = str(val).lower()
91+
pvalue = str(val).upper()
92+
if isinstance(val, datetime.datetime):
93+
if val.time():
94+
value = val.isoformat()
95+
pvalue = val.strftime("%c")
96+
else:
97+
value = val.strftime("%Y-%m-%d")
98+
pvalue = val.strftime("%x")
99+
return pvalue, TableCell(valuetype="date", datevalue=value,
100+
attributes=attributes)
101+
elif isinstance(val, datetime.date):
102+
value = val.strftime("%Y-%m-%d")
103+
pvalue = val.strftime("%x")
104+
return pvalue, TableCell(valuetype="date", datevalue=value,
105+
attributes=attributes)
106+
else:
107+
class_to_cell_type = {
108+
str: "string",
109+
int: "float",
110+
float: "float",
111+
bool: "boolean",
112+
}
113+
return pvalue, TableCell(valuetype=class_to_cell_type[type(val)],
114+
value=value, attributes=attributes)
115+
111116
def _process_style(self, style):
112117
if style is None:
113118
return None
@@ -140,3 +145,38 @@ def _process_style(self, style):
140145
odf_style.addElement(TableCellProperties(verticalalign=vertical))
141146
self.book.styles.addElement(odf_style)
142147
return name
148+
149+
def _create_freeze_panes(self, sheet_name, freeze_panes):
150+
config_item_set = ConfigItemSet(name="ooo:view-settings")
151+
self.book.settings.addElement(config_item_set)
152+
153+
config_item_map_indexed = ConfigItemMapIndexed(name="Views")
154+
config_item_set.addElement(config_item_map_indexed)
155+
156+
config_item_map_entry = ConfigItemMapEntry()
157+
config_item_map_indexed.addElement(config_item_map_entry)
158+
159+
config_item_map_named = ConfigItemMapNamed(name="Tables")
160+
config_item_map_entry.addElement(config_item_map_named)
161+
162+
config_item_map_entry = ConfigItemMapEntry(name=sheet_name)
163+
config_item_map_named.addElement(config_item_map_entry)
164+
165+
config_item_map_entry.addElement(ConfigItem(name="HorizontalSplitMode",
166+
type="short",
167+
text="2"))
168+
config_item_map_entry.addElement(ConfigItem(name="VerticalSplitMode",
169+
type="short",
170+
text="2"))
171+
config_item_map_entry.addElement(ConfigItem(name="HorizontalSplitPosition",
172+
type="int",
173+
text=str(freeze_panes[0])))
174+
config_item_map_entry.addElement(ConfigItem(name="VerticalSplitPosition",
175+
type="int",
176+
text=str(freeze_panes[1])))
177+
config_item_map_entry.addElement(ConfigItem(name="PositionRight",
178+
type="int",
179+
text=str(freeze_panes[0])))
180+
config_item_map_entry.addElement(ConfigItem(name="PositionBottom",
181+
type="int",
182+
text=str(freeze_panes[1])))

0 commit comments

Comments
 (0)