1
- """
2
- Utilities for conversion to writer-agnostic Excel representation.
1
+ """Utilities for conversion to writer-agnostic Excel representation
3
2
"""
4
3
5
4
from functools import reduce
6
5
import itertools
7
6
import re
8
- from typing import Any , Callable , Dict , List , Optional , Sequence , Union
7
+ from typing import Callable , Dict , List , Optional , Sequence , Union
9
8
import warnings
10
9
11
10
import numpy as np
@@ -39,8 +38,7 @@ def __init__(
39
38
40
39
41
40
class CSSToExcelConverter :
42
- """
43
- A callable for converting CSS declarations to ExcelWriter styles.
41
+ """A callable for converting CSS declarations to ExcelWriter styles
44
42
45
43
Supports parts of CSS 2.2, with minimal CSS 3.0 support (e.g. text-shadow),
46
44
focusing on font styling, backgrounds, borders and alignment.
@@ -81,23 +79,15 @@ def __call__(self, declarations_str: str) -> Dict[str, Dict[str, str]]:
81
79
82
80
Returns
83
81
-------
84
- Dict
85
- A style as interpreted by ExcelWriter when found in ExcelCell.style.
82
+ xlstyle : dict
83
+ A style as interpreted by ExcelWriter when found in
84
+ ExcelCell.style.
86
85
"""
87
86
# TODO: memoize?
88
87
properties = self .compute_css (declarations_str , self .inherited )
89
88
return self .build_xlstyle (properties )
90
89
91
90
def build_xlstyle (self , props : Dict [str , str ]) -> Dict [str , Dict [str , str ]]:
92
- """
93
- Parameters
94
- ----------
95
- props : Dict
96
-
97
- Returns
98
- -------
99
- Dict
100
- """
101
91
out = {
102
92
"alignment" : self .build_alignment (props ),
103
93
"border" : self .build_border (props ),
@@ -109,13 +99,7 @@ def build_xlstyle(self, props: Dict[str, str]) -> Dict[str, Dict[str, str]]:
109
99
# TODO: handle cell width and height: needs support in pandas.io.excel
110
100
111
101
def remove_none (d : Dict [str , str ]) -> None :
112
- """
113
- Remove key where value is None, through nested dicts.
114
-
115
- Parameters
116
- ----------
117
- d : Dict
118
- """
102
+ """Remove key where value is None, through nested dicts"""
119
103
for k , v in list (d .items ()):
120
104
if v is None :
121
105
del d [k ]
@@ -137,12 +121,7 @@ def remove_none(d: Dict[str, str]) -> None:
137
121
# OpenXML also has 'justify', 'distributed'
138
122
}
139
123
140
- def build_alignment (self , props ) -> Dict [str , Any ]:
141
- """
142
- Returns
143
- -------
144
- Dict
145
- """
124
+ def build_alignment (self , props ) -> Dict [str , Optional [Union [bool , str ]]]:
146
125
# TODO: text-indent, padding-left -> alignment.indent
147
126
return {
148
127
"horizontal" : props .get ("text-align" ),
@@ -154,16 +133,7 @@ def build_alignment(self, props) -> Dict[str, Any]:
154
133
),
155
134
}
156
135
157
- def build_border (self , props : Dict ) -> Dict [str , Any ]:
158
- """
159
- Parameters
160
- ----------
161
- props : Dict
162
-
163
- Returns
164
- -------
165
- Dict
166
- """
136
+ def build_border (self , props : Dict ) -> Dict [str , Dict [str , str ]]:
167
137
return {
168
138
side : {
169
139
"style" : self ._border_style (
@@ -224,12 +194,7 @@ def _border_style(self, style: Optional[str], width):
224
194
return "dashed"
225
195
return "mediumDashed"
226
196
227
- def build_fill (self , props : Dict ):
228
- """
229
- Parameters
230
- ----------
231
- props : Dict
232
- """
197
+ def build_fill (self , props : Dict [str , str ]):
233
198
# TODO: perhaps allow for special properties
234
199
# -excel-pattern-bgcolor and -excel-pattern-type
235
200
fill_color = props .get ("background-color" )
@@ -253,12 +218,7 @@ def build_fill(self, props: Dict):
253
218
}
254
219
ITALIC_MAP = {"normal" : False , "italic" : True , "oblique" : True }
255
220
256
- def build_font (self , props ) -> Dict [str , Union [bool , int , str , None ]]:
257
- """
258
- Returns
259
- -------
260
- Dict
261
- """
221
+ def build_font (self , props ) -> Dict [str , Optional [Union [bool , int , str ]]]:
262
222
size = props .get ("font-size" )
263
223
if size is not None :
264
224
assert size .endswith ("pt" )
@@ -355,11 +315,6 @@ def build_font(self, props) -> Dict[str, Union[bool, int, str, None]]:
355
315
}
356
316
357
317
def color_to_excel (self , val : Optional [str ]):
358
- """
359
- Parameters
360
- ----------
361
- val : str, optional
362
- """
363
318
if val is None :
364
319
return None
365
320
if val .startswith ("#" ) and len (val ) == 7 :
@@ -371,39 +326,37 @@ def color_to_excel(self, val: Optional[str]):
371
326
except KeyError :
372
327
warnings .warn (f"Unhandled color format: { repr (val )} " , CSSWarning )
373
328
374
- def build_number_format (self , props : Dict ) -> Dict [str , Any ]:
329
+ def build_number_format (self , props : Dict ) -> Dict [str , Optional [ str ] ]:
375
330
return {"format_code" : props .get ("number-format" )}
376
331
377
332
378
333
class ExcelFormatter :
379
334
"""
380
- Class for formatting a DataFrame to a list of ExcelCells.
335
+ Class for formatting a DataFrame to a list of ExcelCells,
381
336
382
337
Parameters
383
338
----------
384
339
df : DataFrame or Styler
385
- na_rep: str
386
- An na representation.
387
- float_format : str, optional
388
- Format string for floating point numbers.
389
- cols : Sequence, optional
390
- Columns to write.
391
- header : Union[bool, List[str]], default True
392
- Write out column names.
393
- If a list of string is given it is assumed to be aliases for the column names
394
- index : bool, default True
395
- Output row names (index).
396
- index_label : Union[str, Sequence, None], default None
397
- Column label for index column(s) if desired.
398
- If None is given, and `header` and `index` are True,
399
- then the index names are used.
400
- A Sequence should be given if the DataFrame uses MultiIndex.
401
- merge_cells : bool, default False
340
+ na_rep: na representation
341
+ float_format : string, default None
342
+ Format string for floating point numbers
343
+ cols : sequence, optional
344
+ Columns to write
345
+ header : boolean or list of string, default True
346
+ Write out column names. If a list of string is given it is
347
+ assumed to be aliases for the column names
348
+ index : boolean, default True
349
+ output row names (index)
350
+ index_label : string or sequence, default None
351
+ Column label for index column(s) if desired. If None is given, and
352
+ `header` and `index` are True, then the index names are used. A
353
+ sequence should be given if the DataFrame uses MultiIndex.
354
+ merge_cells : boolean, default False
402
355
Format MultiIndex and Hierarchical Rows as merged cells.
403
- inf_rep : str , default `'inf'`
356
+ inf_rep : string , default `'inf'`
404
357
representation for np.inf values (which aren't representable in Excel)
405
358
A `'-'` sign will be added in front of -inf.
406
- style_converter : Callable , optional
359
+ style_converter : callable , optional
407
360
This translates Styler styles (CSS) into ExcelWriter styles.
408
361
Defaults to ``CSSToExcelConverter()``.
409
362
It should have signature css_declarations string -> excel style.
@@ -753,7 +706,7 @@ def write(
753
706
freeze_panes : tuple of integer (length 2), default None
754
707
Specifies the one-based bottommost row and rightmost column that
755
708
is to be frozen
756
- engine : str , default None
709
+ engine : string , default None
757
710
write engine to use if writer is a path - you can also set this
758
711
via the options ``io.excel.xlsx.writer``, ``io.excel.xls.writer``,
759
712
and ``io.excel.xlsm.writer``.
0 commit comments