@@ -2151,127 +2151,6 @@ def test_write_cells_merge_styled(self):
2151
2151
self .assertEqual (xcell_b1 .font , openpyxl_sty_merged )
2152
2152
self .assertEqual (xcell_a2 .font , openpyxl_sty_merged )
2153
2153
2154
- def test_styler_to_excel (self ):
2155
- pytest .importorskip ('jinja2' )
2156
- if not openpyxl_compat .is_compat (major_ver = 2 ):
2157
- pytest .skip ('incompatible openpyxl version' )
2158
-
2159
- def style (df ):
2160
- return DataFrame ([['font-weight: bold' , '' , '' ],
2161
- ['' , 'color: blue' , '' ],
2162
- ['' , '' , 'text-decoration: underline' ],
2163
- ['border-style: solid' , '' , '' ],
2164
- ['' , 'font-style: italic' , '' ],
2165
- ['' , '' , 'text-align: right' ],
2166
- ['background-color: red' , '' , '' ],
2167
- ['' , '' , '' ],
2168
- ['' , '' , '' ],
2169
- ['' , '' , '' ]],
2170
- index = df .index , columns = df .columns )
2171
-
2172
- def assert_equal_style (cell1 , cell2 ):
2173
- # XXX: should find a better way to check equality
2174
- assert cell1 .alignment .__dict__ == cell2 .alignment .__dict__
2175
- assert cell1 .border .__dict__ == cell2 .border .__dict__
2176
- assert cell1 .fill .__dict__ == cell2 .fill .__dict__
2177
- assert cell1 .font .__dict__ == cell2 .font .__dict__
2178
- assert cell1 .number_format == cell2 .number_format
2179
- assert cell1 .protection .__dict__ == cell2 .protection .__dict__
2180
-
2181
- def custom_converter (css ):
2182
- # use bold iff there is custom style attached to the cell
2183
- if css .strip (' \n ;' ):
2184
- return {'font' : {'bold' : True }}
2185
- return {}
2186
-
2187
- # Prepare spreadsheets
2188
-
2189
- df = DataFrame (np .random .randn (10 , 3 ))
2190
- with ensure_clean ('.xlsx' ) as path :
2191
- writer = _Openpyxl22Writer (path )
2192
- df .to_excel (writer , engine = 'openpyxl' , sheet_name = 'frame' )
2193
- df .style .to_excel (writer , engine = 'openpyxl' , sheet_name = 'unstyled' )
2194
- styled = df .style .apply (style , axis = None )
2195
- styled .to_excel (writer , engine = 'openpyxl' , sheet_name = 'styled' )
2196
- ExcelFormatter (styled , style_converter = custom_converter ).write (
2197
- writer , engine = 'openpyxl' , sheet_name = 'custom' )
2198
-
2199
- # (1) compare DataFrame.to_excel and Styler.to_excel when unstyled
2200
- n_cells = 0
2201
- for col1 , col2 in zip (writer .sheets ['frame' ],
2202
- writer .sheets ['unstyled' ]):
2203
- assert len (col1 ) == len (col2 )
2204
- for cell1 , cell2 in zip (col1 , col2 ):
2205
- assert cell1 .value == cell2 .value
2206
- assert_equal_style (cell1 , cell2 )
2207
- n_cells += 1
2208
-
2209
- # ensure iteration actually happened:
2210
- assert n_cells == (10 + 1 ) * (3 + 1 )
2211
-
2212
- # (2) check styling with default converter
2213
- n_cells = 0
2214
- for col1 , col2 in zip (writer .sheets ['frame' ],
2215
- writer .sheets ['styled' ]):
2216
- assert len (col1 ) == len (col2 )
2217
- for cell1 , cell2 in zip (col1 , col2 ):
2218
- ref = '%s%d' % (cell2 .column , cell2 .row )
2219
- # XXX: this isn't as strong a test as ideal; we should
2220
- # differences are exclusive
2221
- if ref == 'B2' :
2222
- assert not cell1 .font .bold
2223
- assert cell2 .font .bold
2224
- elif ref == 'C3' :
2225
- assert cell1 .font .color .rgb != cell2 .font .color .rgb
2226
- assert cell2 .font .color .rgb == '000000FF'
2227
- elif ref == 'D4' :
2228
- assert cell1 .font .underline != cell2 .font .underline
2229
- assert cell2 .font .underline == 'single'
2230
- elif ref == 'B5' :
2231
- assert not cell1 .border .left .style
2232
- assert (cell2 .border .top .style ==
2233
- cell2 .border .right .style ==
2234
- cell2 .border .bottom .style ==
2235
- cell2 .border .left .style ==
2236
- 'medium' )
2237
- elif ref == 'C6' :
2238
- assert not cell1 .font .italic
2239
- assert cell2 .font .italic
2240
- elif ref == 'D7' :
2241
- assert (cell1 .alignment .horizontal !=
2242
- cell2 .alignment .horizontal )
2243
- assert cell2 .alignment .horizontal == 'right'
2244
- elif ref == 'B8' :
2245
- assert cell1 .fill .fgColor .rgb != cell2 .fill .fgColor .rgb
2246
- assert cell1 .fill .patternType != cell2 .fill .patternType
2247
- assert cell2 .fill .fgColor .rgb == '00FF0000'
2248
- assert cell2 .fill .patternType == 'solid'
2249
- else :
2250
- assert_equal_style (cell1 , cell2 )
2251
-
2252
- assert cell1 .value == cell2 .value
2253
- n_cells += 1
2254
-
2255
- assert n_cells == (10 + 1 ) * (3 + 1 )
2256
-
2257
- # (3) check styling with custom converter
2258
- n_cells = 0
2259
- for col1 , col2 in zip (writer .sheets ['frame' ],
2260
- writer .sheets ['custom' ]):
2261
- assert len (col1 ) == len (col2 )
2262
- for cell1 , cell2 in zip (col1 , col2 ):
2263
- ref = '%s%d' % (cell2 .column , cell2 .row )
2264
- if ref in ('B2' , 'C3' , 'D4' , 'B5' , 'C6' , 'D7' , 'B8' ):
2265
- assert not cell1 .font .bold
2266
- assert cell2 .font .bold
2267
- else :
2268
- assert_equal_style (cell1 , cell2 )
2269
-
2270
- assert cell1 .value == cell2 .value
2271
- n_cells += 1
2272
-
2273
- assert n_cells == (10 + 1 ) * (3 + 1 )
2274
-
2275
2154
2276
2155
class XlwtTests (ExcelWriterBase , tm .TestCase ):
2277
2156
ext = '.xls'
@@ -2473,3 +2352,138 @@ def check_called(func):
2473
2352
check_called (
2474
2353
lambda : df .to_excel (
2475
2354
'something.xls' , engine = 'dummy' ))
2355
+
2356
+
2357
+ @pytest .mark .parametrize ('engine' , [
2358
+ 'xlwt' ,
2359
+ 'xlsxwriter' ,
2360
+ 'openpyxl' ,
2361
+ ])
2362
+ def test_styler_to_excel (engine ):
2363
+ def style (df ):
2364
+ # XXX: RGB colors not supported in xlwt
2365
+ return DataFrame ([['font-weight: bold' , '' , '' ],
2366
+ (['' , '' , '' ] if engine == 'xlwt'
2367
+ else ['' , 'color: blue' , '' ]),
2368
+ ['' , '' , 'text-decoration: underline' ],
2369
+ ['border-style: solid' , '' , '' ],
2370
+ ['' , 'font-style: italic' , '' ],
2371
+ ['' , '' , 'text-align: right' ],
2372
+ (['' , '' , '' ] if engine == 'xlwt' and False
2373
+ else ['background-color: red' , '' , '' ]),
2374
+ ['' , '' , '' ],
2375
+ ['' , '' , '' ],
2376
+ ['' , '' , '' ]],
2377
+ index = df .index , columns = df .columns )
2378
+
2379
+ def assert_equal_style (cell1 , cell2 ):
2380
+ # XXX: should find a better way to check equality
2381
+ assert cell1 .alignment .__dict__ == cell2 .alignment .__dict__
2382
+ assert cell1 .border .__dict__ == cell2 .border .__dict__
2383
+ assert cell1 .fill .__dict__ == cell2 .fill .__dict__
2384
+ assert cell1 .font .__dict__ == cell2 .font .__dict__
2385
+ assert cell1 .number_format == cell2 .number_format
2386
+ assert cell1 .protection .__dict__ == cell2 .protection .__dict__
2387
+
2388
+ def custom_converter (css ):
2389
+ # use bold iff there is custom style attached to the cell
2390
+ if css .strip (' \n ;' ):
2391
+ return {'font' : {'bold' : True }}
2392
+ return {}
2393
+
2394
+ pytest .importorskip ('jinja2' )
2395
+ pytest .importorskip (engine )
2396
+
2397
+ # Prepare spreadsheets
2398
+
2399
+ df = DataFrame (np .random .randn (10 , 3 ))
2400
+ with ensure_clean ('.xlsx' if engine != 'xlwt' else '.xls' ) as path :
2401
+ writer = ExcelWriter (path , engine = engine )
2402
+ df .to_excel (writer , sheet_name = 'frame' )
2403
+ df .style .to_excel (writer , sheet_name = 'unstyled' )
2404
+ styled = df .style .apply (style , axis = None )
2405
+ styled .to_excel (writer , sheet_name = 'styled' )
2406
+ ExcelFormatter (styled , style_converter = custom_converter ).write (
2407
+ writer , sheet_name = 'custom' )
2408
+
2409
+ # For engines other than openpyxl 2, we only smoke test
2410
+ if engine != 'openpyxl' :
2411
+ return
2412
+ if not openpyxl_compat .is_compat (major_ver = 2 ):
2413
+ pytest .skip ('incompatible openpyxl version' )
2414
+
2415
+ # (1) compare DataFrame.to_excel and Styler.to_excel when unstyled
2416
+ n_cells = 0
2417
+ for col1 , col2 in zip (writer .sheets ['frame' ].columns ,
2418
+ writer .sheets ['unstyled' ].columns ):
2419
+ assert len (col1 ) == len (col2 )
2420
+ for cell1 , cell2 in zip (col1 , col2 ):
2421
+ assert cell1 .value == cell2 .value
2422
+ assert_equal_style (cell1 , cell2 )
2423
+ n_cells += 1
2424
+
2425
+ # ensure iteration actually happened:
2426
+ assert n_cells == (10 + 1 ) * (3 + 1 )
2427
+
2428
+ # (2) check styling with default converter
2429
+ n_cells = 0
2430
+ for col1 , col2 in zip (writer .sheets ['frame' ].columns ,
2431
+ writer .sheets ['styled' ].columns ):
2432
+ assert len (col1 ) == len (col2 )
2433
+ for cell1 , cell2 in zip (col1 , col2 ):
2434
+ ref = '%s%d' % (cell2 .column , cell2 .row )
2435
+ # XXX: this isn't as strong a test as ideal; we should
2436
+ # differences are exclusive
2437
+ if ref == 'B2' :
2438
+ assert not cell1 .font .bold
2439
+ assert cell2 .font .bold
2440
+ elif ref == 'C3' :
2441
+ assert cell1 .font .color .rgb != cell2 .font .color .rgb
2442
+ assert cell2 .font .color .rgb == '000000FF'
2443
+ elif ref == 'D4' :
2444
+ assert cell1 .font .underline != cell2 .font .underline
2445
+ assert cell2 .font .underline == 'single'
2446
+ elif ref == 'B5' :
2447
+ assert not cell1 .border .left .style
2448
+ assert (cell2 .border .top .style ==
2449
+ cell2 .border .right .style ==
2450
+ cell2 .border .bottom .style ==
2451
+ cell2 .border .left .style ==
2452
+ 'medium' )
2453
+ elif ref == 'C6' :
2454
+ assert not cell1 .font .italic
2455
+ assert cell2 .font .italic
2456
+ elif ref == 'D7' :
2457
+ assert (cell1 .alignment .horizontal !=
2458
+ cell2 .alignment .horizontal )
2459
+ assert cell2 .alignment .horizontal == 'right'
2460
+ elif ref == 'B8' :
2461
+ assert cell1 .fill .fgColor .rgb != cell2 .fill .fgColor .rgb
2462
+ assert cell1 .fill .patternType != cell2 .fill .patternType
2463
+ assert cell2 .fill .fgColor .rgb == '00FF0000'
2464
+ assert cell2 .fill .patternType == 'solid'
2465
+ else :
2466
+ assert_equal_style (cell1 , cell2 )
2467
+
2468
+ assert cell1 .value == cell2 .value
2469
+ n_cells += 1
2470
+
2471
+ assert n_cells == (10 + 1 ) * (3 + 1 )
2472
+
2473
+ # (3) check styling with custom converter
2474
+ n_cells = 0
2475
+ for col1 , col2 in zip (writer .sheets ['frame' ].columns ,
2476
+ writer .sheets ['custom' ].columns ):
2477
+ assert len (col1 ) == len (col2 )
2478
+ for cell1 , cell2 in zip (col1 , col2 ):
2479
+ ref = '%s%d' % (cell2 .column , cell2 .row )
2480
+ if ref in ('B2' , 'C3' , 'D4' , 'B5' , 'C6' , 'D7' , 'B8' ):
2481
+ assert not cell1 .font .bold
2482
+ assert cell2 .font .bold
2483
+ else :
2484
+ assert_equal_style (cell1 , cell2 )
2485
+
2486
+ assert cell1 .value == cell2 .value
2487
+ n_cells += 1
2488
+
2489
+ assert n_cells == (10 + 1 ) * (3 + 1 )
0 commit comments