Issues (1577)

myems-api/excelexporters/combinedequipmentload.py (3 issues)

1
import base64
2
from core.utilities import get_translation
3
import os
4
import re
5
import uuid
6
import openpyxl.utils.cell as format_cell
7
from openpyxl import Workbook
8
from openpyxl.chart import LineChart, Reference
9
from openpyxl.drawing.image import Image
10
from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
11
from core.utilities import round2
12
13
########################################################################################################################
14
# PROCEDURES
15
# Step 1: Validate the report data
16
# Step 2: Generate excel file
17
# Step 3: Encode the excel file to Base64
18
########################################################################################################################
19
20
21 View Code Duplication
def export(report,
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
22
           name,
23
           base_period_start_datetime_local,
24
           base_period_end_datetime_local,
25
           reporting_start_datetime_local,
26
           reporting_end_datetime_local,
27
           period_type,
28
           language):
29
    ####################################################################################################################
30
    # Step 1: Validate the report data
31
    ####################################################################################################################
32
    if report is None:
33
        return None
34
35
    ####################################################################################################################
36
    # Step 2: Generate excel file from the report data
37
    ####################################################################################################################
38
    filename = generate_excel(report,
39
                              name,
40
                              base_period_start_datetime_local,
41
                              base_period_end_datetime_local,
42
                              reporting_start_datetime_local,
43
                              reporting_end_datetime_local,
44
                              period_type,
45
                              language)
46
    ####################################################################################################################
47
    # Step 3: Encode the excel file to Base64
48
    ####################################################################################################################
49
    binary_file_data = b''
50
    try:
51
        with open(filename, 'rb') as binary_file:
52
            binary_file_data = binary_file.read()
53
    except IOError as ex:
54
        print(str(ex))
55
56
    # Base64 encode the bytes
57
    base64_encoded_data = base64.b64encode(binary_file_data)
58
    # get the Base64 encoded data using human-readable characters.
59
    base64_message = base64_encoded_data.decode('utf-8')
60
    # delete the file from server
61
    try:
62
        os.remove(filename)
63
    except NotImplementedError as ex:
64
        print(str(ex))
65
    return base64_message
66
67
68
def generate_excel(report,
69
                   name,
70
                   base_period_start_datetime_local,
71
                   base_period_end_datetime_local,
72
                   reporting_start_datetime_local,
73
                   reporting_end_datetime_local,
74
                   period_type,
75
                   language):
76
77
    trans = get_translation(language)
78
    trans.install()
79
    _ = trans.gettext
80
81
    wb = Workbook()
82
    ws = wb.active
83
    ws.title = "CombinedEquipmentLoad"
84
85
    # Row height
86
    ws.row_dimensions[1].height = 102
87
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
    ws.column_dimensions['B'].width = 25.0
94
95
    for i in range(ord('C'), ord('Z')):
96
        ws.column_dimensions[chr(i)].width = 15.0
97
98
    # Font
99
    name_font = Font(name='Arial', size=15, bold=True)
100
    title_font = Font(name='Arial', size=15, bold=True)
101
102
    table_fill = PatternFill(fill_type='solid', fgColor='90ee90')
103
    f_border = Border(left=Side(border_style='medium'),
104
                      right=Side(border_style='medium'),
105
                      bottom=Side(border_style='medium'),
106
                      top=Side(border_style='medium')
107
                      )
108
    b_border = Border(
109
        bottom=Side(border_style='medium'),
110
    )
111
112
    b_c_alignment = Alignment(vertical='bottom',
113
                              horizontal='center',
114
                              text_rotation=0,
115
                              wrap_text=True,
116
                              shrink_to_fit=False,
117
                              indent=0)
118
    c_c_alignment = Alignment(vertical='center',
119
                              horizontal='center',
120
                              text_rotation=0,
121
                              wrap_text=True,
122
                              shrink_to_fit=False,
123
                              indent=0)
124
    b_r_alignment = Alignment(vertical='bottom',
125
                              horizontal='right',
126
                              text_rotation=0,
127
                              wrap_text=True,
128
                              shrink_to_fit=False,
129
                              indent=0)
130
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'
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable str does not seem to be defined.
Loading history...
178
        wb.save(filename)
179
180
        return filename
181
    ####################################################################################################################
182
    # First: Load
183
    # 7: title
184
    # 8: table title
185
    # 9~2*ca_len table_data
186
    ####################################################################################################################
187
    reporting_period_data = report['reporting_period']
188
189
    if "names" not in reporting_period_data.keys() or \
190
            reporting_period_data['names'] is None or \
191
            len(reporting_period_data['names']) == 0:
192
        filename = str(uuid.uuid4()) + '.xlsx'
193
        wb.save(filename)
194
195
        return filename
196
197
    ws['B7'].font = title_font
198
    ws['B7'] = name + ' ' + _('Load')
199
200
    category = reporting_period_data['names']
201
202
    # table_title
203
    ws['B8'].fill = table_fill
204
    ws['B8'].font = title_font
205
    ws['B8'].alignment = c_c_alignment
206
    ws['B8'] = _('Reporting Period')
207
    ws['B8'].border = f_border
