Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/pandas/io/excel/_util.py : 24%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from pandas.compat._optional import import_optional_dependency
3from pandas.core.dtypes.common import is_integer, is_list_like
5_writers = {}
8def register_writer(klass):
9 """
10 Add engine to the excel writer registry.io.excel.
12 You must use this method to integrate with ``to_excel``.
14 Parameters
15 ----------
16 klass : ExcelWriter
17 """
18 if not callable(klass):
19 raise ValueError("Can only register callables as engines")
20 engine_name = klass.engine
21 _writers[engine_name] = klass
24def _get_default_writer(ext):
25 """
26 Return the default writer for the given extension.
28 Parameters
29 ----------
30 ext : str
31 The excel file extension for which to get the default engine.
33 Returns
34 -------
35 str
36 The default engine for the extension.
37 """
38 _default_writers = {"xlsx": "openpyxl", "xlsm": "openpyxl", "xls": "xlwt"}
39 xlsxwriter = import_optional_dependency(
40 "xlsxwriter", raise_on_missing=False, on_version="warn"
41 )
42 if xlsxwriter:
43 _default_writers["xlsx"] = "xlsxwriter"
44 return _default_writers[ext]
47def get_writer(engine_name):
48 try:
49 return _writers[engine_name]
50 except KeyError:
51 raise ValueError(f"No Excel writer '{engine_name}'")
54def _excel2num(x):
55 """
56 Convert Excel column name like 'AB' to 0-based column index.
58 Parameters
59 ----------
60 x : str
61 The Excel column name to convert to a 0-based column index.
63 Returns
64 -------
65 num : int
66 The column index corresponding to the name.
68 Raises
69 ------
70 ValueError
71 Part of the Excel column name was invalid.
72 """
73 index = 0
75 for c in x.upper().strip():
76 cp = ord(c)
78 if cp < ord("A") or cp > ord("Z"):
79 raise ValueError(f"Invalid column name: {x}")
81 index = index * 26 + cp - ord("A") + 1
83 return index - 1
86def _range2cols(areas):
87 """
88 Convert comma separated list of column names and ranges to indices.
90 Parameters
91 ----------
92 areas : str
93 A string containing a sequence of column ranges (or areas).
95 Returns
96 -------
97 cols : list
98 A list of 0-based column indices.
100 Examples
101 --------
102 >>> _range2cols('A:E')
103 [0, 1, 2, 3, 4]
104 >>> _range2cols('A,C,Z:AB')
105 [0, 2, 25, 26, 27]
106 """
107 cols = []
109 for rng in areas.split(","):
110 if ":" in rng:
111 rng = rng.split(":")
112 cols.extend(range(_excel2num(rng[0]), _excel2num(rng[1]) + 1))
113 else:
114 cols.append(_excel2num(rng))
116 return cols
119def _maybe_convert_usecols(usecols):
120 """
121 Convert `usecols` into a compatible format for parsing in `parsers.py`.
123 Parameters
124 ----------
125 usecols : object
126 The use-columns object to potentially convert.
128 Returns
129 -------
130 converted : object
131 The compatible format of `usecols`.
132 """
133 if usecols is None:
134 return usecols
136 if is_integer(usecols):
137 raise ValueError(
138 "Passing an integer for `usecols` is no longer supported. "
139 "Please pass in a list of int from 0 to `usecols` "
140 "inclusive instead."
141 )
143 if isinstance(usecols, str):
144 return _range2cols(usecols)
146 return usecols
149def _validate_freeze_panes(freeze_panes):
150 if freeze_panes is not None:
151 if len(freeze_panes) == 2 and all(
152 isinstance(item, int) for item in freeze_panes
153 ):
154 return True
156 raise ValueError(
157 "freeze_panes must be of form (row, column) "
158 "where row and column are integers"
159 )
161 # freeze_panes wasn't specified, return False so it won't be applied
162 # to output sheet
163 return False
166def _trim_excel_header(row):
167 # trim header row so auto-index inference works
168 # xlrd uses '' , openpyxl None
169 while len(row) > 0 and (row[0] == "" or row[0] is None):
170 row = row[1:]
171 return row
174def _fill_mi_header(row, control_row):
175 """Forward fill blank entries in row but only inside the same parent index.
177 Used for creating headers in Multiindex.
178 Parameters
179 ----------
180 row : list
181 List of items in a single row.
182 control_row : list of bool
183 Helps to determine if particular column is in same parent index as the
184 previous value. Used to stop propagation of empty cells between
185 different indexes.
187 Returns
188 -------
189 Returns changed row and control_row
190 """
191 last = row[0]
192 for i in range(1, len(row)):
193 if not control_row[i]:
194 last = row[i]
196 if row[i] == "" or row[i] is None:
197 row[i] = last
198 else:
199 control_row[i] = False
200 last = row[i]
202 return row, control_row
205def _pop_header_name(row, index_col):
206 """
207 Pop the header name for MultiIndex parsing.
209 Parameters
210 ----------
211 row : list
212 The data row to parse for the header name.
213 index_col : int, list
214 The index columns for our data. Assumed to be non-null.
216 Returns
217 -------
218 header_name : str
219 The extracted header name.
220 trimmed_row : list
221 The original data row with the header name removed.
222 """
223 # Pop out header name and fill w/blank.
224 i = index_col if not is_list_like(index_col) else max(index_col)
226 header_name = row[i]
227 header_name = None if header_name == "" else header_name
229 return header_name, row[:i] + [""] + row[i + 1 :]