Passed
Push — master ( 02289f...d6a19b )
by Guangyu
08:58 queued 15s
created

excelexporters.spaceload.export()   B

Complexity

Conditions 5

Size

Total Lines 46
Code Lines 32

Duplication

Lines 46
Ratio 100 %

Importance

Changes 0
Metric Value
eloc 32
dl 46
loc 46
rs 8.6453
c 0
b 0
f 0
cc 5
nop 8

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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