4
4
from functools import reduce
5
5
import itertools
6
6
import re
7
+ from typing import Callable , Dict , List , Optional , Sequence , Union
7
8
import warnings
8
9
9
10
import numpy as np
@@ -25,7 +26,9 @@ class ExcelCell:
25
26
__fields__ = ("row" , "col" , "val" , "style" , "mergestart" , "mergeend" )
26
27
__slots__ = __fields__
27
28
28
- def __init__ (self , row , col , val , style = None , mergestart = None , mergeend = None ):
29
+ def __init__ (
30
+ self , row : int , col : int , val , style = None , mergestart = None , mergeend = None
31
+ ):
29
32
self .row = row
30
33
self .col = col
31
34
self .val = val
@@ -56,15 +59,15 @@ class CSSToExcelConverter:
56
59
# instancemethods so that users can easily experiment with extensions
57
60
# without monkey-patching.
58
61
59
- def __init__ (self , inherited = None ):
62
+ def __init__ (self , inherited : Optional [ str ] = None ):
60
63
if inherited is not None :
61
64
inherited = self .compute_css (inherited )
62
65
63
66
self .inherited = inherited
64
67
65
68
compute_css = CSSResolver ()
66
69
67
- def __call__ (self , declarations_str : str ):
70
+ def __call__ (self , declarations_str : str ) -> Dict [ str , Dict [ str , str ]] :
68
71
"""
69
72
Convert CSS declarations to ExcelWriter style.
70
73
@@ -84,7 +87,7 @@ def __call__(self, declarations_str: str):
84
87
properties = self .compute_css (declarations_str , self .inherited )
85
88
return self .build_xlstyle (properties )
86
89
87
- def build_xlstyle (self , props ) :
90
+ def build_xlstyle (self , props : Dict [ str , str ]) -> Dict [ str , Dict [ str , str ]] :
88
91
out = {
89
92
"alignment" : self .build_alignment (props ),
90
93
"border" : self .build_border (props ),
@@ -95,7 +98,7 @@ def build_xlstyle(self, props):
95
98
96
99
# TODO: handle cell width and height: needs support in pandas.io.excel
97
100
98
- def remove_none (d ) :
101
+ def remove_none (d : Dict [ str , str ]) -> None :
99
102
"""Remove key where value is None, through nested dicts"""
100
103
for k , v in list (d .items ()):
101
104
if v is None :
@@ -118,7 +121,7 @@ def remove_none(d):
118
121
# OpenXML also has 'justify', 'distributed'
119
122
}
120
123
121
- def build_alignment (self , props ):
124
+ def build_alignment (self , props ) -> Dict [ str , Optional [ Union [ bool , str ]]] :
122
125
# TODO: text-indent, padding-left -> alignment.indent
123
126
return {
124
127
"horizontal" : props .get ("text-align" ),
@@ -130,7 +133,7 @@ def build_alignment(self, props):
130
133
),
131
134
}
132
135
133
- def build_border (self , props ) :
136
+ def build_border (self , props : Dict ) -> Dict [ str , Dict [ str , str ]] :
134
137
return {
135
138
side : {
136
139
"style" : self ._border_style (
@@ -142,7 +145,7 @@ def build_border(self, props):
142
145
for side in ["top" , "right" , "bottom" , "left" ]
143
146
}
144
147
145
- def _border_style (self , style , width ):
148
+ def _border_style (self , style : Optional [ str ] , width ):
146
149
# convert styles and widths to openxml, one of:
147
150
# 'dashDot'
148
151
# 'dashDotDot'
@@ -191,7 +194,7 @@ def _border_style(self, style, width):
191
194
return "dashed"
192
195
return "mediumDashed"
193
196
194
- def build_fill (self , props ):
197
+ def build_fill (self , props : Dict [ str , str ] ):
195
198
# TODO: perhaps allow for special properties
196
199
# -excel-pattern-bgcolor and -excel-pattern-type
197
200
fill_color = props .get ("background-color" )
@@ -215,7 +218,7 @@ def build_fill(self, props):
215
218
}
216
219
ITALIC_MAP = {"normal" : False , "italic" : True , "oblique" : True }
217
220
218
- def build_font (self , props ):
221
+ def build_font (self , props ) -> Dict [ str , Optional [ Union [ bool , int , str ]]] :
219
222
size = props .get ("font-size" )
220
223
if size is not None :
221
224
assert size .endswith ("pt" )
@@ -311,7 +314,7 @@ def build_font(self, props):
311
314
"white" : "FFFFFF" ,
312
315
}
313
316
314
- def color_to_excel (self , val ):
317
+ def color_to_excel (self , val : Optional [ str ] ):
315
318
if val is None :
316
319
return None
317
320
if val .startswith ("#" ) and len (val ) == 7 :
@@ -323,7 +326,7 @@ def color_to_excel(self, val):
323
326
except KeyError :
324
327
warnings .warn (f"Unhandled color format: { repr (val )} " , CSSWarning )
325
328
326
- def build_number_format (self , props ) :
329
+ def build_number_format (self , props : Dict ) -> Dict [ str , Optional [ str ]] :
327
330
return {"format_code" : props .get ("number-format" )}
328
331
329
332
@@ -366,15 +369,15 @@ class ExcelFormatter:
366
369
def __init__ (
367
370
self ,
368
371
df ,
369
- na_rep = "" ,
370
- float_format = None ,
371
- cols = None ,
372
- header = True ,
373
- index = True ,
374
- index_label = None ,
375
- merge_cells = False ,
376
- inf_rep = "inf" ,
377
- style_converter = None ,
372
+ na_rep : str = "" ,
373
+ float_format : Optional [ str ] = None ,
374
+ cols : Optional [ Sequence ] = None ,
375
+ header : Union [ bool , List [ str ]] = True ,
376
+ index : bool = True ,
377
+ index_label : Union [ str , Sequence , None ] = None ,
378
+ merge_cells : bool = False ,
379
+ inf_rep : str = "inf" ,
380
+ style_converter : Optional [ Callable ] = None ,
378
381
):
379
382
self .rowcounter = 0
380
383
self .na_rep = na_rep
@@ -442,10 +445,8 @@ def _format_header_mi(self):
442
445
if self .columns .nlevels > 1 :
443
446
if not self .index :
444
447
raise NotImplementedError (
445
- "Writing to Excel with MultiIndex"
446
- " columns and no index "
447
- "('index'=False) is not yet "
448
- "implemented."
448
+ "Writing to Excel with MultiIndex columns and no "
449
+ "index ('index'=False) is not yet implemented."
449
450
)
450
451
451
452
has_aliases = isinstance (self .header , (tuple , list , np .ndarray , Index ))
@@ -540,7 +541,6 @@ def _format_header(self):
540
541
return itertools .chain (gen , gen2 )
541
542
542
543
def _format_body (self ):
543
-
544
544
if isinstance (self .df .index , ABCMultiIndex ):
545
545
return self ._format_hierarchical_rows ()
546
546
else :
@@ -716,8 +716,7 @@ def write(
716
716
num_rows , num_cols = self .df .shape
717
717
if num_rows > self .max_rows or num_cols > self .max_cols :
718
718
raise ValueError (
719
- "This sheet is too large! Your sheet size is: "
720
- f"{ num_rows } , { num_cols } "
719
+ f"This sheet is too large! Your sheet size is: { num_rows } , { num_cols } "
721
720
f"Max sheet size is: { self .max_rows } , { self .max_cols } "
722
721
)
723
722
0 commit comments