Skip to content

Commit e2cfa77

Browse files
committed
Test Styler.to_excel
1 parent d5db0ac commit e2cfa77

File tree

1 file changed

+121
-4
lines changed

1 file changed

+121
-4
lines changed

pandas/tests/io/test_excel.py

+121-4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import pandas as pd
1818
from pandas import DataFrame, Index, MultiIndex
19+
from pandas.formats.excel import ExcelFormatter
1920
from pandas.io.parsers import read_csv
2021
from pandas.io.excel import (
2122
ExcelFile, ExcelWriter, read_excel, _XlwtWriter, _Openpyxl1Writer,
@@ -27,10 +28,6 @@
2728
import pandas.util.testing as tm
2829

2930

30-
# FIXME: run all/some tests with plain Styler instead of DataFrame
31-
# FIXME: run some tests with styled Styler
32-
33-
3431
def _skip_if_no_xlrd():
3532
try:
3633
import xlrd
@@ -2153,6 +2150,126 @@ def test_write_cells_merge_styled(self):
21532150
self.assertEqual(xcell_b1.font, openpyxl_sty_merged)
21542151
self.assertEqual(xcell_a2.font, openpyxl_sty_merged)
21552152

2153+
def test_styler_to_excel(self):
2154+
if not openpyxl_compat.is_compat(major_ver=2):
2155+
pytest.skip('incompatible openpyxl version')
2156+
2157+
def style(df):
2158+
return DataFrame([['font-weight: bold', '', ''],
2159+
['', 'color: blue', ''],
2160+
['', '', 'text-decoration: underline'],
2161+
['border-style: solid', '', ''],
2162+
['', 'font-style: italic', ''],
2163+
['', '', 'text-align: right'],
2164+
['background-color: red', '', ''],
2165+
['', '', ''],
2166+
['', '', ''],
2167+
['', '', '']],
2168+
index=df.index, columns=df.columns)
2169+
2170+
def assert_equal_style(cell1, cell2):
2171+
# XXX: should find a better way to check equality
2172+
assert cell1.alignment.__dict__ == cell2.alignment.__dict__
2173+
assert cell1.border.__dict__ == cell2.border.__dict__
2174+
assert cell1.fill.__dict__ == cell2.fill.__dict__
2175+
assert cell1.font.__dict__ == cell2.font.__dict__
2176+
assert cell1.number_format == cell2.number_format
2177+
assert cell1.protection.__dict__ == cell2.protection.__dict__
2178+
2179+
def custom_converter(css):
2180+
# use bold iff there is custom style attached to the cell
2181+
if css.strip(' \n;'):
2182+
return {'font': {'bold': True}}
2183+
return {}
2184+
2185+
# Prepare spreadsheets
2186+
2187+
df = DataFrame(np.random.randn(10, 3))
2188+
with ensure_clean('.xlsx') as path:
2189+
writer = _Openpyxl22Writer(path)
2190+
df.to_excel(writer, engine='openpyxl', sheet_name='frame')
2191+
df.style.to_excel(writer, engine='openpyxl', sheet_name='unstyled')
2192+
styled = df.style.apply(style, axis=None)
2193+
styled.to_excel(writer, engine='openpyxl', sheet_name='styled')
2194+
ExcelFormatter(styled, style_converter=custom_converter).write(
2195+
writer, engine='openpyxl', sheet_name='custom')
2196+
2197+
# (1) compare DataFrame.to_excel and Styler.to_excel when unstyled
2198+
n_cells = 0
2199+
for col1, col2 in zip(writer.sheets['frame'],
2200+
writer.sheets['unstyled']):
2201+
assert len(col1) == len(col2)
2202+
for cell1, cell2 in zip(col1, col2):
2203+
assert cell1.value == cell2.value
2204+
assert_equal_style(cell1, cell2)
2205+
n_cells += 1
2206+
2207+
# ensure iteration actually happened:
2208+
assert n_cells == (10 + 1) * (3 + 1)
2209+
2210+
# (2) check styling with default converter
2211+
n_cells = 0
2212+
for col1, col2 in zip(writer.sheets['frame'],
2213+
writer.sheets['styled']):
2214+
assert len(col1) == len(col2)
2215+
for cell1, cell2 in zip(col1, col2):
2216+
ref = '%s%d' % (cell2.column, cell2.row)
2217+
# XXX: this isn't as strong a test as ideal; we should
2218+
# differences are exclusive
2219+
if ref == 'B2':
2220+
assert not cell1.font.bold
2221+
assert cell2.font.bold
2222+
elif ref == 'C3':
2223+
assert cell1.font.color.rgb != cell2.font.color.rgb
2224+
assert cell2.font.color.rgb == '000000FF'
2225+
elif ref == 'D4':
2226+
assert cell1.font.underline != cell2.font.underline
2227+
assert cell2.font.underline == 'single'
2228+
elif ref == 'B5':
2229+
assert not cell1.border.left.style
2230+
assert (cell2.border.top.style ==
2231+
cell2.border.right.style ==
2232+
cell2.border.bottom.style ==
2233+
cell2.border.left.style ==
2234+
'medium')
2235+
elif ref == 'C6':
2236+
assert not cell1.font.italic
2237+
assert cell2.font.italic
2238+
elif ref == 'D7':
2239+
assert (cell1.alignment.horizontal !=
2240+
cell2.alignment.horizontal)
2241+
assert cell2.alignment.horizontal == 'right'
2242+
elif ref == 'B8':
2243+
assert cell1.fill.fgColor.rgb != cell2.fill.fgColor.rgb
2244+
assert cell1.fill.patternType != cell2.fill.patternType
2245+
assert cell2.fill.fgColor.rgb == '00FF0000'
2246+
assert cell2.fill.patternType == 'solid'
2247+
else:
2248+
assert_equal_style(cell1, cell2)
2249+
2250+
assert cell1.value == cell2.value
2251+
n_cells += 1
2252+
2253+
assert n_cells == (10 + 1) * (3 + 1)
2254+
2255+
# (3) check styling with custom converter
2256+
n_cells = 0
2257+
for col1, col2 in zip(writer.sheets['frame'],
2258+
writer.sheets['custom']):
2259+
assert len(col1) == len(col2)
2260+
for cell1, cell2 in zip(col1, col2):
2261+
ref = '%s%d' % (cell2.column, cell2.row)
2262+
if ref in ('B2', 'C3', 'D4', 'B5', 'C6', 'D7', 'B8'):
2263+
assert not cell1.font.bold
2264+
assert cell2.font.bold
2265+
else:
2266+
assert_equal_style(cell1, cell2)
2267+
2268+
assert cell1.value == cell2.value
2269+
n_cells += 1
2270+
2271+
assert n_cells == (10 + 1) * (3 + 1)
2272+
21562273

21572274
class XlwtTests(ExcelWriterBase, tm.TestCase):
21582275
ext = '.xls'

0 commit comments

Comments
 (0)