208
209
    ws['C8'].font = title_font
210
    ws['C8'].alignment = c_c_alignment
211
    ws['C8'] = _('Average Load')
212
    ws['C8'].border = f_border
213
214
    ws['D8'].font = title_font
215
    ws['D8'].alignment = c_c_alignment
216
    ws['D8'] = _('Maximum Load')
217
    ws['D8'].border = f_border
218
219
    ws['E8'].font = title_font
220
    ws['E8'].alignment = c_c_alignment
221
    ws['E8'] = _('Load Factor')
222
    ws['E8'].border = f_border
223
224
    # table_data
225
226
    for i, value in enumerate(category):
227
        row = i * 2 + 9
228
        ws['B' + str(row)].font = name_font
229
        ws['B' + str(row)].alignment = c_c_alignment
230
        ws['B' + str(row)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + "/H )"
231
        ws['B' + str(row)].border = f_border
232
233
        ws['B' + str(row + 1)].font = name_font
234
        ws['B' + str(row + 1)].alignment = c_c_alignment
235
        ws['B' + str(row + 1)] = _('Increment Rate')
236
        ws['B' + str(row + 1)].border = f_border
237
238
        ws['C' + str(row)].font = name_font
239
        ws['C' + str(row)].alignment = c_c_alignment
240
        ws['C' + str(row)] = round2(reporting_period_data['averages'][i], 2) \
241
            if reporting_period_data['averages'][i] is not None else ''
242
        ws['C' + str(row)].border = f_border
243
        ws['C' + str(row)].number_format = '0.00'
244
245
        ws['C' + str(row + 1)].font = name_font
246
        ws['C' + str(row + 1)].alignment = c_c_alignment
247
        ws['C' + str(row + 1)] = str(round2(reporting_period_data['averages_increment_rate'][i] * 100, 2)) + "%" \
248
            if reporting_period_data['averages_increment_rate'][i] is not None else '0.00%'
249
        ws['C' + str(row + 1)].border = f_border
250
251
        ws['D' + str(row)].font = name_font
252
        ws['D' + str(row)].alignment = c_c_alignment
253
        ws['D' + str(row)] = round2(reporting_period_data['maximums'][i], 2) \
254
            if reporting_period_data['maximums'][i] is not None else ''
255
        ws['D' + str(row)].border = f_border
256
        ws['D' + str(row)].number_format = '0.00'
257
258
        ws['D' + str(row + 1)].font = name_font
259
        ws['D' + str(row + 1)].alignment = c_c_alignment
260
        ws['D' + str(row + 1)] = str(round2(reporting_period_data['maximums_increment_rate'][i] * 100, 2)) + "%" \
261
            if reporting_period_data['maximums_increment_rate'][i] is not None else '0.00%'
262
        ws['D' + str(row + 1)].border = f_border
263
264
        ws['E' + str(row)].font = name_font
265
        ws['E' + str(row)].alignment = c_c_alignment
266
        ws['E' + str(row)] = round2(reporting_period_data['factors'][i], 2) \
267
            if reporting_period_data['factors'][i] is not None else ''
268
        ws['E' + str(row)].border = f_border
269
        ws['E' + str(row)].number_format = '0.00'
270
271
        ws['E' + str(row + 1)].font = name_font
272
        ws['E' + str(row + 1)].alignment = c_c_alignment
273
        ws['E' + str(row + 1)] = str(round2(reporting_period_data['factors_increment_rate'][i] * 100, 2)) + "%" \
274
            if reporting_period_data['factors_increment_rate'][i] is not None else '0.00%'
275
        ws['E' + str(row + 1)].border = f_border
276
277
    ####################################################################################################################
278
    # Third: Detailed Data
279
    # analysis_end_row_number~ analysis_end_row_number + 6*cal_len: line
280
    # detailed_start_row_number: table title
281
    # detailed_start_row_number + 1~: table_data
282
    ####################################################################################################################
283
    current_row_number = len(category) * 2 + 9 + 1
284
285
    has_sub_averages_data_flag = True
286
    has_sub_maximums_data_flag = True
287
288
    if "sub_averages" not in report['reporting_period'].keys() or len(report['reporting_period']['sub_averages']) == 0:
289
        has_sub_averages_data_flag = False
290
291
    if "sub_maximums" not in report['reporting_period'].keys() or len(report['reporting_period']['sub_maximums']) == 0:
292
        has_sub_maximums_data_flag = False
293
294
    current_chart_row_number = current_row_number
295
296
    if has_sub_averages_data_flag or has_sub_maximums_data_flag:
297
        if not is_base_period_timestamp_exists_flag:
298
            reporting_period_data = report['reporting_period']
299
            category = reporting_period_data['names']
300
            ca_len = len(category)
301
            times = reporting_period_data['timestamps']
302
            time = times[0]
303
            real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
304
            ws['B' + str(current_row_number)].font = title_font
305
            ws['B' + str(current_row_number)] = name + _('Detailed Data')
306
307
            current_row_number += 1
308
            chart_start_number = current_row_number
309
            # 1: Stand for blank line  2: Stand for title
310
            current_row_number += real_timestamps_len * 6 + 1 + 2
311
            if has_sub_averages_data_flag:
312
                current_row_number = (current_row_number + ca_len * 6)
313
314
            if has_sub_maximums_data_flag:
315
                current_row_number = (current_row_number + ca_len * 6)
316
317
            table_start_number = current_row_number
318
319
            ws.row_dimensions[current_row_number].height = 60
320
            current_col_number = 2
321
            col = format_cell.get_column_letter(current_col_number)
322
            ws[col + str(current_row_number)].fill = table_fill
323
            ws[col + str(current_row_number)].font = title_font
324
            ws[col + str(current_row_number)].alignment = c_c_alignment
325
            ws[col + str(current_row_number)].border = f_border
326
            ws[col + str(current_row_number)] = _('Datetime')
327
328
            current_col_number = 3
329
            col = format_cell.get_column_letter(current_col_number)
330
331
            for i in range(0, ca_len):
332
                if has_sub_averages_data_flag:
333
                    ws[col + str(current_row_number)].fill = table_fill
334
                    ws[col + str(current_row_number)].font = title_font
335
                    ws[col + str(current_row_number)].alignment = c_c_alignment
336
                    ws[col + str(current_row_number)].border = f_border
337
                    ws[col + str(current_row_number)] = reporting_period_data['names'][i] + \
338
                        " " + _('Average Load') + "(" + reporting_period_data['units'][
339
                        i] + "/H)"
340
341
                    current_col_number += 1
342
                    col = format_cell.get_column_letter(current_col_number)
343
344
                if has_sub_maximums_data_flag:
345
                    ws[col + str(current_row_number)].fill = table_fill
346
                    ws[col + str(current_row_number)].font = title_font
347
                    ws[col + str(current_row_number)].alignment = c_c_alignment
348
                    ws[col + str(current_row_number)].border = f_border
349
                    ws[col + str(current_row_number)] = reporting_period_data['names'][i] + \
350
                        " " + _('Maximum Load') + "(" + reporting_period_data['units'][
351
                        i] + "/H)"
352
353
                    current_col_number += 1
354
                    col = format_cell.get_column_letter(current_col_number)
355
356
            current_row_number += 1
357
358
            for i in range(0, len(time)):
359
                current_col_number = 2
360
                col = format_cell.get_column_letter(current_col_number)
361
                ws[col + str(current_row_number)].font = title_font
362
                ws[col + str(current_row_number)].alignment = c_c_alignment
363
                ws[col + str(current_row_number)].border = f_border
364
                ws[col + str(current_row_number)] = time[i]
365
366
                current_col_number = 3
367
                col = format_cell.get_column_letter(current_col_number)
368
                for j in range(0, ca_len):
369
370
                    if has_sub_averages_data_flag:
371
                        ws[col + str(current_row_number)].font = title_font
372
                        ws[col + str(current_row_number)].alignment = c_c_alignment
373
                        ws[col + str(current_row_number)].border = f_border
374
                        ws[col + str(current_row_number)] = round2(reporting_period_data['sub_averages'][j][i], 2) \
375
                            if reporting_period_data['sub_averages'][j][i] is not None else None
376
                        current_col_number += 1
377
                        col = format_cell.get_column_letter(current_col_number)
378
379
                    if has_sub_maximums_data_flag:
380
                        ws[col + str(current_row_number)].font = title_font
381
                        ws[col + str(current_row_number)].alignment = c_c_alignment
382
                        ws[col + str(current_row_number)].border = f_border
383
                        ws[col + str(current_row_number)] = round2(reporting_period_data['sub_maximums'][j][i], 2) \
384
                            if reporting_period_data['sub_maximums'][j][i] is not None else None
385
                        current_col_number += 1
386
                        col = format_cell.get_column_letter(current_col_number)
387
388
                current_row_number += 1
389
390
            table_end_number = current_row_number - 1
391
392
            current_chart_col_number = 3
393
            current_chart_row_number = chart_start_number
394
395
            for i in range(0, ca_len):
396
                labels = Reference(ws, min_col=2, min_row=table_start_number + 1, max_row=table_end_number)
397
398
                if has_sub_averages_data_flag:
399
                    line = LineChart()
400
                    line.title = _('Reporting Period Average Load') + ' - ' \
401
                        + reporting_period_data['names'][i] + \
402
                        " " + _('Average Load') + "(" + reporting_period_data['units'][i] + "/H)"
403
                    datas = Reference(ws, min_col=current_chart_col_number, min_row=table_start_number,
404
                                      max_row=table_end_number)
405
                    line.add_data(datas, titles_from_data=True)
406
                    line.set_categories(labels)
407
                    line_data = line.series[0]
408
                    line_data.marker.symbol = "auto"
409
                    line_data.smooth = True
410
                    line.x_axis.crosses = 'min'
411
                    line.height = 8.25
412
                    line.width = 24
413
                    ws.add_chart(line, "B" + str(current_chart_row_number))
414
                    current_chart_row_number += 6
415
                    current_chart_col_number += 1
416
417
                if has_sub_maximums_data_flag:
418
                    line = LineChart()
419
                    line.title = _('Reporting Period Maximum Load') + ' - ' \
420
                        + reporting_period_data['names'][i] + \
421
                        " " + _('Maximum Load') + "(" + reporting_period_data['units'][i] + "/H)"
422
                    datas = Reference(ws, min_col=current_chart_col_number, min_row=table_start_number,
423
                                      max_row=table_end_number)
424
                    line.add_data(datas, titles_from_data=True)
425
                    line.set_categories(labels)
426
                    line_data = line.series[0]
427
                    line_data.marker.symbol = "auto"
428
                    line_data.smooth = True
429
                    line.x_axis.crosses = 'min'
430
                    line.height = 8.25
431
                    line.width = 24
432
                    ws.add_chart(line, "B" + str(current_chart_row_number))
433
                    current_chart_row_number += 6
434
                    current_chart_col_number += 1
435
436
            current_row_number += 1
437
438
        else:
439
            base_period_data = report['base_period']
440
            reporting_period_data = report['reporting_period']
441
            base_period_timestamps = base_period_data['timestamps']
442
            reporting_period_timestamps = reporting_period_data['timestamps']
443
            # Tip:
444
            #     base_period_data['names'] == reporting_period_data['names']
445
            #     base_period_data['units'] == reporting_period_data['units']
446
            base_period_data_ca_len = len(base_period_data['names'])
447
            reporting_period_data_ca_len = len(reporting_period_data['names'])
448
            real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
449
            ws['B' + str(current_row_number)].font = title_font
450
            ws['B' + str(current_row_number)] = name + ' ' + _('Detailed Data')
451
452
            current_row_number += 1
453
            chart_start_number = current_row_number
454
455
            # 1: Stand for blank line  2: Stand for title
456
            current_row_number += real_timestamps_len * 6 + 1 + 2
457
458
            if has_sub_averages_data_flag:
459
                current_row_number = (current_row_number + reporting_period_data_ca_len * 6)
460
461
            if has_sub_maximums_data_flag:
462
                current_row_number = (current_row_number + reporting_period_data_ca_len * 6)
463
464
            table_start_row_number = current_row_number
465
466
            has_data = False
467
468
            if len(base_period_timestamps[0]) or len(reporting_period_timestamps[0]) > 0:
469
                has_data = True
470
471
            if has_data:
472
                ws.row_dimensions[current_row_number].height = 60
473
                current_col_number = 2
474
                col = format_cell.get_column_letter(current_col_number)
475
                ws[col + str(current_row_number)].fill = table_fill
476
                ws[col + str(current_row_number)].font = title_font
477
                ws[col + str(current_row_number)].border = f_border
478
                ws[col + str(current_row_number)].alignment = c_c_alignment
479
                ws[col + str(current_row_number)] = _('Base Period') + " - " + _('Datetime')
480
481
                for i in range(0, base_period_data_ca_len):
482
                    if has_sub_averages_data_flag:
483
                        current_col_number += 1
484
                        col = format_cell.get_column_letter(current_col_number)
485
486
                        ws[col + str(current_row_number)].fill = table_fill
487
                        ws[col + str(current_row_number)].font = title_font
488
                        ws[col + str(current_row_number)].alignment = c_c_alignment
489
                        ws[col + str(current_row_number)] = _('Base Period') + " - " \
490
                            + base_period_data['names'][i] + \
491
                            " " + _('Average Load') + "(" + base_period_data['units'][
492
                            i] + "/H)"
493
                        ws[col + str(current_row_number)].border = f_border
494
495
                    if has_sub_maximums_data_flag:
496
                        current_col_number += 1
497
                        col = format_cell.get_column_letter(current_col_number)
498
499
                        ws[col + str(current_row_number)].fill = table_fill
500
                        ws[col + str(current_row_number)].font = title_font
501
                        ws[col + str(current_row_number)].alignment = c_c_alignment
502
                        ws[col + str(current_row_number)] = _('Base Period') + " - " \
503
                            + base_period_data['names'][i] + \
504
                            " " + _('Maximum Load') + "(" + base_period_data['units'][
505
                            i] + "/H)"
506
                        ws[col + str(current_row_number)].border = f_border
507
508
                current_col_number += 1
509
                col = format_cell.get_column_letter(current_col_number)
510
511
                ws[col + str(current_row_number)].fill = table_fill
512
                ws[col + str(current_row_number)].font = title_font
513
                ws[col + str(current_row_number)].border = f_border
514
                ws[col + str(current_row_number)].alignment = c_c_alignment
515
                ws[col + str(current_row_number)] = _('Reporting Period') + " - " + _('Datetime')
516
517
                for i in range(0, reporting_period_data_ca_len):
518
                    if has_sub_averages_data_flag:
519
                        current_col_number += 1
520
                        col = format_cell.get_column_letter(current_col_number)
521
                        ws[col + str(current_row_number)].fill = table_fill
522
                        ws[col + str(current_row_number)].font = title_font
523
                        ws[col + str(current_row_number)].alignment = c_c_alignment
524
                        ws[col + str(current_row_number)] = _('Reporting Period') + " - " \
525
                            + reporting_period_data['names'][i] + \
526
                            " " + _('Average Load') + "(" + \
527
                            reporting_period_data['units'][i] + "/H)"
528
                        ws[col + str(current_row_number)].border = f_border
529
530
                    if has_sub_maximums_data_flag:
531
                        current_col_number += 1
532
                        col = format_cell.get_column_letter(current_col_number)
533
                        ws[col + str(current_row_number)].fill = table_fill
534
                        ws[col + str(current_row_number)].font = title_font
535
                        ws[col + str(current_row_number)].alignment = c_c_alignment
536
                        ws[col + str(current_row_number)] = _('Reporting Period') + " - " \
537
                            + reporting_period_data['names'][i] + \
538
                            " " + _('Maximum Load') + "(" + \
539
                            reporting_period_data['units'][i] + "/H)"
540
                        ws[col + str(current_row_number)].border = f_border
541
542
                current_row_number += 1
543
544
                max_timestamps_len = len(base_period_timestamps[0]) \
545
                    if len(base_period_timestamps[0]) >= len(reporting_period_timestamps[0]) \
546
                    else len(reporting_period_timestamps[0])
547
548
                for i in range(0, max_timestamps_len):
549
                    current_col_number = 2
550
                    col = format_cell.get_column_letter(current_col_number)
551
                    ws[col + str(current_row_number)].font = title_font
552
                    ws[col + str(current_row_number)].alignment = c_c_alignment
553
                    ws[col + str(current_row_number)] = base_period_timestamps[0][i] \
554
                        if i < len(base_period_timestamps[0]) else None
555
                    ws[col + str(current_row_number)].border = f_border
556
557
                    for j in range(0, base_period_data_ca_len):
558
                        if has_sub_averages_data_flag:
559
                            current_col_number += 1
560
                            col = format_cell.get_column_letter(current_col_number)
561
562
                            ws[col + str(current_row_number)].font = title_font
563
                            ws[col + str(current_row_number)].alignment = c_c_alignment
564
                            ws[col + str(current_row_number)] = round2(base_period_data['sub_averages'][j][i], 2) \
565
                                if i < len(base_period_data['sub_averages'][j]) \
566
                                and base_period_data['sub_averages'][j][i] is not None else None
567
                            ws[col + str(current_row_number)].border = f_border
568
569
                        if has_sub_maximums_data_flag:
570
                            current_col_number += 1
571
                            col = format_cell.get_column_letter(current_col_number)
572
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(base_period_data['sub_maximums'][j][i], 2) \
576
                                if i < len(base_period_data['sub_maximums'][j]) \
577
                                and base_period_data['sub_averages'][j][i] is not None else None
578
                            ws[col + str(current_row_number)].border = f_border
579
580
                    current_col_number += 1
581
                    col = format_cell.get_column_letter(current_col_number)
582
583
                    ws[col + str(current_row_number)].font = title_font
584
                    ws[col + str(current_row_number)].alignment = c_c_alignment
585
                    ws[col + str(current_row_number)] = reporting_period_timestamps[0][i] \
586
                        if i < len(reporting_period_timestamps[0]) else None
587
                    ws[col + str(current_row_number)].border = f_border
588
589
                    for j in range(0, reporting_period_data_ca_len):
590
                        if has_sub_averages_data_flag:
591
                            current_col_number += 1
592
                            col = format_cell.get_column_letter(current_col_number)
593
594
                            ws[col + str(current_row_number)].font = title_font
595
                            ws[col + str(current_row_number)].alignment = c_c_alignment
596
                            ws[col + str(current_row_number)] = round2(reporting_period_data['sub_averages'][j][i], 2) \
597
                                if i < len(reporting_period_data['sub_averages'][j]) \
598
                                and reporting_period_data['sub_averages'][j][i] is not None else None
599
                            ws[col + str(current_row_number)].border = f_border
600
601
                        if has_sub_maximums_data_flag:
602
                            current_col_number += 1
603
                            col = format_cell.get_column_letter(current_col_number)
604
605
                            ws[col + str(current_row_number)].font = title_font
606
                            ws[col + str(current_row_number)].alignment = c_c_alignment
607
                            ws[col + str(current_row_number)] = round2(reporting_period_data['sub_maximums'][j][i], 2) \
608
                                if i < len(reporting_period_data['sub_maximums'][j]) \
609
                                and reporting_period_data['sub_maximums'][j][i] is not None else None
610
                            ws[col + str(current_row_number)].border = f_border
611
612
                    current_row_number += 1
613
614
                current_chart_col_number = 3
615
                current_chart_row_number = chart_start_number
616
617
                for i in range(0, reporting_period_data_ca_len):
618
                    labels = Reference(ws, min_col=2 + base_period_data_ca_len * 2 + 1,
619
                                       min_row=table_start_row_number + 1,
620
                                       max_row=table_start_row_number + len(reporting_period_timestamps[0]))
621
622
                    if has_sub_averages_data_flag:
623
                        # line
624
                        line = LineChart()
625
                        line.title = _('Base Period Average Load') + ' / ' \
626
                            + _('Reporting Period Average Load') + ' - ' \
627
                            + reporting_period_data['names'][i] + \
628
                            " " + _('Average Load') + "(" + reporting_period_data['units'][i] + "/H)"
629
                        base_line_data = Reference(ws,
630
                                                   min_col=current_chart_col_number,
631
                                                   min_row=table_start_row_number,
632
                                                   max_row=table_start_row_number
633
                                                   + len(reporting_period_timestamps[0]))
634
635
                        data_distance = base_period_data_ca_len
636
                        if has_sub_maximums_data_flag:
637
                            data_distance *= 2
638
639
                        reporting_line_data = Reference(ws,
640
                                                        min_col=current_chart_col_number + data_distance + 1,
641
                                                        min_row=table_start_row_number,
642
                                                        max_row=table_start_row_number
643
                                                        + len(reporting_period_timestamps[0]))
644
                        line.add_data(base_line_data, titles_from_data=True)
645
                        line.add_data(reporting_line_data, titles_from_data=True)
646
                        line.set_categories(labels)
647
                        for j in range(len(line.series)):
648
                            line.series[j].marker.symbol = "auto"
649
                            line.series[j].smooth = True
650
                        line.x_axis.crosses = 'min'
651
                        line.height = 8.25
652
                        line.width = 24
653
                        chart_col = 'B'
654
                        chart_cell = chart_col + str(current_chart_row_number)
655
                        ws.add_chart(line, chart_cell)
656
                        current_chart_row_number += 6
657
                        current_chart_col_number += 1
658
659
                    if has_sub_maximums_data_flag:
660
                        # line
661
                        line = LineChart()
662
                        line.title = _('Base Period Maximum Load') + ' / ' \
663
                            + _('Reporting Period Maximum Load') + ' - ' \
664
                            + reporting_period_data['names'][i] + \
665
                            " " + _('Maximum Load') + "(" + reporting_period_data['units'][i] + "/H)"
666
                        base_line_data = Reference(ws,
667
                                                   min_col=current_chart_col_number,
668
                                                   min_row=table_start_row_number,
669
                                                   max_row=table_start_row_number
670
                                                   + len(reporting_period_timestamps[0]))
671
672
                        data_distance = base_period_data_ca_len
673
                        if has_sub_averages_data_flag:
674
                            data_distance *= 2
675
676
                        reporting_line_data = Reference(ws,
677
                                                        min_col=current_chart_col_number + data_distance + 1,
678
                                                        min_row=table_start_row_number,
679
                                                        max_row=table_start_row_number
680
                                                        + len(reporting_period_timestamps[0]))
681
                        line.add_data(base_line_data, titles_from_data=True)
682
                        line.add_data(reporting_line_data, titles_from_data=True)
683
                        line.set_categories(labels)
684
                        for j in range(len(line.series)):
685
                            line.series[j].marker.symbol = "auto"
686
                            line.series[j].smooth = True
687
                        line.x_axis.crosses = 'min'
688
                        line.height = 8.25
689
                        line.width = 24
690
                        chart_col = 'B'
691
                        chart_cell = chart_col + str(current_chart_row_number)
692
                        ws.add_chart(line, chart_cell)
693
                        current_chart_row_number += 6
694
                        current_chart_col_number += 1
695
696
                current_row_number += 1
697
698
    ####################################################################################################################
699
700
    has_associated_equipment_flag = True
701
702
    if "associated_equipment" not in report.keys() or \
703
            "energy_category_names" not in report['associated_equipment'].keys() or \
704
            len(report['associated_equipment']["energy_category_names"]) == 0 \
705
            or 'associated_equipment_names_array' not in report['associated_equipment'].keys() \
706
            or report['associated_equipment']['associated_equipment_names_array'] is None \
707
            or len(report['associated_equipment']['associated_equipment_names_array']) == 0 \
708
            or len(report['associated_equipment']['associated_equipment_names_array'][0]) == 0:
709
        has_associated_equipment_flag = False
710
711
    if has_associated_equipment_flag:
712
        names = report['associated_equipment']['energy_category_names']
713
        associated_equipment = report['associated_equipment']
714
715
        ws['B' + str(current_row_number)].font = title_font
716
        ws['B' + str(current_row_number)] = name + ' ' + _('Associated Equipment Data')
717
718
        current_row_number += 1
719
720
        ws.row_dimensions[current_row_number].height = 60
721
        ws['B' + str(current_row_number)].fill = table_fill
722
        ws['B' + str(current_row_number)].font = name_font
723
        ws['B' + str(current_row_number)].alignment = c_c_alignment
724
        ws['B' + str(current_row_number)].border = f_border
725
        ws['B' + str(current_row_number)] = _('Associated Equipment')
726
        ca_len = len(associated_equipment['energy_category_names'])
727
728
        for i in range(0, ca_len):
729
            col_average = chr(ord('C') + 2 * i)
730
            col_maximum = chr(ord('D') + 2 * i)
731
732
            ws[col_average + str(current_row_number)].font = name_font
733
            ws[col_average + str(current_row_number)].alignment = c_c_alignment
734
            ws[col_average + str(current_row_number)] = names[i] + " " + _('Average Load') + "(" + \
735
                                                                   associated_equipment['units'][i] + "/H)"
736
            ws[col_average + str(current_row_number)].border = f_border
737
738
            ws[col_maximum + str(current_row_number)].font = name_font
739
            ws[col_maximum + str(current_row_number)].alignment = c_c_alignment
740
            ws[col_maximum + str(current_row_number)] = names[i] + " " + _('Maximum Load') + "(" + \
741
                                                                   associated_equipment['units'][i] + "/H)"
742
            ws[col_maximum + str(current_row_number)].border = f_border
743
744
        # table_data
745
746
        associated_equipment_len = len(associated_equipment['associated_equipment_names_array'][0])
747
748
        for j in range(0, associated_equipment_len):
749
            current_row_number += 1
750
            rows = str(current_row_number)
751
752
            ws['B' + rows].font = title_font
753
            ws['B' + rows].alignment = c_c_alignment
754
            ws['B' + rows] = associated_equipment['associated_equipment_names_array'][0][j]
755
            ws['B' + rows].border = f_border
756
757
            for index in range(0, ca_len):
758
                col_average = chr(ord('C') + 2 * index)
759
                col_maximum = chr(ord('D') + 2 * index)
760
761
                ws[col_average + str(rows)].font = name_font
762
                ws[col_average + str(rows)].alignment = c_c_alignment
763
                ws[col_average + str(rows)] = associated_equipment['sub_averages_array'][index][j] \
764
                    if associated_equipment['sub_averages_array'][index][j] is not None else ''
765
                ws[col_average + str(rows)].number_format = '0.00'
766
                ws[col_average + str(rows)].border = f_border
767
768
                ws[col_maximum + str(rows)].font = name_font
769
                ws[col_maximum + str(rows)].alignment = c_c_alignment
770
                ws[col_maximum + str(rows)] = associated_equipment['sub_maximums_array'][index][j] \
771
                    if associated_equipment['sub_maximums_array'][index][j] is not None else ''
772
                ws[col_maximum + str(rows)].number_format = '0.00'
773
                ws[col_maximum + str(rows)].border = f_border
774
775
    ####################################################################################################################
776
    current_sheet_parameters_row_number = current_chart_row_number + 1
777
    if 'parameters' not in report.keys() or \
778
            report['parameters'] is None or \
779
            'names' not in report['parameters'].keys() or \
780
            report['parameters']['names'] is None or \
781
            len(report['parameters']['names']) == 0 or \
782
            'timestamps' not in report['parameters'].keys() or \
783
            report['parameters']['timestamps'] is None or \
784
            len(report['parameters']['timestamps']) == 0 or \
785
            'values' not in report['parameters'].keys() or \
786
            report['parameters']['values'] is None or \
787
            len(report['parameters']['values']) == 0 or \
788
            timestamps_data_all_equal_0(report['parameters']['timestamps']):
789
        pass
790
    else:
791
792
        ################################################################################################################
793
        # new worksheet
794
        ################################################################################################################
795
796
        parameters_data = report['parameters']
797
        parameters_names_len = len(parameters_data['names'])
798
799
        file_name = (re.sub(r'[^A-Z]', '', ws.title))+'_'
800
        parameters_ws = wb.create_sheet(file_name + _('Parameters'))
801
802
        parameters_timestamps_data_max_len = \
803
            get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps']))
804
805
        # Row height
806
        parameters_ws.row_dimensions[1].height = 102
807
        for i in range(2, 7 + 1):
808
            parameters_ws.row_dimensions[i].height = 42
809
810
        for i in range(8, parameters_timestamps_data_max_len + 10):
811
            parameters_ws.row_dimensions[i].height = 60
812
813
        # Col width
814
        parameters_ws.column_dimensions['A'].width = 1.5
815
816
        parameters_ws.column_dimensions['B'].width = 25.0
817
818
        for i in range(3, 12+parameters_names_len*3):
819
            parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0
820
821
        # Img
822
        img = Image("excelexporters/myems.png")
823
        parameters_ws.add_image(img, 'A1')
824
825
        # Title
826
        parameters_ws['B3'].alignment = b_r_alignment
827
        parameters_ws['B3'] = _('Name') + ':'
828
        parameters_ws['C3'].border = b_border
829
        parameters_ws['C3'].alignment = b_c_alignment
830
        parameters_ws['C3'] = name
831
832
        parameters_ws['D3'].alignment = b_r_alignment
833
        parameters_ws['D3'] = _('Period Type') + ':'
834
        parameters_ws['E3'].border = b_border
835
        parameters_ws['E3'].alignment = b_c_alignment
836
        parameters_ws['E3'] = period_type
837
838
        parameters_ws['B4'].alignment = b_r_alignment
839
        parameters_ws['B4'] = _('Reporting Start Datetime') + ':'
840
        parameters_ws['C4'].border = b_border
841
        parameters_ws['C4'].alignment = b_c_alignment
842
        parameters_ws['C4'] = reporting_start_datetime_local
843
844
        parameters_ws['D4'].alignment = b_r_alignment
845
        parameters_ws['D4'] = _('Reporting End Datetime') + ':'
846
        parameters_ws['E4'].border = b_border
847
        parameters_ws['E4'].alignment = b_c_alignment
848
        parameters_ws['E4'] = reporting_end_datetime_local
849
850
        parameters_ws_current_row_number = 6
851
852
        parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font
853
        parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' ' + _('Parameters')
854
855
        parameters_ws_current_row_number += 1
856
857
        parameters_table_start_row_number = parameters_ws_current_row_number
858
859
        parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80
860
861
        parameters_ws_current_row_number += 1
862
863
        table_current_col_number = 2
864
865
        for i in range(0, parameters_names_len):
866
867
            if len(parameters_data['timestamps'][i]) == 0:
868
                continue
869
870
            col = format_cell.get_column_letter(table_current_col_number)
871
872
            parameters_ws[col + str(parameters_ws_current_row_number-1)].fill = table_fill
873
            parameters_ws[col + str(parameters_ws_current_row_number-1)].border = f_border
874
875
            col = format_cell.get_column_letter(table_current_col_number + 1)
876
877
            parameters_ws[col + str(parameters_ws_current_row_number-1)].fill = table_fill
878
            parameters_ws[col + str(parameters_ws_current_row_number-1)].border = f_border
879
            parameters_ws[col + str(parameters_ws_current_row_number-1)].font = name_font
880
            parameters_ws[col + str(parameters_ws_current_row_number-1)].alignment = c_c_alignment
881
            parameters_ws[col + str(parameters_ws_current_row_number-1)] = parameters_data['names'][i]
882
883
            table_current_row_number = parameters_ws_current_row_number
884
885
            for j, value in enumerate(list(parameters_data['timestamps'][i])):
886
                col = format_cell.get_column_letter(table_current_col_number)
887
888
                parameters_ws[col + str(table_current_row_number)].border = f_border
889
                parameters_ws[col + str(table_current_row_number)].font = title_font
890
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
891
                parameters_ws[col + str(table_current_row_number)] = value
892
893
                col = format_cell.get_column_letter(table_current_col_number + 1)
894
895
                parameters_ws[col + str(table_current_row_number)].border = f_border
896
                parameters_ws[col + str(table_current_row_number)].font = title_font
897
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
898
                parameters_ws[col + str(table_current_row_number)] = round2(parameters_data['values'][i][j], 2)
899
900
                table_current_row_number += 1
901
902
            table_current_col_number = table_current_col_number + 3
903
904
        ################################################################################################################
905
        # parameters chart and parameters table
906
        ################################################################################################################
907
908
        ws['B' + str(current_sheet_parameters_row_number)].font = title_font
909
        ws['B' + str(current_sheet_parameters_row_number)] = name + ' ' + _('Parameters')
910
911
        current_sheet_parameters_row_number += 1
912
913
        chart_start_row_number = current_sheet_parameters_row_number
914
915
        col_index = 0
916
917
        for i in range(0, parameters_names_len):
918
919
            if len(parameters_data['timestamps'][i]) == 0:
920
                continue
921
922
            line = LineChart()
923
            data_col = 3+col_index*3
924
            labels_col = 2+col_index*3
925
            col_index += 1
926
            line.title = _('Parameters') + ' - ' + \
927
                parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value
928
            labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1,
929
                               max_row=(len(parameters_data['timestamps'][i])+parameters_table_start_row_number))
