@@ 69-785 (lines=717) @@ | ||
66 | return base64_message |
|
67 | ||
68 | ||
69 | def generate_excel(report, |
|
70 | name, |
|
71 | base_period_start_datetime_local, |
|
72 | base_period_end_datetime_local, |
|
73 | reporting_start_datetime_local, |
|
74 | reporting_end_datetime_local, |
|
75 | period_type, |
|
76 | language): |
|
77 | ||
78 | trans = get_translation(language) |
|
79 | trans.install() |
|
80 | _ = trans.gettext |
|
81 | ||
82 | wb = Workbook() |
|
83 | ws = wb.active |
|
84 | ws.title = "ShopFloorEnergyItem" |
|
85 | ||
86 | # Row height |
|
87 | ws.row_dimensions[1].height = 102 |
|
88 | for i in range(2, 2000 + 1): |
|
89 | ws.row_dimensions[i].height = 42 |
|
90 | ||
91 | # Col width |
|
92 | ws.column_dimensions['A'].width = 1.5 |
|
93 | ||
94 | ws.column_dimensions['B'].width = 25.0 |
|
95 | ||
96 | for i in range(ord('C'), ord('Z')): |
|
97 | ws.column_dimensions[chr(i)].width = 15.0 |
|
98 | ||
99 | # Font |
|
100 | name_font = Font(name='Arial', size=15, bold=True) |
|
101 | title_font = Font(name='Arial', size=15, bold=True) |
|
102 | ||
103 | table_fill = PatternFill(fill_type='solid', fgColor='90ee90') |
|
104 | f_border = Border(left=Side(border_style='medium'), |
|
105 | right=Side(border_style='medium'), |
|
106 | bottom=Side(border_style='medium'), |
|
107 | top=Side(border_style='medium') |
|
108 | ) |
|
109 | b_border = Border( |
|
110 | bottom=Side(border_style='medium'), |
|
111 | ) |
|
112 | ||
113 | b_c_alignment = Alignment(vertical='bottom', |
|
114 | horizontal='center', |
|
115 | text_rotation=0, |
|
116 | wrap_text=True, |
|
117 | shrink_to_fit=False, |
|
118 | indent=0) |
|
119 | c_c_alignment = Alignment(vertical='center', |
|
120 | horizontal='center', |
|
121 | text_rotation=0, |
|
122 | wrap_text=True, |
|
123 | shrink_to_fit=False, |
|
124 | indent=0) |
|
125 | b_r_alignment = Alignment(vertical='bottom', |
|
126 | horizontal='right', |
|
127 | text_rotation=0, |
|
128 | wrap_text=True, |
|
129 | shrink_to_fit=False, |
|
130 | indent=0) |
|
131 | # Img |
|
132 | img = Image("excelexporters/myems.png") |
|
133 | ws.add_image(img, 'A1') |
|
134 | ||
135 | # Title |
|
136 | ws['B3'].alignment = b_r_alignment |
|
137 | ws['B3'] = _('Name') + ':' |
|
138 | ws['C3'].border = b_border |
|
139 | ws['C3'].alignment = b_c_alignment |
|
140 | ws['C3'] = name |
|
141 | ||
142 | ws['D3'].alignment = b_r_alignment |
|
143 | ws['D3'] = _('Period Type') + ':' |
|
144 | ws['E3'].border = b_border |
|
145 | ws['E3'].alignment = b_c_alignment |
|
146 | ws['E3'] = period_type |
|
147 | ||
148 | ws['B4'].alignment = b_r_alignment |
|
149 | ws['B4'] = _('Reporting Start Datetime') + ':' |
|
150 | ws['C4'].border = b_border |
|
151 | ws['C4'].alignment = b_c_alignment |
|
152 | ws['C4'] = reporting_start_datetime_local |
|
153 | ||
154 | ws['D4'].alignment = b_r_alignment |
|
155 | ws['D4'] = _('Reporting End Datetime') + ':' |
|
156 | ws['E4'].border = b_border |
|
157 | ws['E4'].alignment = b_c_alignment |
|
158 | ws['E4'] = reporting_end_datetime_local |
|
159 | ||
160 | is_base_period_timestamp_exists_flag = is_base_period_timestamp_exists(report['base_period']) |
|
161 | ||
162 | if is_base_period_timestamp_exists_flag: |
|
163 | ws['B5'].alignment = b_r_alignment |
|
164 | ws['B5'] = _('Base Period Start Datetime') + ':' |
|
165 | ws['C5'].border = b_border |
|
166 | ws['C5'].alignment = b_c_alignment |
|
167 | ws['C5'] = base_period_start_datetime_local |
|
168 | ||
169 | ws['D5'].alignment = b_r_alignment |
|
170 | ws['D5'] = _('Base Period End Datetime') + ':' |
|
171 | ws['E5'].border = b_border |
|
172 | ws['E5'].alignment = b_c_alignment |
|
173 | ws['E5'] = base_period_end_datetime_local |
|
174 | ||
175 | if "reporting_period" not in report.keys() or \ |
|
176 | "names" not in report['reporting_period'].keys() or len(report['reporting_period']['names']) == 0: |
|
177 | filename = str(uuid.uuid4()) + '.xlsx' |
|
178 | wb.save(filename) |
|
179 | ||
180 | return filename |
|
181 | ||
182 | #################################################################################################################### |
|
183 | current_row_number = 7 |
|
184 | reporting_period_data = report['reporting_period'] |
|
185 | if "names" not in reporting_period_data.keys() or \ |
|
186 | reporting_period_data['names'] is None or \ |
|
187 | len(reporting_period_data['names']) == 0: |
|
188 | pass |
|
189 | else: |
|
190 | ws['B' + str(current_row_number)].font = title_font |
|
191 | ws['B' + str(current_row_number)] = name + ' ' + _('Reporting Period Consumption') |
|
192 | ||
193 | current_row_number += 1 |
|
194 | ||
195 | category = reporting_period_data['names'] |
|
196 | ca_len = len(category) |
|
197 | ||
198 | ws.row_dimensions[current_row_number].height = 60 |
|
199 | ws['B' + str(current_row_number)].fill = table_fill |
|
200 | ws['B' + str(current_row_number)].border = f_border |
|
201 | ||
202 | col = 'C' |
|
203 | ||
204 | for i in range(0, ca_len): |
|
205 | ws[col + str(current_row_number)].fill = table_fill |
|
206 | ws[col + str(current_row_number)].font = name_font |
|
207 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
208 | ws[col + str(current_row_number)].border = f_border |
|
209 | ws[col + str(current_row_number)] = \ |
|
210 | reporting_period_data['names'][i] + " " + reporting_period_data['energy_category_names'][i] + \ |
|
211 | " (" + reporting_period_data['units'][i] + ")" |
|
212 | ||
213 | col = chr(ord(col) + 1) |
|
214 | ||
215 | current_row_number += 1 |
|
216 | ||
217 | ws['B' + str(current_row_number)].font = title_font |
|
218 | ws['B' + str(current_row_number)].alignment = c_c_alignment |
|
219 | ws['B' + str(current_row_number)].border = f_border |
|
220 | ws['B' + str(current_row_number)] = _('Per Unit Area') |
|
221 | ||
222 | col = 'C' |
|
223 | ||
224 | for i in range(0, ca_len): |
|
225 | ws[col + str(current_row_number)].font = name_font |
|
226 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
227 | ws[col + str(current_row_number)].border = f_border |
|
228 | ws[col + str(current_row_number)] = round2(reporting_period_data['subtotals'][i], 2) |
|
229 | ||
230 | col = chr(ord(col) + 1) |
|
231 | ||
232 | current_row_number += 1 |
|
233 | ||
234 | ws['B' + str(current_row_number)].font = title_font |
|
235 | ws['B' + str(current_row_number)].alignment = c_c_alignment |
|
236 | ws['B' + str(current_row_number)].border = f_border |
|
237 | ws['B' + str(current_row_number)] = 'Per Unit Area' |
|
238 | ||
239 | col = 'C' |
|
240 | ||
241 | for i in range(0, ca_len): |
|
242 | ws[col + str(current_row_number)].font = name_font |
|
243 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
244 | ws[col + str(current_row_number)].border = f_border |
|
245 | ws[col + str(current_row_number)] = round2(reporting_period_data['subtotals_per_unit_area'][i], 2) |
|
246 | ||
247 | col = chr(ord(col) + 1) |
|
248 | ||
249 | current_row_number += 1 |
|
250 | ||
251 | ws['B' + str(current_row_number)].font = title_font |
|
252 | ws['B' + str(current_row_number)].alignment = c_c_alignment |
|
253 | ws['B' + str(current_row_number)].border = f_border |
|
254 | ws['B' + str(current_row_number)] = _('Increment Rate') |
|
255 | ||
256 | col = 'C' |
|
257 | ||
258 | for i in range(0, ca_len): |
|
259 | ws[col + str(current_row_number)].font = name_font |
|
260 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
261 | ws[col + str(current_row_number)].border = f_border |
|
262 | ws[col + str(current_row_number)] = str( |
|
263 | round2(reporting_period_data['increment_rates'][i] * 100, 2)) + '%' \ |
|
264 | if reporting_period_data['increment_rates'][i] is not None else '-' |
|
265 | ||
266 | col = chr(ord(col) + 1) |
|
267 | ||
268 | current_row_number += 2 |
|
269 | ||
270 | category_dict = group_by_category(reporting_period_data['energy_category_names']) |
|
271 | ||
272 | for category_dict_name, category_dict_values in category_dict.items(): |
|
273 | ||
274 | ws['B' + str(current_row_number)].font = title_font |
|
275 | ws['B' + str(current_row_number)] = name + ' ' + category_dict_name + ' ' + \ |
|
276 | '(' + reporting_period_data['units'][category_dict_values[0]] + ') by Energy Item' |
|
277 | ||
278 | current_row_number += 1 |
|
279 | table_start_row_number = current_row_number |
|
280 | ||
281 | ws['B' + str(current_row_number)].fill = table_fill |
|
282 | ws['B' + str(current_row_number)].border = f_border |
|
283 | ||
284 | ws['C' + str(current_row_number)].font = name_font |
|
285 | ws['C' + str(current_row_number)].fill = table_fill |
|
286 | ws['C' + str(current_row_number)].alignment = c_c_alignment |
|
287 | ws['C' + str(current_row_number)].border = f_border |
|
288 | ws['C' + str(current_row_number)] = _('Per Unit Area') |
|
289 | ||
290 | current_row_number += 1 |
|
291 | ||
292 | for i in category_dict_values: |
|
293 | ws['B' + str(current_row_number)].font = title_font |
|
294 | ws['B' + str(current_row_number)].alignment = c_c_alignment |
|
295 | ws['B' + str(current_row_number)].border = f_border |
|
296 | ws['B' + str(current_row_number)] = \ |
|
297 | reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")" |
|
298 | ws['C' + str(current_row_number)].font = name_font |
|
299 | ws['C' + str(current_row_number)].alignment = c_c_alignment |
|
300 | ws['C' + str(current_row_number)].border = f_border |
|
301 | ws['C' + str(current_row_number)] = round2(reporting_period_data['subtotals'][i], 3) |
|
302 | ||
303 | current_row_number += 1 |
|
304 | ||
305 | table_end_row_number = current_row_number - 1 |
|
306 | ||
307 | pie = PieChart() |
|
308 | pie.title = name + ' ' + category_dict_name + ' ' + \ |
|
309 | '(' + reporting_period_data['units'][category_dict_values[0]] + ') by Energy Item' |
|
310 | labels = Reference(ws, min_col=2, min_row=table_start_row_number + 1, max_row=table_end_row_number) |
|
311 | pie_data = Reference(ws, min_col=3, min_row=table_start_row_number, max_row=table_end_row_number) |
|
312 | pie.add_data(pie_data, titles_from_data=True) |
|
313 | pie.set_categories(labels) |
|
314 | pie.height = 6.6 |
|
315 | pie.width = 9 |
|
316 | s1 = pie.series[0] |
|
317 | s1.dLbls = DataLabelList() |
|
318 | s1.dLbls.showCatName = False |
|
319 | s1.dLbls.showVal = False |
|
320 | s1.dLbls.showPercent = True |
|
321 | ws.add_chart(pie, 'D' + str(table_start_row_number)) |
|
322 | ||
323 | if len(category_dict_values) < 4: |
|
324 | current_row_number = current_row_number - len(category_dict_values) + 4 |
|
325 | ||
326 | current_row_number += 1 |
|
327 | ||
328 | #################################################################################################################### |
|
329 | chart_start_row_number = current_row_number |
|
330 | ||
331 | has_values_data = True |
|
332 | has_timestamps_data = True |
|
333 | ||
334 | if 'values' not in reporting_period_data.keys() or \ |
|
335 | reporting_period_data['values'] is None or \ |
|
336 | len(reporting_period_data['values']) == 0: |
|
337 | has_values_data = False |
|
338 | ||
339 | if 'timestamps' not in reporting_period_data.keys() or \ |
|
340 | reporting_period_data['timestamps'] is None or \ |
|
341 | len(reporting_period_data['timestamps']) == 0 or \ |
|
342 | len(reporting_period_data['timestamps'][0]) == 0: |
|
343 | has_timestamps_data = False |
|
344 | ||
345 | if not is_base_period_timestamp_exists_flag: |
|
346 | if has_values_data and has_timestamps_data: |
|
347 | ca_len = len(reporting_period_data['names']) |
|
348 | time = reporting_period_data['timestamps'][0] |
|
349 | real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps']) |
|
350 | ws['B' + str(current_row_number)].font = title_font |
|
351 | ws['B' + str(current_row_number)] = name + ' ' + _('Detailed Data') |
|
352 | ||
353 | current_row_number += 1 |
|
354 | ||
355 | chart_start_row_number = current_row_number |
|
356 | ||
357 | # 1: Stand for blank line 2: Stand for title |
|
358 | current_row_number += ca_len * 6 + real_timestamps_len * 6 + 1 + 2 |
|
359 | table_start_row_number = current_row_number |
|
360 | ||
361 | ws.row_dimensions[current_row_number].height = 60 |
|
362 | ws['B' + str(current_row_number)].fill = table_fill |
|
363 | ws['B' + str(current_row_number)].font = title_font |
|
364 | ws['B' + str(current_row_number)].alignment = c_c_alignment |
|
365 | ws['B' + str(current_row_number)].border = f_border |
|
366 | ws['B' + str(current_row_number)] = _('Datetime') |
|
367 | ||
368 | col = 'C' |
|
369 | ||
370 | for i in range(0, ca_len): |
|
371 | ws[col + str(current_row_number)].fill = table_fill |
|
372 | ws[col + str(current_row_number)].font = title_font |
|
373 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
374 | ws[col + str(current_row_number)].border = f_border |
|
375 | ws[col + str(current_row_number)] = \ |
|
376 | reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")" |
|
377 | col = chr(ord(col) + 1) |
|
378 | ||
379 | current_row_number += 1 |
|
380 | ||
381 | for i in range(0, len(time)): |
|
382 | ws['B' + str(current_row_number)].font = title_font |
|
383 | ws['B' + str(current_row_number)].alignment = c_c_alignment |
|
384 | ws['B' + str(current_row_number)].border = f_border |
|
385 | ws['B' + str(current_row_number)] = time[i] |
|
386 | ||
387 | col = 'C' |
|
388 | for j in range(0, ca_len): |
|
389 | ws[col + str(current_row_number)].font = title_font |
|
390 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
391 | ws[col + str(current_row_number)].border = f_border |
|
392 | ws[col + str(current_row_number)] = round2(reporting_period_data['values'][j][i], 2) \ |
|
393 | if reporting_period_data['values'][j][i] is not None else 0.00 |
|
394 | col = chr(ord(col) + 1) |
|
395 | ||
396 | current_row_number += 1 |
|
397 | ||
398 | table_end_row_number = current_row_number - 1 |
|
399 | ||
400 | ws['B' + str(current_row_number)].font = title_font |
|
401 | ws['B' + str(current_row_number)].alignment = c_c_alignment |
|
402 | ws['B' + str(current_row_number)].border = f_border |
|
403 | ws['B' + str(current_row_number)] = _('Subtotal') |
|
404 | ||
405 | col = 'C' |
|
406 | ||
407 | for i in range(0, ca_len): |
|
408 | ws[col + str(current_row_number)].font = title_font |
|
409 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
410 | ws[col + str(current_row_number)].border = f_border |
|
411 | ws[col + str(current_row_number)] = round2(reporting_period_data['subtotals'][i], 2) |
|
412 | col = chr(ord(col) + 1) |
|
413 | ||
414 | current_row_number += 2 |
|
415 | ||
416 | for i in range(0, ca_len): |
|
417 | line = LineChart() |
|
418 | line.title = _('Reporting Period Consumption') + ' - ' \ |
|
419 | + reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")" |
|
420 | labels = Reference(ws, min_col=2, |
|
421 | min_row=table_start_row_number + 1, |
|
422 | max_row=table_end_row_number) |
|
423 | reporting_line_data = Reference(ws, min_col=3 + i, |
|
424 | min_row=table_start_row_number, |
|
425 | max_row=table_end_row_number) |
|
426 | line.add_data(reporting_line_data, titles_from_data=True) |
|
427 | line.set_categories(labels) |
|
428 | reporting_line_data = line.series[0] |
|
429 | reporting_line_data.marker.symbol = "auto" |
|
430 | reporting_line_data.smooth = True |
|
431 | line.x_axis.crosses = 'min' |
|
432 | line.height = 8.25 |
|
433 | line.width = 24 |
|
434 | chart_col = 'B' |
|
435 | chart_cell = chart_col + str(chart_start_row_number) |
|
436 | chart_start_row_number += 6 |
|
437 | ws.add_chart(line, chart_cell) |
|
438 | ||
439 | else: |
|
440 | if has_values_data and has_timestamps_data: |
|
441 | base_period_data = report['base_period'] |
|
442 | reporting_period_data = report['reporting_period'] |
|
443 | base_period_timestamps = base_period_data['timestamps'] |
|
444 | reporting_period_timestamps = reporting_period_data['timestamps'] |
|
445 | # Tip: |
|
446 | # base_period_data['names'] == reporting_period_data['names'] |
|
447 | # base_period_data['units'] == reporting_period_data['units'] |
|
448 | base_period_data_ca_len = len(base_period_data['names']) |
|
449 | reporting_period_data_ca_len = len(reporting_period_data['names']) |
|
450 | real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps']) |
|
451 | ws['B' + str(current_row_number)].font = title_font |
|
452 | ws['B' + str(current_row_number)] = name + ' ' + _('Detailed Data') |
|
453 | current_row_number += 1 |
|
454 | ||
455 | chart_start_row_number = current_row_number |
|
456 | ||
457 | # 1: Stand for blank line 2: Stand for title |
|
458 | current_row_number += reporting_period_data_ca_len * 6 + real_timestamps_len * 6 + 1 + 2 |
|
459 | table_start_row_number = current_row_number |
|
460 | ||
461 | ws.row_dimensions[current_row_number].height = 60 |
|
462 | current_col_number = 2 |
|
463 | col = format_cell.get_column_letter(current_col_number) |
|
464 | ws[col + str(current_row_number)].fill = table_fill |
|
465 | ws[col + str(current_row_number)].font = title_font |
|
466 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
467 | ws[col + str(current_row_number)].border = f_border |
|
468 | ws[col + str(current_row_number)] = _('Base Period') + " - " + _('Datetime') |
|
469 | ||
470 | for i in range(0, base_period_data_ca_len): |
|
471 | current_col_number += 1 |
|
472 | col = format_cell.get_column_letter(current_col_number) |
|
473 | ||
474 | ws[col + str(current_row_number)].fill = table_fill |
|
475 | ws[col + str(current_row_number)].font = title_font |
|
476 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
477 | ws[col + str(current_row_number)] = _('Base Period') + " - " + base_period_data['names'][i] + \ |
|
478 | " (" + base_period_data['units'][i] + ")" |
|
479 | ws[col + str(current_row_number)].border = f_border |
|
480 | ||
481 | current_col_number += 1 |
|
482 | col = format_cell.get_column_letter(current_col_number) |
|
483 | ||
484 | ws[col + str(current_row_number)].fill = table_fill |
|
485 | ws[col + str(current_row_number)].font = title_font |
|
486 | ws[col + str(current_row_number)].border = f_border |
|
487 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
488 | ws[col + str(current_row_number)] = _('Reporting Period') + " - " + _('Datetime') |
|
489 | ||
490 | for i in range(0, reporting_period_data_ca_len): |
|
491 | current_col_number += 1 |
|
492 | col = format_cell.get_column_letter(current_col_number) |
|
493 | ws[col + str(current_row_number)].fill = table_fill |
|
494 | ws[col + str(current_row_number)].font = title_font |
|
495 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
496 | ws[col + str(current_row_number)] = _('Reporting Period') + " - " \ |
|
497 | + reporting_period_data['names'][i] + " (" + \ |
|
498 | reporting_period_data['units'][i] + ")" |
|
499 | ws[col + str(current_row_number)].border = f_border |
|
500 | ||
501 | current_row_number += 1 |
|
502 | ||
503 | max_timestamps_len = len(base_period_timestamps[0]) \ |
|
504 | if len(base_period_timestamps[0]) >= len(reporting_period_timestamps[0]) \ |
|
505 | else len(reporting_period_timestamps[0]) |
|
506 | ||
507 | for i in range(0, max_timestamps_len): |
|
508 | current_col_number = 2 |
|
509 | col = format_cell.get_column_letter(current_col_number) |
|
510 | ws[col + str(current_row_number)].font = title_font |
|
511 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
512 | ws[col + str(current_row_number)] = base_period_timestamps[0][i] \ |
|
513 | if i < len(base_period_timestamps[0]) else None |
|
514 | ws[col + str(current_row_number)].border = f_border |
|
515 | ||
516 | for j in range(0, base_period_data_ca_len): |
|
517 | current_col_number += 1 |
|
518 | col = format_cell.get_column_letter(current_col_number) |
|
519 | ||
520 | ws[col + str(current_row_number)].font = title_font |
|
521 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
522 | ws[col + str(current_row_number)] = round2(base_period_data['values'][j][i], 2) \ |
|
523 | if i < len(base_period_data['values'][j]) else None |
|
524 | ws[col + str(current_row_number)].border = f_border |
|
525 | current_col_number += 1 |
|
526 | col = format_cell.get_column_letter(current_col_number) |
|
527 | ||
528 | ws[col + str(current_row_number)].font = title_font |
|
529 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
530 | ws[col + str(current_row_number)] = reporting_period_timestamps[0][i] \ |
|
531 | if i < len(reporting_period_timestamps[0]) else None |
|
532 | ws[col + str(current_row_number)].border = f_border |
|
533 | ||
534 | for j in range(0, reporting_period_data_ca_len): |
|
535 | current_col_number += 1 |
|
536 | col = format_cell.get_column_letter(current_col_number) |
|
537 | ||
538 | ws[col + str(current_row_number)].font = title_font |
|
539 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
540 | ws[col + str(current_row_number)] = round2(reporting_period_data['values'][j][i], 2) \ |
|
541 | if i < len(reporting_period_data['values'][j]) else None |
|
542 | ws[col + str(current_row_number)].border = f_border |
|
543 | ||
544 | current_row_number += 1 |
|
545 | ||
546 | current_col_number = 2 |
|
547 | col = format_cell.get_column_letter(current_col_number) |
|
548 | ||
549 | ws[col + str(current_row_number)].font = title_font |
|
550 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
551 | ws[col + str(current_row_number)] = _('Subtotal') |
|
552 | ws[col + str(current_row_number)].border = f_border |
|
553 | ||
554 | for i in range(0, base_period_data_ca_len): |
|
555 | current_col_number += 1 |
|
556 | col = format_cell.get_column_letter(current_col_number) |
|
557 | ws[col + str(current_row_number)].font = title_font |
|
558 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
559 | ws[col + str(current_row_number)] = round2(base_period_data['subtotals'][i], 2) |
|
560 | ws[col + str(current_row_number)].border = f_border |
|
561 | ||
562 | current_col_number += 1 |
|
563 | col = format_cell.get_column_letter(current_col_number) |
|
564 | ||
565 | ws[col + str(current_row_number)].font = title_font |
|
566 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
567 | ws[col + str(current_row_number)] = _('Subtotal') |
|
568 | ws[col + str(current_row_number)].border = f_border |
|
569 | ||
570 | for i in range(0, reporting_period_data_ca_len): |
|
571 | current_col_number += 1 |
|
572 | col = format_cell.get_column_letter(current_col_number) |
|
573 | ws[col + str(current_row_number)].font = title_font |
|
574 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
575 | ws[col + str(current_row_number)] = round2(reporting_period_data['subtotals'][i], 2) |
|
576 | ws[col + str(current_row_number)].border = f_border |
|
577 | ||
578 | current_row_number += 2 |
|
579 | ||
580 | for i in range(0, reporting_period_data_ca_len): |
|
581 | line = LineChart() |
|
582 | line.title = _('Base Period Consumption') + ' / ' \ |
|
583 | + _('Reporting Period Consumption') + ' - ' \ |
|
584 | + reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")" |
|
585 | labels = Reference(ws, min_col=2 + base_period_data_ca_len + 1, |
|
586 | min_row=table_start_row_number + 1, |
|
587 | max_row=table_start_row_number + len(reporting_period_timestamps[0])) |
|
588 | base_line_data = Reference(ws, min_col=3 + i, |
|
589 | min_row=table_start_row_number, |
|
590 | max_row=table_start_row_number + len(reporting_period_timestamps[0])) |
|
591 | reporting_line_data = Reference(ws, min_col=3 + base_period_data_ca_len + 1 + i, |
|
592 | min_row=table_start_row_number, |
|
593 | max_row=table_start_row_number + len(reporting_period_timestamps[0])) |
|
594 | line.add_data(base_line_data, titles_from_data=True) |
|
595 | line.add_data(reporting_line_data, titles_from_data=True) |
|
596 | line.set_categories(labels) |
|
597 | for j in range(len(line.series)): |
|
598 | line.series[j].marker.symbol = "auto" |
|
599 | line.series[j].smooth = True |
|
600 | line.x_axis.crosses = 'min' |
|
601 | line.height = 8.25 |
|
602 | line.width = 24 |
|
603 | chart_col = 'B' |
|
604 | chart_cell = chart_col + str(chart_start_row_number) |
|
605 | chart_start_row_number += 6 |
|
606 | ws.add_chart(line, chart_cell) |
|
607 | ||
608 | #################################################################################################################### |
|
609 | current_sheet_parameters_row_number = chart_start_row_number + 1 |
|
610 | if 'parameters' not in report.keys() or \ |
|
611 | report['parameters'] is None or \ |
|
612 | 'names' not in report['parameters'].keys() or \ |
|
613 | report['parameters']['names'] is None or \ |
|
614 | len(report['parameters']['names']) == 0 or \ |
|
615 | 'timestamps' not in report['parameters'].keys() or \ |
|
616 | report['parameters']['timestamps'] is None or \ |
|
617 | len(report['parameters']['timestamps']) == 0 or \ |
|
618 | 'values' not in report['parameters'].keys() or \ |
|
619 | report['parameters']['values'] is None or \ |
|
620 | len(report['parameters']['values']) == 0 or \ |
|
621 | timestamps_data_all_equal_0(report['parameters']['timestamps']): |
|
622 | pass |
|
623 | else: |
|
624 | ################################################################################################################ |
|
625 | # new worksheet |
|
626 | ################################################################################################################ |
|
627 | ||
628 | parameters_data = report['parameters'] |
|
629 | ||
630 | parameters_names_len = len(parameters_data['names']) |
|
631 | ||
632 | file_name = (re.sub(r'[^A-Z]', '', ws.title)) + '_' |
|
633 | parameters_ws = wb.create_sheet(file_name + _('Parameters')) |
|
634 | ||
635 | parameters_timestamps_data_max_len = \ |
|
636 | get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps'])) |
|
637 | ||
638 | # Row height |
|
639 | parameters_ws.row_dimensions[1].height = 102 |
|
640 | for i in range(2, 7 + 1): |
|
641 | parameters_ws.row_dimensions[i].height = 42 |
|
642 | ||
643 | for i in range(8, parameters_timestamps_data_max_len + 10): |
|
644 | parameters_ws.row_dimensions[i].height = 60 |
|
645 | ||
646 | # Col width |
|
647 | parameters_ws.column_dimensions['A'].width = 1.5 |
|
648 | ||
649 | parameters_ws.column_dimensions['B'].width = 25.0 |
|
650 | ||
651 | for i in range(3, 12 + parameters_names_len * 3): |
|
652 | parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0 |
|
653 | ||
654 | # Img |
|
655 | img = Image("excelexporters/myems.png") |
|
656 | parameters_ws.add_image(img, 'A1') |
|
657 | ||
658 | # Title |
|
659 | parameters_ws['B3'].alignment = b_r_alignment |
|
660 | parameters_ws['B3'] = _('Name') + ':' |
|
661 | parameters_ws['C3'].border = b_border |
|
662 | parameters_ws['C3'].alignment = b_c_alignment |
|
663 | parameters_ws['C3'] = name |
|
664 | ||
665 | parameters_ws['D3'].alignment = b_r_alignment |
|
666 | parameters_ws['D3'] = _('Period Type') + ':' |
|
667 | parameters_ws['E3'].border = b_border |
|
668 | parameters_ws['E3'].alignment = b_c_alignment |
|
669 | parameters_ws['E3'] = period_type |
|
670 | ||
671 | parameters_ws['B4'].alignment = b_r_alignment |
|
672 | parameters_ws['B4'] = _('Reporting Start Datetime') + ':' |
|
673 | parameters_ws['C4'].border = b_border |
|
674 | parameters_ws['C4'].alignment = b_c_alignment |
|
675 | parameters_ws['C4'] = reporting_start_datetime_local |
|
676 | ||
677 | parameters_ws['D4'].alignment = b_r_alignment |
|
678 | parameters_ws['D4'] = _('Reporting End Datetime') + ':' |
|
679 | parameters_ws['E4'].border = b_border |
|
680 | parameters_ws['E4'].alignment = b_c_alignment |
|
681 | parameters_ws['E4'] = reporting_end_datetime_local |
|
682 | ||
683 | parameters_ws_current_row_number = 6 |
|
684 | ||
685 | parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font |
|
686 | parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' ' + _('Parameters') |
|
687 | ||
688 | parameters_ws_current_row_number += 1 |
|
689 | ||
690 | parameters_table_start_row_number = parameters_ws_current_row_number |
|
691 | ||
692 | parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80 |
|
693 | ||
694 | parameters_ws_current_row_number += 1 |
|
695 | ||
696 | table_current_col_number = 2 |
|
697 | ||
698 | for i in range(0, parameters_names_len): |
|
699 | ||
700 | if len(parameters_data['timestamps'][i]) == 0: |
|
701 | continue |
|
702 | ||
703 | col = format_cell.get_column_letter(table_current_col_number) |
|
704 | ||
705 | parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill |
|
706 | parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border |
|
707 | ||
708 | col = format_cell.get_column_letter(table_current_col_number + 1) |
|
709 | ||
710 | parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill |
|
711 | parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border |
|
712 | parameters_ws[col + str(parameters_ws_current_row_number - 1)].font = name_font |
|
713 | parameters_ws[col + str(parameters_ws_current_row_number - 1)].alignment = c_c_alignment |
|
714 | parameters_ws[col + str(parameters_ws_current_row_number - 1)] = parameters_data['names'][i] |
|
715 | ||
716 | table_current_row_number = parameters_ws_current_row_number |
|
717 | ||
718 | for j, value in enumerate(list(parameters_data['timestamps'][i])): |
|
719 | col = format_cell.get_column_letter(table_current_col_number) |
|
720 | ||
721 | parameters_ws[col + str(table_current_row_number)].border = f_border |
|
722 | parameters_ws[col + str(table_current_row_number)].font = title_font |
|
723 | parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment |
|
724 | parameters_ws[col + str(table_current_row_number)] = value |
|
725 | ||
726 | col = format_cell.get_column_letter(table_current_col_number + 1) |
|
727 | ||
728 | parameters_ws[col + str(table_current_row_number)].border = f_border |
|
729 | parameters_ws[col + str(table_current_row_number)].font = title_font |
|
730 | parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment |
|
731 | parameters_ws[col + str(table_current_row_number)] = round2(parameters_data['values'][i][j], 2) |
|
732 | ||
733 | table_current_row_number += 1 |
|
734 | ||
735 | table_current_col_number = table_current_col_number + 3 |
|
736 | ||
737 | ################################################################################################################ |
|
738 | # parameters chart and parameters table |
|
739 | ################################################################################################################ |
|
740 | ||
741 | ws['B' + str(current_sheet_parameters_row_number)].font = title_font |
|
742 | ws['B' + str(current_sheet_parameters_row_number)] = name + ' ' + _('Parameters') |
|
743 | ||
744 | current_sheet_parameters_row_number += 1 |
|
745 | ||
746 | chart_start_row_number = current_sheet_parameters_row_number |
|
747 | ||
748 | col_index = 0 |
|
749 | ||
750 | for i in range(0, parameters_names_len): |
|
751 | ||
752 | if len(parameters_data['timestamps'][i]) == 0: |
|
753 | continue |
|
754 | ||
755 | line = LineChart() |
|
756 | data_col = 3 + col_index * 3 |
|
757 | labels_col = 2 + col_index * 3 |
|
758 | col_index += 1 |
|
759 | line.title = _('Parameters') + ' - ' + \ |
|
760 | parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value |
|
761 | labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1, |
|
762 | max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number)) |
|
763 | line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number, |
|
764 | max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number)) |
|
765 | line.add_data(line_data, titles_from_data=True) |
|
766 | line.set_categories(labels) |
|
767 | line_data = line.series[0] |
|
768 | line_data.marker.symbol = "auto" |
|
769 | line_data.smooth = True |
|
770 | line.x_axis.crosses = 'min' |
|
771 | line.height = 8.25 |
|
772 | line.width = 24 |
|
773 | chart_col = 'B' |
|
774 | chart_cell = chart_col + str(chart_start_row_number) |
|
775 | chart_start_row_number += 6 |
|
776 | ws.add_chart(line, chart_cell) |
|
777 | ||
778 | current_sheet_parameters_row_number = chart_start_row_number |
|
779 | ||
780 | current_sheet_parameters_row_number += 1 |
|
781 | ||
782 | filename = str(uuid.uuid4()) + '.xlsx' |
|
783 | wb.save(filename) |
|
784 | ||
785 | return filename |
|
786 | ||
787 | ||
788 | def group_by_category(category_list): |
@@ 69-785 (lines=717) @@ | ||
66 | return base64_message |
|
67 | ||
68 | ||
69 | def generate_excel(report, |
|
70 | name, |
|
71 | base_period_start_datetime_local, |
|
72 | base_period_end_datetime_local, |
|
73 | reporting_start_datetime_local, |
|
74 | reporting_end_datetime_local, |
|
75 | period_type, |
|
76 | language): |
|
77 | ||
78 | trans = get_translation(language) |
|
79 | trans.install() |
|
80 | _ = trans.gettext |
|
81 | ||
82 | wb = Workbook() |
|
83 | ws = wb.active |
|
84 | ws.title = "StoreEnergyItem" |
|
85 | ||
86 | # Row height |
|
87 | ws.row_dimensions[1].height = 102 |
|
88 | for i in range(2, 2000 + 1): |
|
89 | ws.row_dimensions[i].height = 42 |
|
90 | ||
91 | # Col width |
|
92 | ws.column_dimensions['A'].width = 1.5 |
|
93 | ||
94 | ws.column_dimensions['B'].width = 25.0 |
|
95 | ||
96 | for i in range(ord('C'), ord('Z')): |
|
97 | ws.column_dimensions[chr(i)].width = 15.0 |
|
98 | ||
99 | # Font |
|
100 | name_font = Font(name='Arial', size=15, bold=True) |
|
101 | title_font = Font(name='Arial', size=15, bold=True) |
|
102 | ||
103 | table_fill = PatternFill(fill_type='solid', fgColor='90ee90') |
|
104 | f_border = Border(left=Side(border_style='medium'), |
|
105 | right=Side(border_style='medium'), |
|
106 | bottom=Side(border_style='medium'), |
|
107 | top=Side(border_style='medium') |
|
108 | ) |
|
109 | b_border = Border( |
|
110 | bottom=Side(border_style='medium'), |
|
111 | ) |
|
112 | ||
113 | b_c_alignment = Alignment(vertical='bottom', |
|
114 | horizontal='center', |
|
115 | text_rotation=0, |
|
116 | wrap_text=True, |
|
117 | shrink_to_fit=False, |
|
118 | indent=0) |
|
119 | c_c_alignment = Alignment(vertical='center', |
|
120 | horizontal='center', |
|
121 | text_rotation=0, |
|
122 | wrap_text=True, |
|
123 | shrink_to_fit=False, |
|
124 | indent=0) |
|
125 | b_r_alignment = Alignment(vertical='bottom', |
|
126 | horizontal='right', |
|
127 | text_rotation=0, |
|
128 | wrap_text=True, |
|
129 | shrink_to_fit=False, |
|
130 | indent=0) |
|
131 | # Img |
|
132 | img = Image("excelexporters/myems.png") |
|
133 | ws.add_image(img, 'A1') |
|
134 | ||
135 | # Title |
|
136 | ws['B3'].alignment = b_r_alignment |
|
137 | ws['B3'] = _('Name') + ':' |
|
138 | ws['C3'].border = b_border |
|
139 | ws['C3'].alignment = b_c_alignment |
|
140 | ws['C3'] = name |
|
141 | ||
142 | ws['D3'].alignment = b_r_alignment |
|
143 | ws['D3'] = _('Period Type') + ':' |
|
144 | ws['E3'].border = b_border |
|
145 | ws['E3'].alignment = b_c_alignment |
|
146 | ws['E3'] = period_type |
|
147 | ||
148 | ws['B4'].alignment = b_r_alignment |
|
149 | ws['B4'] = _('Reporting Start Datetime') + ':' |
|
150 | ws['C4'].border = b_border |
|
151 | ws['C4'].alignment = b_c_alignment |
|
152 | ws['C4'] = reporting_start_datetime_local |
|
153 | ||
154 | ws['D4'].alignment = b_r_alignment |
|
155 | ws['D4'] = _('Reporting End Datetime') + ':' |
|
156 | ws['E4'].border = b_border |
|
157 | ws['E4'].alignment = b_c_alignment |
|
158 | ws['E4'] = reporting_end_datetime_local |
|
159 | ||
160 | is_base_period_timestamp_exists_flag = is_base_period_timestamp_exists(report['base_period']) |
|
161 | ||
162 | if is_base_period_timestamp_exists_flag: |
|
163 | ws['B5'].alignment = b_r_alignment |
|
164 | ws['B5'] = _('Base Period Start Datetime') + ':' |
|
165 | ws['C5'].border = b_border |
|
166 | ws['C5'].alignment = b_c_alignment |
|
167 | ws['C5'] = base_period_start_datetime_local |
|
168 | ||
169 | ws['D5'].alignment = b_r_alignment |
|
170 | ws['D5'] = _('Base Period End Datetime') + ':' |
|
171 | ws['E5'].border = b_border |
|
172 | ws['E5'].alignment = b_c_alignment |
|
173 | ws['E5'] = base_period_end_datetime_local |
|
174 | ||
175 | if "reporting_period" not in report.keys() or \ |
|
176 | "names" not in report['reporting_period'].keys() or len(report['reporting_period']['names']) == 0: |
|
177 | filename = str(uuid.uuid4()) + '.xlsx' |
|
178 | wb.save(filename) |
|
179 | ||
180 | return filename |
|
181 | ||
182 | #################################################################################################################### |
|
183 | current_row_number = 7 |
|
184 | reporting_period_data = report['reporting_period'] |
|
185 | if "names" not in reporting_period_data.keys() or \ |
|
186 | reporting_period_data['names'] is None or \ |
|
187 | len(reporting_period_data['names']) == 0: |
|
188 | pass |
|
189 | else: |
|
190 | ws['B' + str(current_row_number)].font = title_font |
|
191 | ws['B' + str(current_row_number)] = name + ' ' + _('Reporting Period Consumption') |
|
192 | ||
193 | current_row_number += 1 |
|
194 | ||
195 | category = reporting_period_data['names'] |
|
196 | ca_len = len(category) |
|
197 | ||
198 | ws.row_dimensions[current_row_number].height = 60 |
|
199 | ws['B' + str(current_row_number)].fill = table_fill |
|
200 | ws['B' + str(current_row_number)].border = f_border |
|
201 | ||
202 | col = 'C' |
|
203 | ||
204 | for i in range(0, ca_len): |
|
205 | ws[col + str(current_row_number)].fill = table_fill |
|
206 | ws[col + str(current_row_number)].font = name_font |
|
207 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
208 | ws[col + str(current_row_number)].border = f_border |
|
209 | ws[col + str(current_row_number)] = \ |
|
210 | reporting_period_data['names'][i] + " " + reporting_period_data['energy_category_names'][i] + \ |
|
211 | " (" + reporting_period_data['units'][i] + ")" |
|
212 | ||
213 | col = chr(ord(col) + 1) |
|
214 | ||
215 | current_row_number += 1 |
|
216 | ||
217 | ws['B' + str(current_row_number)].font = title_font |
|
218 | ws['B' + str(current_row_number)].alignment = c_c_alignment |
|
219 | ws['B' + str(current_row_number)].border = f_border |
|
220 | ws['B' + str(current_row_number)] = _('Per Unit Area') |
|
221 | ||
222 | col = 'C' |
|
223 | ||
224 | for i in range(0, ca_len): |
|
225 | ws[col + str(current_row_number)].font = name_font |
|
226 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
227 | ws[col + str(current_row_number)].border = f_border |
|
228 | ws[col + str(current_row_number)] = round2(reporting_period_data['subtotals'][i], 2) |
|
229 | ||
230 | col = chr(ord(col) + 1) |
|
231 | ||
232 | current_row_number += 1 |
|
233 | ||
234 | ws['B' + str(current_row_number)].font = title_font |
|
235 | ws['B' + str(current_row_number)].alignment = c_c_alignment |
|
236 | ws['B' + str(current_row_number)].border = f_border |
|
237 | ws['B' + str(current_row_number)] = _('Per Unit Area') |
|
238 | ||
239 | col = 'C' |
|
240 | ||
241 | for i in range(0, ca_len): |
|
242 | ws[col + str(current_row_number)].font = name_font |
|
243 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
244 | ws[col + str(current_row_number)].border = f_border |
|
245 | ws[col + str(current_row_number)] = round2(reporting_period_data['subtotals_per_unit_area'][i], 2) |
|
246 | ||
247 | col = chr(ord(col) + 1) |
|
248 | ||
249 | current_row_number += 1 |
|
250 | ||
251 | ws['B' + str(current_row_number)].font = title_font |
|
252 | ws['B' + str(current_row_number)].alignment = c_c_alignment |
|
253 | ws['B' + str(current_row_number)].border = f_border |
|
254 | ws['B' + str(current_row_number)] = _('Increment Rate') |
|
255 | ||
256 | col = 'C' |
|
257 | ||
258 | for i in range(0, ca_len): |
|
259 | ws[col + str(current_row_number)].font = name_font |
|
260 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
261 | ws[col + str(current_row_number)].border = f_border |
|
262 | ws[col + str(current_row_number)] = str( |
|
263 | round2(reporting_period_data['increment_rates'][i] * 100, 2)) + '%' \ |
|
264 | if reporting_period_data['increment_rates'][i] is not None else '-' |
|
265 | ||
266 | col = chr(ord(col) + 1) |
|
267 | ||
268 | current_row_number += 2 |
|
269 | ||
270 | category_dict = group_by_category(reporting_period_data['energy_category_names']) |
|
271 | ||
272 | for category_dict_name, category_dict_values in category_dict.items(): |
|
273 | ||
274 | ws['B' + str(current_row_number)].font = title_font |
|
275 | ws['B' + str(current_row_number)] = name + ' ' + category_dict_name + ' ' + \ |
|
276 | '(' + reporting_period_data['units'][category_dict_values[0]] + ') by Energy Item' |
|
277 | ||
278 | current_row_number += 1 |
|
279 | table_start_row_number = current_row_number |
|
280 | ||
281 | ws['B' + str(current_row_number)].fill = table_fill |
|
282 | ws['B' + str(current_row_number)].border = f_border |
|
283 | ||
284 | ws['C' + str(current_row_number)].font = name_font |
|
285 | ws['C' + str(current_row_number)].fill = table_fill |
|
286 | ws['C' + str(current_row_number)].alignment = c_c_alignment |
|
287 | ws['C' + str(current_row_number)].border = f_border |
|
288 | ws['C' + str(current_row_number)] = _('Per Unit Area') |
|
289 | ||
290 | current_row_number += 1 |
|
291 | ||
292 | for i in category_dict_values: |
|
293 | ws['B' + str(current_row_number)].font = title_font |
|
294 | ws['B' + str(current_row_number)].alignment = c_c_alignment |
|
295 | ws['B' + str(current_row_number)].border = f_border |
|
296 | ws['B' + str(current_row_number)] = \ |
|
297 | reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")" |
|
298 | ws['C' + str(current_row_number)].font = name_font |
|
299 | ws['C' + str(current_row_number)].alignment = c_c_alignment |
|
300 | ws['C' + str(current_row_number)].border = f_border |
|
301 | ws['C' + str(current_row_number)] = round2(reporting_period_data['subtotals'][i], 3) |
|
302 | ||
303 | current_row_number += 1 |
|
304 | ||
305 | table_end_row_number = current_row_number - 1 |
|
306 | ||
307 | pie = PieChart() |
|
308 | pie.title = name + ' ' + category_dict_name + ' ' + \ |
|
309 | '(' + reporting_period_data['units'][category_dict_values[0]] + ') by Energy Item' |
|
310 | labels = Reference(ws, min_col=2, min_row=table_start_row_number + 1, max_row=table_end_row_number) |
|
311 | pie_data = Reference(ws, min_col=3, min_row=table_start_row_number, max_row=table_end_row_number) |
|
312 | pie.add_data(pie_data, titles_from_data=True) |
|
313 | pie.set_categories(labels) |
|
314 | pie.height = 6.6 |
|
315 | pie.width = 9 |
|
316 | s1 = pie.series[0] |
|
317 | s1.dLbls = DataLabelList() |
|
318 | s1.dLbls.showCatName = False |
|
319 | s1.dLbls.showVal = False |
|
320 | s1.dLbls.showPercent = True |
|
321 | ws.add_chart(pie, 'D' + str(table_start_row_number)) |
|
322 | ||
323 | if len(category_dict_values) < 4: |
|
324 | current_row_number = current_row_number - len(category_dict_values) + 4 |
|
325 | ||
326 | current_row_number += 1 |
|
327 | ||
328 | #################################################################################################################### |
|
329 | chart_start_row_number = current_row_number |
|
330 | ||
331 | has_values_data = True |
|
332 | has_timestamps_data = True |
|
333 | ||
334 | if 'values' not in reporting_period_data.keys() or \ |
|
335 | reporting_period_data['values'] is None or \ |
|
336 | len(reporting_period_data['values']) == 0: |
|
337 | has_values_data = False |
|
338 | ||
339 | if 'timestamps' not in reporting_period_data.keys() or \ |
|
340 | reporting_period_data['timestamps'] is None or \ |
|
341 | len(reporting_period_data['timestamps']) == 0 or \ |
|
342 | len(reporting_period_data['timestamps'][0]) == 0: |
|
343 | has_timestamps_data = False |
|
344 | ||
345 | if not is_base_period_timestamp_exists_flag: |
|
346 | if has_values_data and has_timestamps_data: |
|
347 | ca_len = len(reporting_period_data['names']) |
|
348 | time = reporting_period_data['timestamps'][0] |
|
349 | real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps']) |
|
350 | ws['B' + str(current_row_number)].font = title_font |
|
351 | ws['B' + str(current_row_number)] = name + ' ' + _('Detailed Data') |
|
352 | ||
353 | current_row_number += 1 |
|
354 | ||
355 | chart_start_row_number = current_row_number |
|
356 | ||
357 | # 1: Stand for blank line 2: Stand for title |
|
358 | current_row_number += ca_len * 6 + real_timestamps_len * 6 + 1 + 2 |
|
359 | table_start_row_number = current_row_number |
|
360 | ||
361 | ws.row_dimensions[current_row_number].height = 60 |
|
362 | ws['B' + str(current_row_number)].fill = table_fill |
|
363 | ws['B' + str(current_row_number)].font = title_font |
|
364 | ws['B' + str(current_row_number)].alignment = c_c_alignment |
|
365 | ws['B' + str(current_row_number)].border = f_border |
|
366 | ws['B' + str(current_row_number)] = _('Datetime') |
|
367 | ||
368 | col = 'C' |
|
369 | ||
370 | for i in range(0, ca_len): |
|
371 | ws[col + str(current_row_number)].fill = table_fill |
|
372 | ws[col + str(current_row_number)].font = title_font |
|
373 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
374 | ws[col + str(current_row_number)].border = f_border |
|
375 | ws[col + str(current_row_number)] = \ |
|
376 | reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")" |
|
377 | col = chr(ord(col) + 1) |
|
378 | ||
379 | current_row_number += 1 |
|
380 | ||
381 | for i in range(0, len(time)): |
|
382 | ws['B' + str(current_row_number)].font = title_font |
|
383 | ws['B' + str(current_row_number)].alignment = c_c_alignment |
|
384 | ws['B' + str(current_row_number)].border = f_border |
|
385 | ws['B' + str(current_row_number)] = time[i] |
|
386 | ||
387 | col = 'C' |
|
388 | for j in range(0, ca_len): |
|
389 | ws[col + str(current_row_number)].font = title_font |
|
390 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
391 | ws[col + str(current_row_number)].border = f_border |
|
392 | ws[col + str(current_row_number)] = round2(reporting_period_data['values'][j][i], 2) \ |
|
393 | if reporting_period_data['values'][j][i] is not None else 0.00 |
|
394 | col = chr(ord(col) + 1) |
|
395 | ||
396 | current_row_number += 1 |
|
397 | ||
398 | table_end_row_number = current_row_number - 1 |
|
399 | ||
400 | ws['B' + str(current_row_number)].font = title_font |
|
401 | ws['B' + str(current_row_number)].alignment = c_c_alignment |
|
402 | ws['B' + str(current_row_number)].border = f_border |
|
403 | ws['B' + str(current_row_number)] = _('Subtotal') |
|
404 | ||
405 | col = 'C' |
|
406 | ||
407 | for i in range(0, ca_len): |
|
408 | ws[col + str(current_row_number)].font = title_font |
|
409 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
410 | ws[col + str(current_row_number)].border = f_border |
|
411 | ws[col + str(current_row_number)] = round2(reporting_period_data['subtotals'][i], 2) |
|
412 | col = chr(ord(col) + 1) |
|
413 | ||
414 | current_row_number += 2 |
|
415 | ||
416 | for i in range(0, ca_len): |
|
417 | line = LineChart() |
|
418 | line.title = _('Reporting Period Consumption') + ' - ' \ |
|
419 | + reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")" |
|
420 | labels = Reference(ws, min_col=2, |
|
421 | min_row=table_start_row_number + 1, |
|
422 | max_row=table_end_row_number) |
|
423 | reporting_line_data = Reference(ws, min_col=3 + i, |
|
424 | min_row=table_start_row_number, |
|
425 | max_row=table_end_row_number) |
|
426 | line.add_data(reporting_line_data, titles_from_data=True) |
|
427 | line.set_categories(labels) |
|
428 | reporting_line_data = line.series[0] |
|
429 | reporting_line_data.marker.symbol = "auto" |
|
430 | reporting_line_data.smooth = True |
|
431 | line.x_axis.crosses = 'min' |
|
432 | line.height = 8.25 |
|
433 | line.width = 24 |
|
434 | chart_col = 'B' |
|
435 | chart_cell = chart_col + str(chart_start_row_number) |
|
436 | chart_start_row_number += 6 |
|
437 | ws.add_chart(line, chart_cell) |
|
438 | ||
439 | else: |
|
440 | if has_values_data and has_timestamps_data: |
|
441 | base_period_data = report['base_period'] |
|
442 | reporting_period_data = report['reporting_period'] |
|
443 | base_period_timestamps = base_period_data['timestamps'] |
|
444 | reporting_period_timestamps = reporting_period_data['timestamps'] |
|
445 | # Tip: |
|
446 | # base_period_data['names'] == reporting_period_data['names'] |
|
447 | # base_period_data['units'] == reporting_period_data['units'] |
|
448 | base_period_data_ca_len = len(base_period_data['names']) |
|
449 | reporting_period_data_ca_len = len(reporting_period_data['names']) |
|
450 | real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps']) |
|
451 | ws['B' + str(current_row_number)].font = title_font |
|
452 | ws['B' + str(current_row_number)] = name + ' ' + _('Detailed Data') |
|
453 | current_row_number += 1 |
|
454 | ||
455 | chart_start_row_number = current_row_number |
|
456 | ||
457 | # 1: Stand for blank line 2: Stand for title |
|
458 | current_row_number += reporting_period_data_ca_len * 6 + real_timestamps_len * 6 + 1 + 2 |
|
459 | table_start_row_number = current_row_number |
|
460 | ||
461 | ws.row_dimensions[current_row_number].height = 60 |
|
462 | current_col_number = 2 |
|
463 | col = format_cell.get_column_letter(current_col_number) |
|
464 | ws[col + str(current_row_number)].fill = table_fill |
|
465 | ws[col + str(current_row_number)].font = title_font |
|
466 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
467 | ws[col + str(current_row_number)].border = f_border |
|
468 | ws[col + str(current_row_number)] = _('Base Period') + " - " + _('Datetime') |
|
469 | ||
470 | for i in range(0, base_period_data_ca_len): |
|
471 | current_col_number += 1 |
|
472 | col = format_cell.get_column_letter(current_col_number) |
|
473 | ||
474 | ws[col + str(current_row_number)].fill = table_fill |
|
475 | ws[col + str(current_row_number)].font = title_font |
|
476 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
477 | ws[col + str(current_row_number)] = _('Base Period') + " - " + base_period_data['names'][i] + \ |
|
478 | " (" + base_period_data['units'][i] + ")" |
|
479 | ws[col + str(current_row_number)].border = f_border |
|
480 | ||
481 | current_col_number += 1 |
|
482 | col = format_cell.get_column_letter(current_col_number) |
|
483 | ||
484 | ws[col + str(current_row_number)].fill = table_fill |
|
485 | ws[col + str(current_row_number)].font = title_font |
|
486 | ws[col + str(current_row_number)].border = f_border |
|
487 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
488 | ws[col + str(current_row_number)] = _('Reporting Period') + " - " + _('Datetime') |
|
489 | ||
490 | for i in range(0, reporting_period_data_ca_len): |
|
491 | current_col_number += 1 |
|
492 | col = format_cell.get_column_letter(current_col_number) |
|
493 | ws[col + str(current_row_number)].fill = table_fill |
|
494 | ws[col + str(current_row_number)].font = title_font |
|
495 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
496 | ws[col + str(current_row_number)] = _('Reporting Period') + " - " \ |
|
497 | + reporting_period_data['names'][i] + " (" + \ |
|
498 | reporting_period_data['units'][i] + ")" |
|
499 | ws[col + str(current_row_number)].border = f_border |
|
500 | ||
501 | current_row_number += 1 |
|
502 | ||
503 | max_timestamps_len = len(base_period_timestamps[0]) \ |
|
504 | if len(base_period_timestamps[0]) >= len(reporting_period_timestamps[0]) \ |
|
505 | else len(reporting_period_timestamps[0]) |
|
506 | ||
507 | for i in range(0, max_timestamps_len): |
|
508 | current_col_number = 2 |
|
509 | col = format_cell.get_column_letter(current_col_number) |
|
510 | ws[col + str(current_row_number)].font = title_font |
|
511 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
512 | ws[col + str(current_row_number)] = base_period_timestamps[0][i] \ |
|
513 | if i < len(base_period_timestamps[0]) else None |
|
514 | ws[col + str(current_row_number)].border = f_border |
|
515 | ||
516 | for j in range(0, base_period_data_ca_len): |
|
517 | current_col_number += 1 |
|
518 | col = format_cell.get_column_letter(current_col_number) |
|
519 | ||
520 | ws[col + str(current_row_number)].font = title_font |
|
521 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
522 | ws[col + str(current_row_number)] = round2(base_period_data['values'][j][i], 2) \ |
|
523 | if i < len(base_period_data['values'][j]) else None |
|
524 | ws[col + str(current_row_number)].border = f_border |
|
525 | current_col_number += 1 |
|
526 | col = format_cell.get_column_letter(current_col_number) |
|
527 | ||
528 | ws[col + str(current_row_number)].font = title_font |
|
529 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
530 | ws[col + str(current_row_number)] = reporting_period_timestamps[0][i] \ |
|
531 | if i < len(reporting_period_timestamps[0]) else None |
|
532 | ws[col + str(current_row_number)].border = f_border |
|
533 | ||
534 | for j in range(0, reporting_period_data_ca_len): |
|
535 | current_col_number += 1 |
|
536 | col = format_cell.get_column_letter(current_col_number) |
|
537 | ||
538 | ws[col + str(current_row_number)].font = title_font |
|
539 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
540 | ws[col + str(current_row_number)] = round2(reporting_period_data['values'][j][i], 2) \ |
|
541 | if i < len(reporting_period_data['values'][j]) else None |
|
542 | ws[col + str(current_row_number)].border = f_border |
|
543 | ||
544 | current_row_number += 1 |
|
545 | ||
546 | current_col_number = 2 |
|
547 | col = format_cell.get_column_letter(current_col_number) |
|
548 | ||
549 | ws[col + str(current_row_number)].font = title_font |
|
550 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
551 | ws[col + str(current_row_number)] = _('Subtotal') |
|
552 | ws[col + str(current_row_number)].border = f_border |
|
553 | ||
554 | for i in range(0, base_period_data_ca_len): |
|
555 | current_col_number += 1 |
|
556 | col = format_cell.get_column_letter(current_col_number) |
|
557 | ws[col + str(current_row_number)].font = title_font |
|
558 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
559 | ws[col + str(current_row_number)] = round2(base_period_data['subtotals'][i], 2) |
|
560 | ws[col + str(current_row_number)].border = f_border |
|
561 | ||
562 | current_col_number += 1 |
|
563 | col = format_cell.get_column_letter(current_col_number) |
|
564 | ||
565 | ws[col + str(current_row_number)].font = title_font |
|
566 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
567 | ws[col + str(current_row_number)] = _('Subtotal') |
|
568 | ws[col + str(current_row_number)].border = f_border |
|
569 | ||
570 | for i in range(0, reporting_period_data_ca_len): |
|
571 | current_col_number += 1 |
|
572 | col = format_cell.get_column_letter(current_col_number) |
|
573 | ws[col + str(current_row_number)].font = title_font |
|
574 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
575 | ws[col + str(current_row_number)] = round2(reporting_period_data['subtotals'][i], 2) |
|
576 | ws[col + str(current_row_number)].border = f_border |
|
577 | ||
578 | current_row_number += 2 |
|
579 | ||
580 | for i in range(0, reporting_period_data_ca_len): |
|
581 | line = LineChart() |
|
582 | line.title = _('Base Period Consumption') + ' / ' \ |
|
583 | + _('Reporting Period Consumption') + ' - ' \ |
|
584 | + reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")" |
|
585 | labels = Reference(ws, min_col=2 + base_period_data_ca_len + 1, |
|
586 | min_row=table_start_row_number + 1, |
|
587 | max_row=table_start_row_number + len(reporting_period_timestamps[0])) |
|
588 | base_line_data = Reference(ws, min_col=3 + i, |
|
589 | min_row=table_start_row_number, |
|
590 | max_row=table_start_row_number + len(reporting_period_timestamps[0])) |
|
591 | reporting_line_data = Reference(ws, min_col=3 + base_period_data_ca_len + 1 + i, |
|
592 | min_row=table_start_row_number, |
|
593 | max_row=table_start_row_number + len(reporting_period_timestamps[0])) |
|
594 | line.add_data(base_line_data, titles_from_data=True) |
|
595 | line.add_data(reporting_line_data, titles_from_data=True) |
|
596 | line.set_categories(labels) |
|
597 | for j in range(len(line.series)): |
|
598 | line.series[j].marker.symbol = "auto" |
|
599 | line.series[j].smooth = True |
|
600 | line.x_axis.crosses = 'min' |
|
601 | line.height = 8.25 |
|
602 | line.width = 24 |
|
603 | chart_col = 'B' |
|
604 | chart_cell = chart_col + str(chart_start_row_number) |
|
605 | chart_start_row_number += 6 |
|
606 | ws.add_chart(line, chart_cell) |
|
607 | ||
608 | #################################################################################################################### |
|
609 | current_sheet_parameters_row_number = chart_start_row_number + 1 |
|
610 | if 'parameters' not in report.keys() or \ |
|
611 | report['parameters'] is None or \ |
|
612 | 'names' not in report['parameters'].keys() or \ |
|
613 | report['parameters']['names'] is None or \ |
|
614 | len(report['parameters']['names']) == 0 or \ |
|
615 | 'timestamps' not in report['parameters'].keys() or \ |
|
616 | report['parameters']['timestamps'] is None or \ |
|
617 | len(report['parameters']['timestamps']) == 0 or \ |
|
618 | 'values' not in report['parameters'].keys() or \ |
|
619 | report['parameters']['values'] is None or \ |
|
620 | len(report['parameters']['values']) == 0 or \ |
|
621 | timestamps_data_all_equal_0(report['parameters']['timestamps']): |
|
622 | pass |
|
623 | else: |
|
624 | ################################################################################################################ |
|
625 | # new worksheet |
|
626 | ################################################################################################################ |
|
627 | ||
628 | parameters_data = report['parameters'] |
|
629 | ||
630 | parameters_names_len = len(parameters_data['names']) |
|
631 | ||
632 | file_name = "Store"+re.sub(r'[^A-Z]', '', ws.title.strip('S')) + "_" |
|
633 | parameters_ws = wb.create_sheet(file_name + _('Parameters')) |
|
634 | ||
635 | parameters_timestamps_data_max_len = \ |
|
636 | get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps'])) |
|
637 | ||
638 | # Row height |
|
639 | parameters_ws.row_dimensions[1].height = 102 |
|
640 | for i in range(2, 7 + 1): |
|
641 | parameters_ws.row_dimensions[i].height = 42 |
|
642 | ||
643 | for i in range(8, parameters_timestamps_data_max_len + 10): |
|
644 | parameters_ws.row_dimensions[i].height = 60 |
|
645 | ||
646 | # Col width |
|
647 | parameters_ws.column_dimensions['A'].width = 1.5 |
|
648 | ||
649 | parameters_ws.column_dimensions['B'].width = 25.0 |
|
650 | ||
651 | for i in range(3, 12 + parameters_names_len * 3): |
|
652 | parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0 |
|
653 | ||
654 | # Img |
|
655 | img = Image("excelexporters/myems.png") |
|
656 | parameters_ws.add_image(img, 'A1') |
|
657 | ||
658 | # Title |
|
659 | parameters_ws['B3'].alignment = b_r_alignment |
|
660 | parameters_ws['B3'] = _('Name') + ':' |
|
661 | parameters_ws['C3'].border = b_border |
|
662 | parameters_ws['C3'].alignment = b_c_alignment |
|
663 | parameters_ws['C3'] = name |
|
664 | ||
665 | parameters_ws['D3'].alignment = b_r_alignment |
|
666 | parameters_ws['D3'] = _('Period Type') + ':' |
|
667 | parameters_ws['E3'].border = b_border |
|
668 | parameters_ws['E3'].alignment = b_c_alignment |
|
669 | parameters_ws['E3'] = period_type |
|
670 | ||
671 | parameters_ws['B4'].alignment = b_r_alignment |
|
672 | parameters_ws['B4'] = _('Reporting Start Datetime') + ':' |
|
673 | parameters_ws['C4'].border = b_border |
|
674 | parameters_ws['C4'].alignment = b_c_alignment |
|
675 | parameters_ws['C4'] = reporting_start_datetime_local |
|
676 | ||
677 | parameters_ws['D4'].alignment = b_r_alignment |
|
678 | parameters_ws['D4'] = _('Reporting End Datetime') + ':' |
|
679 | parameters_ws['E4'].border = b_border |
|
680 | parameters_ws['E4'].alignment = b_c_alignment |
|
681 | parameters_ws['E4'] = reporting_end_datetime_local |
|
682 | ||
683 | parameters_ws_current_row_number = 6 |
|
684 | ||
685 | parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font |
|
686 | parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' ' + _('Parameters') |
|
687 | ||
688 | parameters_ws_current_row_number += 1 |
|
689 | ||
690 | parameters_table_start_row_number = parameters_ws_current_row_number |
|
691 | ||
692 | parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80 |
|
693 | ||
694 | parameters_ws_current_row_number += 1 |
|
695 | ||
696 | table_current_col_number = 2 |
|
697 | ||
698 | for i in range(0, parameters_names_len): |
|
699 | ||
700 | if len(parameters_data['timestamps'][i]) == 0: |
|
701 | continue |
|
702 | ||
703 | col = format_cell.get_column_letter(table_current_col_number) |
|
704 | ||
705 | parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill |
|
706 | parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border |
|
707 | ||
708 | col = format_cell.get_column_letter(table_current_col_number + 1) |
|
709 | ||
710 | parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill |
|
711 | parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border |
|
712 | parameters_ws[col + str(parameters_ws_current_row_number - 1)].font = name_font |
|
713 | parameters_ws[col + str(parameters_ws_current_row_number - 1)].alignment = c_c_alignment |
|
714 | parameters_ws[col + str(parameters_ws_current_row_number - 1)] = parameters_data['names'][i] |
|
715 | ||
716 | table_current_row_number = parameters_ws_current_row_number |
|
717 | ||
718 | for j, value in enumerate(list(parameters_data['timestamps'][i])): |
|
719 | col = format_cell.get_column_letter(table_current_col_number) |
|
720 | ||
721 | parameters_ws[col + str(table_current_row_number)].border = f_border |
|
722 | parameters_ws[col + str(table_current_row_number)].font = title_font |
|
723 | parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment |
|
724 | parameters_ws[col + str(table_current_row_number)] = value |
|
725 | ||
726 | col = format_cell.get_column_letter(table_current_col_number + 1) |
|
727 | ||
728 | parameters_ws[col + str(table_current_row_number)].border = f_border |
|
729 | parameters_ws[col + str(table_current_row_number)].font = title_font |
|
730 | parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment |
|
731 | parameters_ws[col + str(table_current_row_number)] = round2(parameters_data['values'][i][j], 2) |
|
732 | ||
733 | table_current_row_number += 1 |
|
734 | ||
735 | table_current_col_number = table_current_col_number + 3 |
|
736 | ||
737 | ################################################################################################################ |
|
738 | # parameters chart and parameters table |
|
739 | ################################################################################################################ |
|
740 | ||
741 | ws['B' + str(current_sheet_parameters_row_number)].font = title_font |
|
742 | ws['B' + str(current_sheet_parameters_row_number)] = name + ' ' + _('Parameters') |
|
743 | ||
744 | current_sheet_parameters_row_number += 1 |
|
745 | ||
746 | chart_start_row_number = current_sheet_parameters_row_number |
|
747 | ||
748 | col_index = 0 |
|
749 | ||
750 | for i in range(0, parameters_names_len): |
|
751 | ||
752 | if len(parameters_data['timestamps'][i]) == 0: |
|
753 | continue |
|
754 | ||
755 | line = LineChart() |
|
756 | data_col = 3 + col_index * 3 |
|
757 | labels_col = 2 + col_index * 3 |
|
758 | col_index += 1 |
|
759 | line.title = _('Parameters') + ' - ' + \ |
|
760 | parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value |
|
761 | labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1, |
|
762 | max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number)) |
|
763 | line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number, |
|
764 | max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number)) |
|
765 | line.add_data(line_data, titles_from_data=True) |
|
766 | line.set_categories(labels) |
|
767 | line_data = line.series[0] |
|
768 | line_data.marker.symbol = "auto" |
|
769 | line_data.smooth = True |
|
770 | line.x_axis.crosses = 'min' |
|
771 | line.height = 8.25 |
|
772 | line.width = 24 |
|
773 | chart_col = 'B' |
|
774 | chart_cell = chart_col + str(chart_start_row_number) |
|
775 | chart_start_row_number += 6 |
|
776 | ws.add_chart(line, chart_cell) |
|
777 | ||
778 | current_sheet_parameters_row_number = chart_start_row_number |
|
779 | ||
780 | current_sheet_parameters_row_number += 1 |
|
781 | ||
782 | filename = str(uuid.uuid4()) + '.xlsx' |
|
783 | wb.save(filename) |
|
784 | ||
785 | return filename |
|
786 | ||
787 | ||
788 | def group_by_category(category_list): |
@@ 69-784 (lines=716) @@ | ||
66 | return base64_message |
|
67 | ||
68 | ||
69 | def generate_excel(report, |
|
70 | name, |
|
71 | base_period_start_datetime_local, |
|
72 | base_period_end_datetime_local, |
|
73 | reporting_start_datetime_local, |
|
74 | reporting_end_datetime_local, |
|
75 | period_type, |
|
76 | language): |
|
77 | ||
78 | trans = get_translation(language) |
|
79 | trans.install() |
|
80 | _ = trans.gettext |
|
81 | ||
82 | wb = Workbook() |
|
83 | ws = wb.active |
|
84 | ws.title = "TenantEnergyItem" |
|
85 | ||
86 | # Row height |
|
87 | ws.row_dimensions[1].height = 102 |
|
88 | for i in range(2, 2000 + 1): |
|
89 | ws.row_dimensions[i].height = 42 |
|
90 | ||
91 | # Col width |
|
92 | ws.column_dimensions['A'].width = 1.5 |
|
93 | ||
94 | ws.column_dimensions['B'].width = 25.0 |
|
95 | ||
96 | for i in range(ord('C'), ord('Z')): |
|
97 | ws.column_dimensions[chr(i)].width = 15.0 |
|
98 | ||
99 | # Font |
|
100 | name_font = Font(name='Arial', size=15, bold=True) |
|
101 | title_font = Font(name='Arial', size=15, bold=True) |
|
102 | ||
103 | table_fill = PatternFill(fill_type='solid', fgColor='90ee90') |
|
104 | f_border = Border(left=Side(border_style='medium'), |
|
105 | right=Side(border_style='medium'), |
|
106 | bottom=Side(border_style='medium'), |
|
107 | top=Side(border_style='medium') |
|
108 | ) |
|
109 | b_border = Border( |
|
110 | bottom=Side(border_style='medium'), |
|
111 | ) |
|
112 | ||
113 | b_c_alignment = Alignment(vertical='bottom', |
|
114 | horizontal='center', |
|
115 | text_rotation=0, |
|
116 | wrap_text=True, |
|
117 | shrink_to_fit=False, |
|
118 | indent=0) |
|
119 | c_c_alignment = Alignment(vertical='center', |
|
120 | horizontal='center', |
|
121 | text_rotation=0, |
|
122 | wrap_text=True, |
|
123 | shrink_to_fit=False, |
|
124 | indent=0) |
|
125 | b_r_alignment = Alignment(vertical='bottom', |
|
126 | horizontal='right', |
|
127 | text_rotation=0, |
|
128 | wrap_text=True, |
|
129 | shrink_to_fit=False, |
|
130 | indent=0) |
|
131 | # Img |
|
132 | img = Image("excelexporters/myems.png") |
|
133 | ws.add_image(img, 'A1') |
|
134 | ||
135 | # Title |
|
136 | ws['B3'].alignment = b_r_alignment |
|
137 | ws['B3'] = _('Name') + ':' |
|
138 | ws['C3'].border = b_border |
|
139 | ws['C3'].alignment = b_c_alignment |
|
140 | ws['C3'] = name |
|
141 | ||
142 | ws['D3'].alignment = b_r_alignment |
|
143 | ws['D3'] = _('Period Type') + ':' |
|
144 | ws['E3'].border = b_border |
|
145 | ws['E3'].alignment = b_c_alignment |
|
146 | ws['E3'] = period_type |
|
147 | ||
148 | ws['B4'].alignment = b_r_alignment |
|
149 | ws['B4'] = _('Reporting Start Datetime') + ':' |
|
150 | ws['C4'].border = b_border |
|
151 | ws['C4'].alignment = b_c_alignment |
|
152 | ws['C4'] = reporting_start_datetime_local |
|
153 | ||
154 | ws['D4'].alignment = b_r_alignment |
|
155 | ws['D4'] = _('Reporting End Datetime') + ':' |
|
156 | ws['E4'].border = b_border |
|
157 | ws['E4'].alignment = b_c_alignment |
|
158 | ws['E4'] = reporting_end_datetime_local |
|
159 | ||
160 | is_base_period_timestamp_exists_flag = is_base_period_timestamp_exists(report['base_period']) |
|
161 | ||
162 | if is_base_period_timestamp_exists_flag: |
|
163 | ws['B5'].alignment = b_r_alignment |
|
164 | ws['B5'] = _('Base Period Start Datetime') + ':' |
|
165 | ws['C5'].border = b_border |
|
166 | ws['C5'].alignment = b_c_alignment |
|
167 | ws['C5'] = base_period_start_datetime_local |
|
168 | ||
169 | ws['D5'].alignment = b_r_alignment |
|
170 | ws['D5'] = _('Base Period End Datetime') + ':' |
|
171 | ws['E5'].border = b_border |
|
172 | ws['E5'].alignment = b_c_alignment |
|
173 | ws['E5'] = base_period_end_datetime_local |
|
174 | ||
175 | if "reporting_period" not in report.keys() or \ |
|
176 | "names" not in report['reporting_period'].keys() or len(report['reporting_period']['names']) == 0: |
|
177 | filename = str(uuid.uuid4()) + '.xlsx' |
|
178 | wb.save(filename) |
|
179 | ||
180 | return filename |
|
181 | ||
182 | #################################################################################################################### |
|
183 | current_row_number = 7 |
|
184 | reporting_period_data = report['reporting_period'] |
|
185 | if "names" not in reporting_period_data.keys() or \ |
|
186 | reporting_period_data['names'] is None or \ |
|
187 | len(reporting_period_data['names']) == 0: |
|
188 | pass |
|
189 | else: |
|
190 | ws['B' + str(current_row_number)].font = title_font |
|
191 | ws['B' + str(current_row_number)] = name + ' ' + _('Reporting Period Consumption') |
|
192 | ||
193 | current_row_number += 1 |
|
194 | ||
195 | category = reporting_period_data['names'] |
|
196 | ca_len = len(category) |
|
197 | ||
198 | ws.row_dimensions[current_row_number].height = 60 |
|
199 | ws['B' + str(current_row_number)].fill = table_fill |
|
200 | ws['B' + str(current_row_number)].border = f_border |
|
201 | ||
202 | col = 'C' |
|
203 | ||
204 | for i in range(0, ca_len): |
|
205 | ws[col + str(current_row_number)].fill = table_fill |
|
206 | ws[col + str(current_row_number)].font = name_font |
|
207 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
208 | ws[col + str(current_row_number)].border = f_border |
|
209 | ws[col + str(current_row_number)] = \ |
|
210 | reporting_period_data['names'][i] + " " + reporting_period_data['energy_category_names'][i] + \ |
|
211 | " (" + reporting_period_data['units'][i] + ")" |
|
212 | ||
213 | col = chr(ord(col) + 1) |
|
214 | ||
215 | current_row_number += 1 |
|
216 | ||
217 | ws['B' + str(current_row_number)].font = title_font |
|
218 | ws['B' + str(current_row_number)].alignment = c_c_alignment |
|
219 | ws['B' + str(current_row_number)].border = f_border |
|
220 | ws['B' + str(current_row_number)] = _('Consumption') |
|
221 | ||
222 | col = 'C' |
|
223 | ||
224 | for i in range(0, ca_len): |
|
225 | ws[col + str(current_row_number)].font = name_font |
|
226 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
227 | ws[col + str(current_row_number)].border = f_border |
|
228 | ws[col + str(current_row_number)] = round2(reporting_period_data['subtotals'][i], 2) |
|
229 | ||
230 | col = chr(ord(col) + 1) |
|
231 | ||
232 | current_row_number += 1 |
|
233 | ||
234 | ws['B' + str(current_row_number)].font = title_font |
|
235 | ws['B' + str(current_row_number)].alignment = c_c_alignment |
|
236 | ws['B' + str(current_row_number)].border = f_border |
|
237 | ws['B' + str(current_row_number)] = _('Per Unit Area') |
|
238 | ||
239 | col = 'C' |
|
240 | ||
241 | for i in range(0, ca_len): |
|
242 | ws[col + str(current_row_number)].font = name_font |
|
243 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
244 | ws[col + str(current_row_number)].border = f_border |
|
245 | ws[col + str(current_row_number)] = round2(reporting_period_data['subtotals_per_unit_area'][i], 2) |
|
246 | ||
247 | col = chr(ord(col) + 1) |
|
248 | ||
249 | current_row_number += 1 |
|
250 | ||
251 | ws['B' + str(current_row_number)].font = title_font |
|
252 | ws['B' + str(current_row_number)].alignment = c_c_alignment |
|
253 | ws['B' + str(current_row_number)].border = f_border |
|
254 | ws['B' + str(current_row_number)] = _('Increment Rate') |
|
255 | ||
256 | col = 'C' |
|
257 | ||
258 | for i in range(0, ca_len): |
|
259 | ws[col + str(current_row_number)].font = name_font |
|
260 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
261 | ws[col + str(current_row_number)].border = f_border |
|
262 | ws[col + str(current_row_number)] = str( |
|
263 | round2(reporting_period_data['increment_rates'][i] * 100, 2)) + '%' \ |
|
264 | if reporting_period_data['increment_rates'][i] is not None else '-' |
|
265 | ||
266 | col = chr(ord(col) + 1) |
|
267 | ||
268 | current_row_number += 2 |
|
269 | ||
270 | category_dict = group_by_category(reporting_period_data['energy_category_names']) |
|
271 | ||
272 | for category_dict_name, category_dict_values in category_dict.items(): |
|
273 | ||
274 | ws['B' + str(current_row_number)].font = title_font |
|
275 | ws['B' + str(current_row_number)] = name + ' ' + category_dict_name + ' ' + \ |
|
276 | '(' + reporting_period_data['units'][category_dict_values[0]] + ') by Energy Item' |
|
277 | ||
278 | current_row_number += 1 |
|
279 | table_start_row_number = current_row_number |
|
280 | ||
281 | ws['B' + str(current_row_number)].fill = table_fill |
|
282 | ws['B' + str(current_row_number)].border = f_border |
|
283 | ||
284 | ws['C' + str(current_row_number)].font = name_font |
|
285 | ws['C' + str(current_row_number)].fill = table_fill |
|
286 | ws['C' + str(current_row_number)].alignment = c_c_alignment |
|
287 | ws['C' + str(current_row_number)].border = f_border |
|
288 | ws['C' + str(current_row_number)] = _('Per Unit Area') |
|
289 | ||
290 | current_row_number += 1 |
|
291 | ||
292 | for i in category_dict_values: |
|
293 | ws['B' + str(current_row_number)].font = title_font |
|
294 | ws['B' + str(current_row_number)].alignment = c_c_alignment |
|
295 | ws['B' + str(current_row_number)].border = f_border |
|
296 | ws['B' + str(current_row_number)] = \ |
|
297 | reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")" |
|
298 | ws['C' + str(current_row_number)].font = name_font |
|
299 | ws['C' + str(current_row_number)].alignment = c_c_alignment |
|
300 | ws['C' + str(current_row_number)].border = f_border |
|
301 | ws['C' + str(current_row_number)] = round2(reporting_period_data['subtotals'][i], 3) |
|
302 | ||
303 | current_row_number += 1 |
|
304 | ||
305 | table_end_row_number = current_row_number - 1 |
|
306 | ||
307 | pie = PieChart() |
|
308 | pie.title = name + ' ' + category_dict_name + ' ' + \ |
|
309 | '(' + reporting_period_data['units'][category_dict_values[0]] + ') by Energy Item' |
|
310 | labels = Reference(ws, min_col=2, min_row=table_start_row_number + 1, max_row=table_end_row_number) |
|
311 | pie_data = Reference(ws, min_col=3, min_row=table_start_row_number, max_row=table_end_row_number) |
|
312 | pie.add_data(pie_data, titles_from_data=True) |
|
313 | pie.set_categories(labels) |
|
314 | pie.height = 6.6 |
|
315 | pie.width = 9 |
|
316 | s1 = pie.series[0] |
|
317 | s1.dLbls = DataLabelList() |
|
318 | s1.dLbls.showCatName = False |
|
319 | s1.dLbls.showVal = False |
|
320 | s1.dLbls.showPercent = True |
|
321 | ws.add_chart(pie, 'D' + str(table_start_row_number)) |
|
322 | ||
323 | if len(category_dict_values) < 4: |
|
324 | current_row_number = current_row_number - len(category_dict_values) + 4 |
|
325 | ||
326 | current_row_number += 1 |
|
327 | ||
328 | #################################################################################################################### |
|
329 | chart_start_row_number = current_row_number |
|
330 | ||
331 | has_values_data = True |
|
332 | has_timestamps_data = True |
|
333 | ||
334 | if 'values' not in reporting_period_data.keys() or \ |
|
335 | reporting_period_data['values'] is None or \ |
|
336 | len(reporting_period_data['values']) == 0: |
|
337 | has_values_data = False |
|
338 | ||
339 | if 'timestamps' not in reporting_period_data.keys() or \ |
|
340 | reporting_period_data['timestamps'] is None or \ |
|
341 | len(reporting_period_data['timestamps']) == 0 or \ |
|
342 | len(reporting_period_data['timestamps'][0]) == 0: |
|
343 | has_timestamps_data = False |
|
344 | ||
345 | if not is_base_period_timestamp_exists_flag: |
|
346 | if has_values_data and has_timestamps_data: |
|
347 | ca_len = len(reporting_period_data['names']) |
|
348 | time = reporting_period_data['timestamps'][0] |
|
349 | real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps']) |
|
350 | ws['B' + str(current_row_number)].font = title_font |
|
351 | ws['B' + str(current_row_number)] = name + ' ' + _('Detailed Data') |
|
352 | ||
353 | current_row_number += 1 |
|
354 | ||
355 | chart_start_row_number = current_row_number |
|
356 | ||
357 | # 1: Stand for blank line 2: Stand for title |
|
358 | current_row_number += ca_len * 6 + real_timestamps_len * 6 + 1 + 2 |
|
359 | table_start_row_number = current_row_number |
|
360 | ||
361 | ws.row_dimensions[current_row_number].height = 60 |
|
362 | ws['B' + str(current_row_number)].fill = table_fill |
|
363 | ws['B' + str(current_row_number)].font = title_font |
|
364 | ws['B' + str(current_row_number)].alignment = c_c_alignment |
|
365 | ws['B' + str(current_row_number)].border = f_border |
|
366 | ws['B' + str(current_row_number)] = _('Datetime') |
|
367 | ||
368 | col = 'C' |
|
369 | ||
370 | for i in range(0, ca_len): |
|
371 | ws[col + str(current_row_number)].fill = table_fill |
|
372 | ws[col + str(current_row_number)].font = title_font |
|
373 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
374 | ws[col + str(current_row_number)].border = f_border |
|
375 | ws[col + str(current_row_number)] = \ |
|
376 | reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")" |
|
377 | col = chr(ord(col) + 1) |
|
378 | ||
379 | current_row_number += 1 |
|
380 | ||
381 | for i in range(0, len(time)): |
|
382 | ws['B' + str(current_row_number)].font = title_font |
|
383 | ws['B' + str(current_row_number)].alignment = c_c_alignment |
|
384 | ws['B' + str(current_row_number)].border = f_border |
|
385 | ws['B' + str(current_row_number)] = time[i] |
|
386 | ||
387 | col = 'C' |
|
388 | for j in range(0, ca_len): |
|
389 | ws[col + str(current_row_number)].font = title_font |
|
390 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
391 | ws[col + str(current_row_number)].border = f_border |
|
392 | ws[col + str(current_row_number)] = round2(reporting_period_data['values'][j][i], 2) \ |
|
393 | if reporting_period_data['values'][j][i] is not None else 0.00 |
|
394 | col = chr(ord(col) + 1) |
|
395 | ||
396 | current_row_number += 1 |
|
397 | ||
398 | table_end_row_number = current_row_number - 1 |
|
399 | ||
400 | ws['B' + str(current_row_number)].font = title_font |
|
401 | ws['B' + str(current_row_number)].alignment = c_c_alignment |
|
402 | ws['B' + str(current_row_number)].border = f_border |
|
403 | ws['B' + str(current_row_number)] = _('Subtotal') |
|
404 | ||
405 | col = 'C' |
|
406 | ||
407 | for i in range(0, ca_len): |
|
408 | ws[col + str(current_row_number)].font = title_font |
|
409 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
410 | ws[col + str(current_row_number)].border = f_border |
|
411 | ws[col + str(current_row_number)] = round2(reporting_period_data['subtotals'][i], 2) |
|
412 | col = chr(ord(col) + 1) |
|
413 | ||
414 | current_row_number += 2 |
|
415 | ||
416 | for i in range(0, ca_len): |
|
417 | line = LineChart() |
|
418 | line.title = _('Reporting Period Consumption') + ' - ' \ |
|
419 | + reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")" |
|
420 | labels = Reference(ws, min_col=2, |
|
421 | min_row=table_start_row_number + 1, |
|
422 | max_row=table_end_row_number) |
|
423 | reporting_line_data = Reference(ws, min_col=3 + i, |
|
424 | min_row=table_start_row_number, |
|
425 | max_row=table_end_row_number) |
|
426 | line.add_data(reporting_line_data, titles_from_data=True) |
|
427 | line.set_categories(labels) |
|
428 | reporting_line_data = line.series[0] |
|
429 | reporting_line_data.marker.symbol = "auto" |
|
430 | reporting_line_data.smooth = True |
|
431 | line.x_axis.crosses = 'min' |
|
432 | line.height = 8.25 |
|
433 | line.width = 24 |
|
434 | chart_col = 'B' |
|
435 | chart_cell = chart_col + str(chart_start_row_number) |
|
436 | chart_start_row_number += 6 |
|
437 | ws.add_chart(line, chart_cell) |
|
438 | ||
439 | else: |
|
440 | if has_values_data and has_timestamps_data: |
|
441 | base_period_data = report['base_period'] |
|
442 | reporting_period_data = report['reporting_period'] |
|
443 | base_period_timestamps = base_period_data['timestamps'] |
|
444 | reporting_period_timestamps = reporting_period_data['timestamps'] |
|
445 | # Tip: |
|
446 | # base_period_data['names'] == reporting_period_data['names'] |
|
447 | # base_period_data['units'] == reporting_period_data['units'] |
|
448 | base_period_data_ca_len = len(base_period_data['names']) |
|
449 | reporting_period_data_ca_len = len(reporting_period_data['names']) |
|
450 | real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps']) |
|
451 | ws['B' + str(current_row_number)].font = title_font |
|
452 | ws['B' + str(current_row_number)] = name + ' ' + _('Detailed Data') |
|
453 | current_row_number += 1 |
|
454 | ||
455 | chart_start_row_number = current_row_number |
|
456 | ||
457 | # 1: Stand for blank line 2: Stand for title |
|
458 | current_row_number += reporting_period_data_ca_len * 6 + real_timestamps_len * 6 + 1 + 2 |
|
459 | table_start_row_number = current_row_number |
|
460 | ||
461 | ws.row_dimensions[current_row_number].height = 60 |
|
462 | current_col_number = 2 |
|
463 | col = format_cell.get_column_letter(current_col_number) |
|
464 | ws[col + str(current_row_number)].fill = table_fill |
|
465 | ws[col + str(current_row_number)].font = title_font |
|
466 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
467 | ws[col + str(current_row_number)].border = f_border |
|
468 | ws[col + str(current_row_number)] = _('Base Period') + " - " + _('Datetime') |
|
469 | ||
470 | for i in range(0, base_period_data_ca_len): |
|
471 | current_col_number += 1 |
|
472 | col = format_cell.get_column_letter(current_col_number) |
|
473 | ||
474 | ws[col + str(current_row_number)].fill = table_fill |
|
475 | ws[col + str(current_row_number)].font = title_font |
|
476 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
477 | ws[col + str(current_row_number)] = _('Base Period') + " - " + base_period_data['names'][i] + \ |
|
478 | " (" + base_period_data['units'][i] + ")" |
|
479 | ws[col + str(current_row_number)].border = f_border |
|
480 | ||
481 | current_col_number += 1 |
|
482 | col = format_cell.get_column_letter(current_col_number) |
|
483 | ||
484 | ws[col + str(current_row_number)].fill = table_fill |
|
485 | ws[col + str(current_row_number)].font = title_font |
|
486 | ws[col + str(current_row_number)].border = f_border |
|
487 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
488 | ws[col + str(current_row_number)] = _('Reporting Period') + " - " + _('Datetime') |
|
489 | ||
490 | for i in range(0, reporting_period_data_ca_len): |
|
491 | current_col_number += 1 |
|
492 | col = format_cell.get_column_letter(current_col_number) |
|
493 | ws[col + str(current_row_number)].fill = table_fill |
|
494 | ws[col + str(current_row_number)].font = title_font |
|
495 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
496 | ws[col + str(current_row_number)] = _('Reporting Period') + " - " \ |
|
497 | + reporting_period_data['names'][i] + " (" + \ |
|
498 | reporting_period_data['units'][i] + ")" |
|
499 | ws[col + str(current_row_number)].border = f_border |
|
500 | ||
501 | current_row_number += 1 |
|
502 | ||
503 | max_timestamps_len = len(base_period_timestamps[0]) \ |
|
504 | if len(base_period_timestamps[0]) >= len(reporting_period_timestamps[0]) \ |
|
505 | else len(reporting_period_timestamps[0]) |
|
506 | ||
507 | for i in range(0, max_timestamps_len): |
|
508 | current_col_number = 2 |
|
509 | col = format_cell.get_column_letter(current_col_number) |
|
510 | ws[col + str(current_row_number)].font = title_font |
|
511 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
512 | ws[col + str(current_row_number)] = base_period_timestamps[0][i] \ |
|
513 | if i < len(base_period_timestamps[0]) else None |
|
514 | ws[col + str(current_row_number)].border = f_border |
|
515 | ||
516 | for j in range(0, base_period_data_ca_len): |
|
517 | current_col_number += 1 |
|
518 | col = format_cell.get_column_letter(current_col_number) |
|
519 | ||
520 | ws[col + str(current_row_number)].font = title_font |
|
521 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
522 | ws[col + str(current_row_number)] = round2(base_period_data['values'][j][i], 2) \ |
|
523 | if i < len(base_period_data['values'][j]) else None |
|
524 | ws[col + str(current_row_number)].border = f_border |
|
525 | current_col_number += 1 |
|
526 | col = format_cell.get_column_letter(current_col_number) |
|
527 | ||
528 | ws[col + str(current_row_number)].font = title_font |
|
529 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
530 | ws[col + str(current_row_number)] = reporting_period_timestamps[0][i] \ |
|
531 | if i < len(reporting_period_timestamps[0]) else None |
|
532 | ws[col + str(current_row_number)].border = f_border |
|
533 | ||
534 | for j in range(0, reporting_period_data_ca_len): |
|
535 | current_col_number += 1 |
|
536 | col = format_cell.get_column_letter(current_col_number) |
|
537 | ||
538 | ws[col + str(current_row_number)].font = title_font |
|
539 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
540 | ws[col + str(current_row_number)] = round2(reporting_period_data['values'][j][i], 2) \ |
|
541 | if i < len(reporting_period_data['values'][j]) else None |
|
542 | ws[col + str(current_row_number)].border = f_border |
|
543 | ||
544 | current_row_number += 1 |
|
545 | ||
546 | current_col_number = 2 |
|
547 | col = format_cell.get_column_letter(current_col_number) |
|
548 | ||
549 | ws[col + str(current_row_number)].font = title_font |
|
550 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
551 | ws[col + str(current_row_number)] = _('Subtotal') |
|
552 | ws[col + str(current_row_number)].border = f_border |
|
553 | ||
554 | for i in range(0, base_period_data_ca_len): |
|
555 | current_col_number += 1 |
|
556 | col = format_cell.get_column_letter(current_col_number) |
|
557 | ws[col + str(current_row_number)].font = title_font |
|
558 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
559 | ws[col + str(current_row_number)] = round2(base_period_data['subtotals'][i], 2) |
|
560 | ws[col + str(current_row_number)].border = f_border |
|
561 | ||
562 | current_col_number += 1 |
|
563 | col = format_cell.get_column_letter(current_col_number) |
|
564 | ||
565 | ws[col + str(current_row_number)].font = title_font |
|
566 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
567 | ws[col + str(current_row_number)] = _('Subtotal') |
|
568 | ws[col + str(current_row_number)].border = f_border |
|
569 | ||
570 | for i in range(0, reporting_period_data_ca_len): |
|
571 | current_col_number += 1 |
|
572 | col = format_cell.get_column_letter(current_col_number) |
|
573 | ws[col + str(current_row_number)].font = title_font |
|
574 | ws[col + str(current_row_number)].alignment = c_c_alignment |
|
575 | ws[col + str(current_row_number)] = round2(reporting_period_data['subtotals'][i], 2) |
|
576 | ws[col + str(current_row_number)].border = f_border |
|
577 | ||
578 | current_row_number += 2 |
|
579 | ||
580 | for i in range(0, reporting_period_data_ca_len): |
|
581 | line = LineChart() |
|
582 | line.title = _('Base Period Consumption') + ' / ' \ |
|
583 | + _('Reporting Period Consumption') + ' - ' \ |
|
584 | + reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")" |
|
585 | labels = Reference(ws, min_col=2 + base_period_data_ca_len + 1, |
|
586 | min_row=table_start_row_number + 1, |
|
587 | max_row=table_start_row_number + len(reporting_period_timestamps[0])) |
|
588 | base_line_data = Reference(ws, min_col=3 + i, |
|
589 | min_row=table_start_row_number, |
|
590 | max_row=table_start_row_number + len(reporting_period_timestamps[0])) |
|
591 | reporting_line_data = Reference(ws, min_col=3 + base_period_data_ca_len + 1 + i, |
|
592 | min_row=table_start_row_number, |
|
593 | max_row=table_start_row_number + len(reporting_period_timestamps[0])) |
|
594 | line.add_data(base_line_data, titles_from_data=True) |
|
595 | line.add_data(reporting_line_data, titles_from_data=True) |
|
596 | line.set_categories(labels) |
|
597 | for j in range(len(line.series)): |
|
598 | line.series[j].marker.symbol = "auto" |
|
599 | line.series[j].smooth = True |
|
600 | line.x_axis.crosses = 'min' |
|
601 | line.height = 8.25 |
|
602 | line.width = 24 |
|
603 | chart_col = 'B' |
|
604 | chart_cell = chart_col + str(chart_start_row_number) |
|
605 | chart_start_row_number += 6 |
|
606 | ws.add_chart(line, chart_cell) |
|
607 | ||
608 | #################################################################################################################### |
|
609 | current_sheet_parameters_row_number = chart_start_row_number + 1 |
|
610 | if 'parameters' not in report.keys() or \ |
|
611 | report['parameters'] is None or \ |
|
612 | 'names' not in report['parameters'].keys() or \ |
|
613 | report['parameters']['names'] is None or \ |
|
614 | len(report['parameters']['names']) == 0 or \ |
|
615 | 'timestamps' not in report['parameters'].keys() or \ |
|
616 | report['parameters']['timestamps'] is None or \ |
|
617 | len(report['parameters']['timestamps']) == 0 or \ |
|
618 | 'values' not in report['parameters'].keys() or \ |
|
619 | report['parameters']['values'] is None or \ |
|
620 | len(report['parameters']['values']) == 0 or \ |
|
621 | timestamps_data_all_equal_0(report['parameters']['timestamps']): |
|
622 | pass |
|
623 | else: |
|
624 | ################################################################################################################ |
|
625 | # new worksheet |
|
626 | ################################################################################################################ |
|
627 | ||
628 | parameters_data = report['parameters'] |
|
629 | parameters_names_len = len(parameters_data['names']) |
|
630 | ||
631 | file_name = (re.sub(r'[^A-Z]', '', ws.title))+'_' |
|
632 | parameters_ws = wb.create_sheet(file_name + _('Parameters')) |
|
633 | ||
634 | parameters_timestamps_data_max_len = \ |
|
635 | get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps'])) |
|
636 | ||
637 | # Row height |
|
638 | parameters_ws.row_dimensions[1].height = 102 |
|
639 | for i in range(2, 7 + 1): |
|
640 | parameters_ws.row_dimensions[i].height = 42 |
|
641 | ||
642 | for i in range(8, parameters_timestamps_data_max_len + 10): |
|
643 | parameters_ws.row_dimensions[i].height = 60 |
|
644 | ||
645 | # Col width |
|
646 | parameters_ws.column_dimensions['A'].width = 1.5 |
|
647 | ||
648 | parameters_ws.column_dimensions['B'].width = 25.0 |
|
649 | ||
650 | for i in range(3, 12 + parameters_names_len * 3): |
|
651 | parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0 |
|
652 | ||
653 | # Img |
|
654 | img = Image("excelexporters/myems.png") |
|
655 | parameters_ws.add_image(img, 'A1') |
|
656 | ||
657 | # Title |
|
658 | parameters_ws['B3'].alignment = b_r_alignment |
|
659 | parameters_ws['B3'] = _('Name') + ':' |
|
660 | parameters_ws['C3'].border = b_border |
|
661 | parameters_ws['C3'].alignment = b_c_alignment |
|
662 | parameters_ws['C3'] = name |
|
663 | ||
664 | parameters_ws['D3'].alignment = b_r_alignment |
|
665 | parameters_ws['D3'] = _('Period Type') + ':' |
|
666 | parameters_ws['E3'].border = b_border |
|
667 | parameters_ws['E3'].alignment = b_c_alignment |
|
668 | parameters_ws['E3'] = period_type |
|
669 | ||
670 | parameters_ws['B4'].alignment = b_r_alignment |
|
671 | parameters_ws['B4'] = _('Reporting Start Datetime') + ':' |
|
672 | parameters_ws['C4'].border = b_border |
|
673 | parameters_ws['C4'].alignment = b_c_alignment |
|
674 | parameters_ws['C4'] = reporting_start_datetime_local |
|
675 | ||
676 | parameters_ws['D4'].alignment = b_r_alignment |
|
677 | parameters_ws['D4'] = _('Reporting End Datetime') + ':' |
|
678 | parameters_ws['E4'].border = b_border |
|
679 | parameters_ws['E4'].alignment = b_c_alignment |
|
680 | parameters_ws['E4'] = reporting_end_datetime_local |
|
681 | ||
682 | parameters_ws_current_row_number = 6 |
|
683 | ||
684 | parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font |
|
685 | parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' ' + _('Parameters') |
|
686 | ||
687 | parameters_ws_current_row_number += 1 |
|
688 | ||
689 | parameters_table_start_row_number = parameters_ws_current_row_number |
|
690 | ||
691 | parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80 |
|
692 | ||
693 | parameters_ws_current_row_number += 1 |
|
694 | ||
695 | table_current_col_number = 2 |
|
696 | ||
697 | for i in range(0, parameters_names_len): |
|
698 | ||
699 | if len(parameters_data['timestamps'][i]) == 0: |
|
700 | continue |
|
701 | ||
702 | col = format_cell.get_column_letter(table_current_col_number) |
|
703 | ||
704 | parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill |
|
705 | parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border |
|
706 | ||
707 | col = format_cell.get_column_letter(table_current_col_number + 1) |
|
708 | ||
709 | parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill |
|
710 | parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border |
|
711 | parameters_ws[col + str(parameters_ws_current_row_number - 1)].font = name_font |
|
712 | parameters_ws[col + str(parameters_ws_current_row_number - 1)].alignment = c_c_alignment |
|
713 | parameters_ws[col + str(parameters_ws_current_row_number - 1)] = parameters_data['names'][i] |
|
714 | ||
715 | table_current_row_number = parameters_ws_current_row_number |
|
716 | ||
717 | for j, value in enumerate(list(parameters_data['timestamps'][i])): |
|
718 | col = format_cell.get_column_letter(table_current_col_number) |
|
719 | ||
720 | parameters_ws[col + str(table_current_row_number)].border = f_border |
|
721 | parameters_ws[col + str(table_current_row_number)].font = title_font |
|
722 | parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment |
|
723 | parameters_ws[col + str(table_current_row_number)] = value |
|
724 | ||
725 | col = format_cell.get_column_letter(table_current_col_number + 1) |
|
726 | ||
727 | parameters_ws[col + str(table_current_row_number)].border = f_border |
|
728 | parameters_ws[col + str(table_current_row_number)].font = title_font |
|
729 | parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment |
|
730 | parameters_ws[col + str(table_current_row_number)] = round2(parameters_data['values'][i][j], 2) |
|
731 | ||
732 | table_current_row_number += 1 |
|
733 | ||
734 | table_current_col_number = table_current_col_number + 3 |
|
735 | ||
736 | ################################################################################################################ |
|
737 | # parameters chart and parameters table |
|
738 | ################################################################################################################ |
|
739 | ||
740 | ws['B' + str(current_sheet_parameters_row_number)].font = title_font |
|
741 | ws['B' + str(current_sheet_parameters_row_number)] = name + ' ' + _('Parameters') |
|
742 | ||
743 | current_sheet_parameters_row_number += 1 |
|
744 | ||
745 | chart_start_row_number = current_sheet_parameters_row_number |
|
746 | ||
747 | col_index = 0 |
|
748 | ||
749 | for i in range(0, parameters_names_len): |
|
750 | ||
751 | if len(parameters_data['timestamps'][i]) == 0: |
|
752 | continue |
|
753 | ||
754 | line = LineChart() |
|
755 | data_col = 3 + col_index * 3 |
|
756 | labels_col = 2 + col_index * 3 |
|
757 | col_index += 1 |
|
758 | line.title = _('Parameters') + ' - ' + \ |
|
759 | parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value |
|
760 | labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1, |
|
761 | max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number)) |
|
762 | line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number, |
|
763 | max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number)) |
|
764 | line.add_data(line_data, titles_from_data=True) |
|
765 | line.set_categories(labels) |
|
766 | line_data = line.series[0] |
|
767 | line_data.marker.symbol = "auto" |
|
768 | line_data.smooth = True |
|
769 | line.x_axis.crosses = 'min' |
|
770 | line.height = 8.25 |
|
771 | line.width = 24 |
|
772 | chart_col = 'B' |
|
773 | chart_cell = chart_col + str(chart_start_row_number) |
|
774 | chart_start_row_number += 6 |
|
775 | ws.add_chart(line, chart_cell) |
|
776 | ||
777 | current_sheet_parameters_row_number = chart_start_row_number |
|
778 | ||
779 | current_sheet_parameters_row_number += 1 |
|
780 | #################################################################################################################### |
|
781 | filename = str(uuid.uuid4()) + '.xlsx' |
|
782 | wb.save(filename) |
|
783 | ||
784 | return filename |
|
785 | ||
786 | ||
787 | def group_by_category(category_list): |