Skip to content

Commit ada5101

Browse files
committed
ENH: support Styler in ExcelFormatter
1 parent 23889d3 commit ada5101

File tree

1 file changed

+30
-10
lines changed

1 file changed

+30
-10
lines changed

pandas/formats/format.py

+30-10
Original file line numberDiff line numberDiff line change
@@ -1655,7 +1655,7 @@ class ExcelFormatter(object):
16551655
16561656
Parameters
16571657
----------
1658-
df : dataframe
1658+
df : dataframe or Styler
16591659
na_rep: na representation
16601660
float_format : string, default None
16611661
Format string for floating point numbers
@@ -1675,13 +1675,22 @@ class ExcelFormatter(object):
16751675
inf_rep : string, default `'inf'`
16761676
representation for np.inf values (which aren't representable in Excel)
16771677
A `'-'` sign will be added in front of -inf.
1678+
style_converter : callable, optional
1679+
This translates Styler styles (CSS) into ExcelWriter styles.
1680+
It should have signature css_list -> dict or None.
1681+
This is only called for body cells.
16781682
"""
16791683

16801684
def __init__(self, df, na_rep='', float_format=None, cols=None,
16811685
header=True, index=True, index_label=None, merge_cells=False,
1682-
inf_rep='inf'):
1686+
inf_rep='inf', style_converter=None):
16831687
self.rowcounter = 0
16841688
self.na_rep = na_rep
1689+
if hasattr(df, 'render'):
1690+
self.styler = df
1691+
df = df.data
1692+
else:
1693+
self.styler = None
16851694
self.df = df
16861695
if cols is not None:
16871696
self.df = df.loc[:, cols]
@@ -1692,6 +1701,7 @@ def __init__(self, df, na_rep='', float_format=None, cols=None,
16921701
self.header = header
16931702
self.merge_cells = merge_cells
16941703
self.inf_rep = inf_rep
1704+
self.style_converter = style_converter
16951705

16961706
def _format_value(self, val):
16971707
if lib.checknull(val):
@@ -1802,7 +1812,6 @@ def _format_regular_rows(self):
18021812
if has_aliases or self.header:
18031813
self.rowcounter += 1
18041814

1805-
coloffset = 0
18061815
# output index and index_label?
18071816
if self.index:
18081817
# chek aliases
@@ -1829,15 +1838,11 @@ def _format_regular_rows(self):
18291838
if isinstance(self.df.index, PeriodIndex):
18301839
index_values = self.df.index.to_timestamp()
18311840

1832-
coloffset = 1
18331841
for idx, idxval in enumerate(index_values):
18341842
yield ExcelCell(self.rowcounter + idx, 0, idxval, header_style)
18351843

1836-
# Write the body of the frame data series by series.
1837-
for colidx in range(len(self.columns)):
1838-
series = self.df.iloc[:, colidx]
1839-
for i, val in enumerate(series):
1840-
yield ExcelCell(self.rowcounter + i, colidx + coloffset, val)
1844+
for cell in self._generate_body(coloffset=1):
1845+
yield cell
18411846

18421847
def _format_hierarchical_rows(self):
18431848
has_aliases = isinstance(self.header, (tuple, list, np.ndarray, Index))
@@ -1902,11 +1907,26 @@ def _format_hierarchical_rows(self):
19021907
indexcolval, header_style)
19031908
gcolidx += 1
19041909

1910+
for cell in self._generate_body(coloffset=gcolidx):
1911+
yield cell
1912+
1913+
def _generate_body(self, coloffset):
1914+
if self.style_converter is None or self.styler is None:
1915+
styles = None
1916+
else:
1917+
styles = self.styler._compute().ctx
1918+
if not styles:
1919+
styles = None
1920+
xlstyle = None
1921+
19051922
# Write the body of the frame data series by series.
19061923
for colidx in range(len(self.columns)):
19071924
series = self.df.iloc[:, colidx]
19081925
for i, val in enumerate(series):
1909-
yield ExcelCell(self.rowcounter + i, gcolidx + colidx, val)
1926+
if styles is not None:
1927+
xlstyle = self.style_converter(styles[i, colidx])
1928+
yield ExcelCell(self.rowcounter + i, colidx + coloffset, val,
1929+
xlstyle)
19101930

19111931
def get_formatted_cells(self):
19121932
for cell in itertools.chain(self._format_header(),

0 commit comments

Comments
 (0)