930
            line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number,
931
                                  max_row=(len(parameters_data['timestamps'][i])+parameters_table_start_row_number))
932
            line.add_data(line_data, titles_from_data=True)
933
            line.set_categories(labels)
934
            line_data = line.series[0]
935
            line_data.marker.symbol = "auto"
936
            line_data.smooth = True
937
            line.x_axis.crosses = 'min'
938
            line.height = 8.25
939
            line.width = 24
940
            chart_col = 'B'
941
            chart_cell = chart_col + str(chart_start_row_number)
942
            chart_start_row_number += 6
943
            ws.add_chart(line, chart_cell)
944
945
        current_sheet_parameters_row_number = chart_start_row_number
946
947
        current_sheet_parameters_row_number += 1
948
    ####################################################################################################################
949
    filename = str(uuid.uuid4()) + '.xlsx'
950
    wb.save(filename)
951
952
    return filename
953
954
955
def get_parameters_timestamps_lists_max_len(parameters_timestamps_lists):
956
    max_len = 0
957
    for i, value in enumerate(list(parameters_timestamps_lists)):
958
        if len(value) > max_len:
959
            max_len = len(value)
960
961
    return max_len
962
963
964
def timestamps_data_all_equal_0(lists):
965
    for i, value in enumerate(list(lists)):
966
        if len(value) > 0:
967
            return False
968
969
    return True
970
971
972
def timestamps_data_not_equal_0(lists):
973
    number = 0
974
    for i, value in enumerate(list(lists)):
975
        if len(value) > 0:
976
            number += 1
977
    return number
978
979
980 View Code Duplication
def is_base_period_timestamp_exists(base_period_data):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
981
    timestamps = base_period_data['timestamps']
982
983
    if len(timestamps) == 0:
984
        return False
985
986
    for timestamp in timestamps:
987
        if len(timestamp) > 0:
988
            return True
989
990
    return False
991