Passed
Push — master ( 414b30...be43ee )
by Guangyu
14:19 queued 13s
created

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
80
    locale_path = './i18n/'
81
    if language == 'zh_CN':
82
        trans = gettext.translation('myems', locale_path, languages=['zh_CN'])
83
    elif language == 'de':
84
        trans = gettext.translation('myems', locale_path, languages=['de'])
85
    elif language == 'en':
86
        trans = gettext.translation('myems', locale_path, languages=['en'])
87
    else:
88
        trans = gettext.translation('myems', locale_path, languages=['en'])
89
    trans.install()
90
    _ = trans.gettext
91
92
    wb = Workbook()
93
    ws = wb.active
94
    ws.title = "CombinedEquipmentStatistics"
95
96
    # Row height
97
    ws.row_dimensions[1].height = 102
98
99
    for i in range(2, 2000 + 1):
100
        ws.row_dimensions[i].height = 42
101
102
    # Col width
103
    ws.column_dimensions['A'].width = 1.5
104
    ws.column_dimensions['B'].width = 25.0
105
106
    for i in range(ord('C'), ord('Z')):
107
        ws.column_dimensions[chr(i)].width = 15.0
108
109
    # Font
110
    name_font = Font(name='Arial', size=15, bold=True)
111
    title_font = Font(name='Arial', size=15, bold=True)
112
113
    table_fill = PatternFill(fill_type='solid', fgColor='90ee90')
114
    f_border = Border(left=Side(border_style='medium'),
115
                      right=Side(border_style='medium'),
116
                      bottom=Side(border_style='medium'),
117
                      top=Side(border_style='medium')
118
                      )
119
    b_border = Border(
120
        bottom=Side(border_style='medium'),
121
    )
122
123
    b_c_alignment = Alignment(vertical='bottom',
124
                              horizontal='center',
125
                              text_rotation=0,
126
                              wrap_text=True,
127
                              shrink_to_fit=False,
128
                              indent=0)
129
    c_c_alignment = Alignment(vertical='center',
130
                              horizontal='center',
131
                              text_rotation=0,
132
                              wrap_text=True,
133
                              shrink_to_fit=False,
134
                              indent=0)
135
    b_r_alignment = Alignment(vertical='bottom',
136
                              horizontal='right',
137
                              text_rotation=0,
138
                              wrap_text=True,
139
                              shrink_to_fit=False,
140
                              indent=0)
141
142
    # Img
143
    img = Image("excelexporters/myems.png")
144
    ws.add_image(img, 'A1')
145
146
    # Title
147
    ws['B3'].alignment = b_r_alignment
148
    ws['B3'] = _('Name') + ':'
149
    ws['C3'].border = b_border
150
    ws['C3'].alignment = b_c_alignment
151
    ws['C3'] = name
152
153
    ws['D3'].alignment = b_r_alignment
154
    ws['D3'] = _('Period Type') + ':'
155
    ws['E3'].border = b_border
156
    ws['E3'].alignment = b_c_alignment
157
    ws['E3'] = period_type
158
159
    ws['B4'].alignment = b_r_alignment
160
    ws['B4'] = _('Reporting Start Datetime') + ':'
161
    ws['C4'].border = b_border
162
    ws['C4'].alignment = b_c_alignment
163
    ws['C4'] = reporting_start_datetime_local
164
165
    ws['D4'].alignment = b_r_alignment
166
    ws['D4'] = _('Reporting End Datetime') + ':'
167
    ws['E4'].border = b_border
168
    ws['E4'].alignment = b_c_alignment
169
    ws['E4'] = reporting_end_datetime_local
170
171
    is_base_period_timestamp_exists_flag = is_base_period_timestamp_exists(report['base_period'])
172
173
    if is_base_period_timestamp_exists_flag:
174
        ws['B5'].alignment = b_r_alignment
175
        ws['B5'] = _('Base Period Start Datetime') + ':'
176
        ws['C5'].border = b_border
177
        ws['C5'].alignment = b_c_alignment
178
        ws['C5'] = base_period_start_datetime_local
179
180
        ws['D5'].alignment = b_r_alignment
181
        ws['D5'] = _('Base Period End Datetime') + ':'
182
        ws['E5'].border = b_border
183
        ws['E5'].alignment = b_c_alignment
184
        ws['E5'] = base_period_end_datetime_local
185
186
    if "reporting_period" not in report.keys() or \
187
            "names" not in report['reporting_period'].keys() or len(report['reporting_period']['names']) == 0:
188
        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...
189
        wb.save(filename)
190
191
        return filename
192
    ####################################################################################################################
193
    # First: Statistics
194
    # 7: title
195
    # 8: table title
196
    # 9~ca_len table_data
197
    ####################################################################################################################
198
    reporting_period_data = report['reporting_period']
199
200
    if "names" not in reporting_period_data.keys() or \
201
            reporting_period_data['names'] is None or \
202
            len(reporting_period_data['names']) == 0:
203
        filename = str(uuid.uuid4()) + '.xlsx'
204
        wb.save(filename)
205
        return filename
206
207
    ws['B7'].font = title_font
208
    ws['B7'] = name + ' ' + _('Statistics')
209
210
    category = reporting_period_data['names']
211
212
    # table_title
213
    ws['B8'].fill = table_fill
214
    ws['B8'].font = title_font
215
    ws['B8'].alignment = c_c_alignment
216
    ws['B8'] = _('Reporting Period')
217
    ws['B8'].border = f_border
218
219
    ws['C8'].font = title_font
220
    ws['C8'].alignment = c_c_alignment
221
    ws['C8'] = _('Arithmetic Mean')
222
    ws['C8'].border = f_border
223
224
    ws['D8'].font = title_font
225
    ws['D8'].alignment = c_c_alignment
226
    ws['D8'] = _('Median (Middle Value)')
227
    ws['D8'].border = f_border
228
229
    ws['E8'].font = title_font
230
    ws['E8'].alignment = c_c_alignment
231
    ws['E8'] = _('Minimum Value')
232
    ws['E8'].border = f_border
233
234
    ws['F8'].font = title_font
235
    ws['F8'].alignment = c_c_alignment
236
    ws['F8'] = _('Maximum Value')
237
    ws['F8'].border = f_border
238
239
    ws['G8'].font = title_font
240
    ws['G8'].alignment = c_c_alignment
241
    ws['G8'] = _('Sample Standard Deviation')
242
    ws['G8'].border = f_border
243
244
    ws['H8'].font = title_font
245
    ws['H8'].alignment = c_c_alignment
246
    ws['H8'] = _('Sample Variance')
247
    ws['H8'].border = f_border
248
249
    # table_data
250
251
    for i, value in enumerate(category):
252
        row = i * 2 + 9
253
        ws['B' + str(row)].font = name_font
254
        ws['B' + str(row)].alignment = c_c_alignment
255
        ws['B' + str(row)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + " )"
256
        ws['B' + str(row)].border = f_border
257
258
        ws['B' + str(row + 1)].font = name_font
259
        ws['B' + str(row + 1)].alignment = c_c_alignment
260
        ws['B' + str(row + 1)] = _('Increment Rate')
261
        ws['B' + str(row + 1)].border = f_border
262
263
        ws['C' + str(row)].font = name_font
264
        ws['C' + str(row)].alignment = c_c_alignment
265
        ws['C' + str(row)] = reporting_period_data['means'][i] \
266
            if reporting_period_data['means'][i] is not None else ''
267
        ws['C' + str(row)].border = f_border
268
        ws['C' + str(row)].number_format = '0.00'
269
270
        ws['C' + str(row + 1)].font = name_font
271
        ws['C' + str(row + 1)].alignment = c_c_alignment
272
        ws['C' + str(row + 1)] = str(round(reporting_period_data['means_increment_rate'][i] * 100, 2)) + "%" \
273
            if reporting_period_data['means_increment_rate'][i] is not None else '0.00%'
274
        ws['C' + str(row + 1)].border = f_border
275
276
        ws['D' + str(row)].font = name_font
277
        ws['D' + str(row)].alignment = c_c_alignment
278
        ws['D' + str(row)] = reporting_period_data['medians'][i] \
279
            if reporting_period_data['medians'][i] is not None else ''
280
        ws['D' + str(row)].border = f_border
281
        ws['D' + str(row)].number_format = '0.00'
282
283
        ws['D' + str(row + 1)].font = name_font
284
        ws['D' + str(row + 1)].alignment = c_c_alignment
285
        ws['D' + str(row + 1)] = str(round(reporting_period_data['medians_increment_rate'][i] * 100, 2)) + "%" \
286
            if reporting_period_data['medians_increment_rate'][i] is not None else '0.00%'
287
        ws['D' + str(row + 1)].border = f_border
288
289
        ws['E' + str(row)].font = name_font
290
        ws['E' + str(row)].alignment = c_c_alignment
291
        ws['E' + str(row)] = reporting_period_data['minimums'][i] \
292
            if reporting_period_data['minimums'][i] is not None else ''
293
        ws['E' + str(row)].border = f_border
294
        ws['E' + str(row)].number_format = '0.00'
295
296
        ws['E' + str(row + 1)].font = name_font
297
        ws['E' + str(row + 1)].alignment = c_c_alignment
298
        ws['E' + str(row + 1)] = str(round(reporting_period_data['minimums_increment_rate'][i] * 100, 2)) + "%" \
299
            if reporting_period_data['minimums_increment_rate'][i] is not None else '0.00%'
300
        ws['E' + str(row + 1)].border = f_border
301
302
        ws['F' + str(row)].font = name_font
303
        ws['F' + str(row)].alignment = c_c_alignment
304
        ws['F' + str(row)] = reporting_period_data['maximums'][i] \
305
            if reporting_period_data['maximums'][i] is not None else ''
306
        ws['F' + str(row)].border = f_border
307
        ws['F' + str(row)].number_format = '0.00'
308
309
        ws['F' + str(row + 1)].font = name_font
310
        ws['F' + str(row + 1)].alignment = c_c_alignment
311
        ws['F' + str(row + 1)] = str(round(reporting_period_data['maximums_increment_rate'][i] * 100, 2)) + "%" \
312
            if reporting_period_data['maximums_increment_rate'][i] is not None else '0.00%'
313
        ws['F' + str(row + 1)].border = f_border
314
315
        ws['G' + str(row)].font = name_font
316
        ws['G' + str(row)].alignment = c_c_alignment
317
        ws['G' + str(row)] = reporting_period_data['stdevs'][i] \
318
            if reporting_period_data['stdevs'][i] is not None else ''
319
        ws['G' + str(row)].border = f_border
320
        ws['G' + str(row)].number_format = '0.00'
321
322
        ws['G' + str(row + 1)].font = name_font
323
        ws['G' + str(row + 1)].alignment = c_c_alignment
324
        ws['G' + str(row + 1)] = str(round(reporting_period_data['stdevs_increment_rate'][i] * 100, 2)) + "%" \
325
            if reporting_period_data['stdevs_increment_rate'][i] is not None else '0.00%'
326
        ws['G' + str(row + 1)].border = f_border
327
328
        ws['H' + str(row)].font = name_font
329
        ws['H' + str(row)].alignment = c_c_alignment
330
        ws['H' + str(row)] = reporting_period_data['variances'][i] \
331
            if reporting_period_data['variances'][i] is not None else ''
332
        ws['H' + str(row)].border = f_border
333
        ws['H' + str(row)].number_format = '0.00'
334
335
        ws['H' + str(row + 1)].font = name_font
336
        ws['H' + str(row + 1)].alignment = c_c_alignment
337
        ws['H' + str(row + 1)] = str(round(reporting_period_data['variances_increment_rate'][i] * 100, 2)) + "%" \
338
            if reporting_period_data['variances_increment_rate'][i] is not None else '0.00%'
339
        ws['H' + str(row + 1)].border = f_border
340
341
    ####################################################################################################################
342
    # Second: Detailed Data
343
    # analysis_end_row_number+1~ analysis_end_row_number+1+line_charts_row_number+: line
344
    # detailed_start_row_number~ : the detailed data table
345
    ####################################################################################################################
346
    current_row_number = len(category) * 2 + 9 + 1
347
348
    table_start_draw_flag = current_row_number + 1
349
    if "timestamps" not in reporting_period_data.keys() or \
350
            reporting_period_data['timestamps'] is None or \
351
            len(reporting_period_data['timestamps']) == 0:
352
        pass
353
    else:
354
        if not is_base_period_timestamp_exists_flag:
355
            reporting_period_data = report['reporting_period']
356
            times = reporting_period_data['timestamps']
357
            ca_len = len(report['reporting_period']['names'])
358
            real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
359
            ws['B' + str(current_row_number)].font = title_font
360
            ws['B' + str(current_row_number)] = name + ' ' + _('Detailed Data')
361
362
            current_row_number += 1
363
            # 1: Stand for blank line  2: Stand for title
364
            current_row_number += ca_len * 6 + real_timestamps_len * 6 + 1 + 2
365
            table_start_row_number = current_row_number
366
367
            time = times[0]
368
            has_data = False
369
370
            if len(time) > 0:
371
                has_data = True
372
373
            if has_data:
374
375
                ws.row_dimensions[current_row_number].height = 60
376
                current_col_number = 2
377
                col = format_cell.get_column_letter(current_col_number)
378
                ws[col + str(current_row_number)].fill = table_fill
379
                ws[col + str(current_row_number)].font = title_font
380
                ws[col + str(current_row_number)].border = f_border
381
                ws[col + str(current_row_number)].alignment = c_c_alignment
382
                ws[col + str(current_row_number)] = _('Datetime')
383
384
                for i in range(0, ca_len):
385
                    current_col_number += 1
386
                    col = format_cell.get_column_letter(current_col_number)
387
388
                    ws[col + str(current_row_number)].fill = table_fill
389
                    ws[col + str(current_row_number)].font = title_font
390
                    ws[col + str(current_row_number)].alignment = c_c_alignment
391
                    ws[col + str(current_row_number)] = reporting_period_data['names'][i] + \
392
                        " (" + reporting_period_data['units'][i] + ")"
393
                    ws[col + str(current_row_number)].border = f_border
394
395
                current_row_number += 1
396
397
                for i in range(0, len(time)):
398
                    current_col_number = 2
399
                    col = format_cell.get_column_letter(current_col_number)
400
                    ws[col + str(current_row_number)].font = title_font
401
                    ws[col + str(current_row_number)].alignment = c_c_alignment
402
                    ws[col + str(current_row_number)] = time[i]
403
                    ws[col + str(current_row_number)].border = f_border
404
405
                    for j in range(0, ca_len):
406
                        current_col_number += 1
407
                        col = format_cell.get_column_letter(current_col_number)
408
409
                        ws[col + str(current_row_number)].font = title_font
410
                        ws[col + str(current_row_number)].alignment = c_c_alignment
411
                        ws[col + str(current_row_number)] = round(reporting_period_data['values'][j][i], 2)
412
                        ws[col + str(current_row_number)].border = f_border
413
414
                    current_row_number += 1
415
416
                table_end_row_number = current_row_number - 1
417
418
                current_col_number = 2
419
                col = format_cell.get_column_letter(current_col_number)
420
                ws[col + str(current_row_number)].font = title_font
421
                ws[col + str(current_row_number)].alignment = c_c_alignment
422
                ws[col + str(current_row_number)] = _('Subtotal')
423
                ws[col + str(current_row_number)].border = f_border
424
425
                for i in range(0, ca_len):
426
                    current_col_number += 1
427
                    col = format_cell.get_column_letter(current_col_number)
428
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)] = round(reporting_period_data['subtotals'][i], 2)
432
                    ws[col + str(current_row_number)].border = f_border
433
434
                    # line
435
                    line = LineChart()
436
                    line.title = _('Reporting Period Consumption') + ' - ' \
437
                        + reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")"
438
                    labels = Reference(ws, min_col=2, min_row=table_start_row_number + 1, max_row=table_end_row_number)
439
                    line_data = Reference(ws, min_col=3 + i, min_row=table_start_row_number,
440
                                          max_row=table_end_row_number)
441
                    line.add_data(line_data, titles_from_data=True)
442
                    line.set_categories(labels)
443
                    line_data = line.series[0]
444
                    line_data.marker.symbol = "circle"
445
                    line_data.smooth = True
446
                    line.x_axis.crosses = 'min'
447
                    line.height = 8.25
448
                    line.width = 24
449
                    line.dLbls = DataLabelList()
450
                    line.dLbls.dLblPos = 't'
451
                    line.dLbls.showVal = True
452
                    line.dLbls.showPercent = False
453
                    chart_col = 'B'
454
                    chart_cell = chart_col + str(table_start_draw_flag + 6 * i)
455
                    ws.add_chart(line, chart_cell)
456
457
                current_row_number += 2
458
        else:
459
            base_period_data = report['base_period']
460
            reporting_period_data = report['reporting_period']
461
            base_period_timestamps = base_period_data['timestamps']
462
            reporting_period_timestamps = reporting_period_data['timestamps']
463
            # Tip:
464
            #     base_period_data['names'] == reporting_period_data['names']
465
            #     base_period_data['units'] == reporting_period_data['units']
466
            base_period_data_ca_len = len(base_period_data['names'])
467
            reporting_period_data_ca_len = len(reporting_period_data['names'])
468
            real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
469
            ws['B' + str(current_row_number)].font = title_font
470
            ws['B' + str(current_row_number)] = name + ' ' + _('Detailed Data')
471
472
            current_row_number += 1
473
            # 1: Stand for blank line  2: Stand for title
474
            current_row_number += reporting_period_data_ca_len * 6 + real_timestamps_len * 6 + 1 + 2
475
            table_start_row_number = current_row_number
476
477
            has_data = False
478
479
            if len(base_period_timestamps[0]) or len(reporting_period_timestamps[0]) > 0:
480
                has_data = True
481
482
            if has_data:
483
                ws.row_dimensions[current_row_number].height = 60
484
                current_col_number = 2
485
                col = format_cell.get_column_letter(current_col_number)
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)].border = f_border
489
                ws[col + str(current_row_number)].alignment = c_c_alignment
490
                ws[col + str(current_row_number)] = _('Base Period') + " - " + _('Datetime')
491
492
                for i in range(0, base_period_data_ca_len):
493
                    current_col_number += 1
494
                    col = format_cell.get_column_letter(current_col_number)
495
496
                    ws[col + str(current_row_number)].fill = table_fill
497
                    ws[col + str(current_row_number)].font = title_font
498
                    ws[col + str(current_row_number)].alignment = c_c_alignment
499
                    ws[col + str(current_row_number)] = _('Base Period') + " - " + base_period_data['names'][i] + \
500
                        " (" + base_period_data['units'][i] + ")"
501
                    ws[col + str(current_row_number)].border = f_border
502
                current_col_number += 1
503
                col = format_cell.get_column_letter(current_col_number)
504
505
                ws[col + str(current_row_number)].fill = table_fill
506
                ws[col + str(current_row_number)].font = title_font
507
                ws[col + str(current_row_number)].border = f_border
508
                ws[col + str(current_row_number)].alignment = c_c_alignment
509
                ws[col + str(current_row_number)] = _('Reporting Period') + " - " + _('Datetime')
510
511
                for i in range(0, reporting_period_data_ca_len):
512
                    current_col_number += 1
513
                    col = format_cell.get_column_letter(current_col_number)
514
                    ws[col + str(current_row_number)].fill = table_fill
515
                    ws[col + str(current_row_number)].font = title_font
516
                    ws[col + str(current_row_number)].alignment = c_c_alignment
517
                    ws[col + str(current_row_number)] = _('Reporting Period') + " - " \
518
                        + reporting_period_data['names'][i] + " (" + \
519
                        reporting_period_data['units'][i] + ")"
520
                    ws[col + str(current_row_number)].border = f_border
521
522
                current_row_number += 1
523
524
                max_timestamps_len = len(base_period_timestamps[0]) \
525
                    if len(base_period_timestamps[0]) >= len(reporting_period_timestamps[0]) \
526
                    else len(reporting_period_timestamps[0])
527
528
                for i in range(0, max_timestamps_len):
529
                    current_col_number = 2
530
                    col = format_cell.get_column_letter(current_col_number)
531
                    ws[col + str(current_row_number)].font = title_font
532
                    ws[col + str(current_row_number)].alignment = c_c_alignment
533
                    ws[col + str(current_row_number)] = base_period_timestamps[0][i] \
534
                        if i < len(base_period_timestamps[0]) else None
535
                    ws[col + str(current_row_number)].border = f_border
536
537
                    for j in range(0, base_period_data_ca_len):
538
                        current_col_number += 1
539
                        col = format_cell.get_column_letter(current_col_number)
540
541
                        ws[col + str(current_row_number)].font = title_font
542
                        ws[col + str(current_row_number)].alignment = c_c_alignment
543
                        ws[col + str(current_row_number)] = round(base_period_data['values'][j][i], 2) \
544
                            if i < len(base_period_data['values'][j]) else None
545
                        ws[col + str(current_row_number)].border = f_border
546
                    current_col_number += 1
547
                    col = format_cell.get_column_letter(current_col_number)
548
549
                    ws[col + str(current_row_number)].font = title_font
550
                    ws[col + str(current_row_number)].alignment = c_c_alignment
551
                    ws[col + str(current_row_number)] = reporting_period_timestamps[0][i] \
552
                        if i < len(reporting_period_timestamps[0]) else None
553
                    ws[col + str(current_row_number)].border = f_border
554
555
                    for j in range(0, reporting_period_data_ca_len):
556
                        current_col_number += 1
557
                        col = format_cell.get_column_letter(current_col_number)
558
559
                        ws[col + str(current_row_number)].font = title_font
560
                        ws[col + str(current_row_number)].alignment = c_c_alignment
561
                        ws[col + str(current_row_number)] = round(reporting_period_data['values'][j][i], 2) \
562
                            if i < len(reporting_period_data['values'][j]) else None
563
                        ws[col + str(current_row_number)].border = f_border
564
565
                    current_row_number += 1
566
567
                current_col_number = 2
568
                col = format_cell.get_column_letter(current_col_number)
569
                ws[col + str(current_row_number)].font = title_font
570
                ws[col + str(current_row_number)].alignment = c_c_alignment
571
                ws[col + str(current_row_number)] = _('Subtotal')
572
                ws[col + str(current_row_number)].border = f_border
573
574
                for i in range(0, base_period_data_ca_len):
575
                    current_col_number += 1
576
                    col = format_cell.get_column_letter(current_col_number)
577
                    ws[col + str(current_row_number)].font = title_font
578
                    ws[col + str(current_row_number)].alignment = c_c_alignment
579
                    ws[col + str(current_row_number)] = round(base_period_data['subtotals'][i], 2)
580
                    ws[col + str(current_row_number)].border = f_border
581
582
                current_col_number += 1
583
                col = format_cell.get_column_letter(current_col_number)
584
585
                ws[col + str(current_row_number)].font = title_font
586
                ws[col + str(current_row_number)].alignment = c_c_alignment
587
                ws[col + str(current_row_number)] = _('Subtotal')
588
                ws[col + str(current_row_number)].border = f_border
589
590
                for i in range(0, reporting_period_data_ca_len):
591
                    current_col_number += 1
592
                    col = format_cell.get_column_letter(current_col_number)
593
                    ws[col + str(current_row_number)].font = title_font
594
                    ws[col + str(current_row_number)].alignment = c_c_alignment
595
                    ws[col + str(current_row_number)] = round(reporting_period_data['subtotals'][i], 2)
596
                    ws[col + str(current_row_number)].border = f_border
597
598
                for i in range(0, reporting_period_data_ca_len):
599
                    # line
600
                    line = LineChart()
601
                    line.title = _('Base Period Consumption') + ' / ' \
602
                        + _('Reporting Period Consumption') + ' - ' \
603
                        + reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")"
604
                    labels = Reference(ws, min_col=2 + base_period_data_ca_len + 1,
605
                                       min_row=table_start_row_number + 1,
606
                                       max_row=table_start_row_number + len(reporting_period_timestamps[0]))
607
                    base_line_data = Reference(ws, min_col=3 + i, min_row=table_start_row_number,
608
                                               max_row=table_start_row_number + len(reporting_period_timestamps[0]))
609
                    reporting_line_data = Reference(ws, min_col=3 + base_period_data_ca_len + 1 + i,
610
                                                    min_row=table_start_row_number,
611
                                                    max_row=table_start_row_number
612
                                                    + len(reporting_period_timestamps[0]))
613
                    line.add_data(base_line_data, titles_from_data=True)
614
                    line.add_data(reporting_line_data, titles_from_data=True)
615
                    line.set_categories(labels)
616
                    for j in range(len(line.series)):
617
                        line.series[j].marker.symbol = "circle"
618
                        line.series[j].smooth = True
619
                    line.x_axis.crosses = 'min'
620
                    line.height = 8.25
621
                    line.width = 24
622
                    line.dLbls = DataLabelList()
623
                    line.dLbls.dLblPos = 't'
624
                    line.dLbls.showVal = True
625
                    line.dLbls.showPercent = False
626
                    chart_col = 'B'
627
                    chart_cell = chart_col + str(table_start_draw_flag + 6 * i)
628
                    ws.add_chart(line, chart_cell)
629
630
                current_row_number += 2
631
632
    ####################################################################################################################
633 View Code Duplication
    if "associated_equipment" not in report.keys() or \
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
634
            "energy_category_names" not in report['associated_equipment'].keys() or \
635
            len(report['associated_equipment']["energy_category_names"]) == 0 \
636
            or 'associated_equipment_names_array' not in report['associated_equipment'].keys() \
637
            or report['associated_equipment']['associated_equipment_names_array'] is None \
638
            or len(report['associated_equipment']['associated_equipment_names_array']) == 0 \
639
            or len(report['associated_equipment']['associated_equipment_names_array'][0]) == 0:
640
        pass
641
    else:
642
        associated_equipment = report['associated_equipment']
643
644
        ws['B' + str(current_row_number)].font = title_font
645
        ws['B' + str(current_row_number)] = name + ' ' + _('Associated Equipment Data')
646
647
        current_row_number += 1
648
649
        ws.row_dimensions[current_row_number].height = 60
650
        ws['B' + str(current_row_number)].fill = table_fill
651
        ws['B' + str(current_row_number)].font = name_font
652
        ws['B' + str(current_row_number)].alignment = c_c_alignment
653
        ws['B' + str(current_row_number)].border = f_border
654
        ws['B' + str(current_row_number)] = _('Associated Equipment')
655
        ca_len = len(associated_equipment['energy_category_names'])
656
        for i in range(0, ca_len):
657
            row = chr(ord('C') + i)
658
            ws[row + str(current_row_number)].fill = table_fill
659
            ws[row + str(current_row_number)].font = name_font
660
            ws[row + str(current_row_number)].alignment = c_c_alignment
661
            ws[row + str(current_row_number)].border = f_border
662
            ws[row + str(current_row_number)] = \
663
                associated_equipment['energy_category_names'][i] + " (" + associated_equipment['units'][i] + ")"
664
665
        associated_equipment_len = len(associated_equipment['associated_equipment_names_array'][0])
666
        for i in range(0, associated_equipment_len):
667
            current_row_number += 1
668
            row = str(current_row_number)
669
670
            ws['B' + row].font = title_font
671
            ws['B' + row].alignment = c_c_alignment
672
            ws['B' + row] = associated_equipment['associated_equipment_names_array'][0][i]
673
            ws['B' + row].border = f_border
674
            for j in range(0, ca_len):
675
                col = chr(ord('C') + j)
676
                ws[col + row].font = title_font
677
                ws[col + row].alignment = c_c_alignment
678
                ws[col + row] = round(associated_equipment['subtotals_array'][j][i], 2) \
679
                    if associated_equipment['subtotals_array'][j][i] is not None else ''
680
                ws[col + row].border = f_border
681
    ####################################################################################################################
682
    current_sheet_parameters_row_number = table_start_draw_flag + len(reporting_period_data['names']) * 6 + 1
683
    if 'parameters' not in report.keys() or \
684
            report['parameters'] is None or \
685
            'names' not in report['parameters'].keys() or \
686
            report['parameters']['names'] is None or \
687
            len(report['parameters']['names']) == 0 or \
688
            'timestamps' not in report['parameters'].keys() or \
689
            report['parameters']['timestamps'] is None or \
690
            len(report['parameters']['timestamps']) == 0 or \
691
            'values' not in report['parameters'].keys() or \
692
            report['parameters']['values'] is None or \
693
            len(report['parameters']['values']) == 0 or \
694
            timestamps_data_all_equal_0(report['parameters']['timestamps']):
695
        pass
696
    else:
697
        ################################################################################################################
698
        # new worksheet
699
        ################################################################################################################
700
701
        parameters_data = report['parameters']
702
        parameters_names_len = len(parameters_data['names'])
703
704
        file_name = (re.sub(r'[^A-Z]', '', ws.title))+'tatistics_'
705
        parameters_ws = wb.create_sheet(file_name + _('Parameters'))
706
707
        parameters_timestamps_data_max_len = \
708
            get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps']))
709
710
        # Row height
711
        parameters_ws.row_dimensions[1].height = 102
712
        for i in range(2, 7 + 1):
713
            parameters_ws.row_dimensions[i].height = 42
714
715
        for i in range(8, parameters_timestamps_data_max_len + 10):
716
            parameters_ws.row_dimensions[i].height = 60
717
718
        # Col width
719
        parameters_ws.column_dimensions['A'].width = 1.5
720
721
        parameters_ws.column_dimensions['B'].width = 25.0
722
723
        for i in range(3, 12+parameters_names_len*3):
724
            parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0
725
726
        # Img
727
        img = Image("excelexporters/myems.png")
728
        parameters_ws.add_image(img, 'A1')
729
730
        # Title
731
        parameters_ws['B3'].alignment = b_r_alignment
732
        parameters_ws['B3'] = _('Name') + ':'
733
        parameters_ws['C3'].border = b_border
734
        parameters_ws['C3'].alignment = b_c_alignment
735
        parameters_ws['C3'] = name
736
737
        parameters_ws['D3'].alignment = b_r_alignment
738
        parameters_ws['D3'] = _('Period Type') + ':'
739
        parameters_ws['E3'].border = b_border
740
        parameters_ws['E3'].alignment = b_c_alignment
741
        parameters_ws['E3'] = period_type
742
743
        parameters_ws['B4'].alignment = b_r_alignment
744
        parameters_ws['B4'] = _('Reporting Start Datetime') + ':'
745
        parameters_ws['C4'].border = b_border
746
        parameters_ws['C4'].alignment = b_c_alignment
747
        parameters_ws['C4'] = reporting_start_datetime_local
748
749
        parameters_ws['D4'].alignment = b_r_alignment
750
        parameters_ws['D4'] = _('Reporting End Datetime') + ':'
751
        parameters_ws['E4'].border = b_border
752
        parameters_ws['E4'].alignment = b_c_alignment
753
        parameters_ws['E4'] = reporting_end_datetime_local
754
755
        parameters_ws_current_row_number = 6
756
757
        parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font
758
        parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' ' + _('Parameters')
759
760
        parameters_ws_current_row_number += 1
761
762
        parameters_table_start_row_number = parameters_ws_current_row_number
763
764
        parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80
765
766
        parameters_ws_current_row_number += 1
767
768
        table_current_col_number = 2
769
770
        for i in range(0, parameters_names_len):
771
772
            if len(parameters_data['timestamps'][i]) == 0:
773
                continue
774
775
            col = format_cell.get_column_letter(table_current_col_number)
776
777
            parameters_ws[col + str(parameters_ws_current_row_number-1)].fill = table_fill
778
            parameters_ws[col + str(parameters_ws_current_row_number-1)].border = f_border
779
780
            col = format_cell.get_column_letter(table_current_col_number + 1)
781
782
            parameters_ws[col + str(parameters_ws_current_row_number-1)].fill = table_fill
783
            parameters_ws[col + str(parameters_ws_current_row_number-1)].border = f_border
784
            parameters_ws[col + str(parameters_ws_current_row_number-1)].font = name_font
785
            parameters_ws[col + str(parameters_ws_current_row_number-1)].alignment = c_c_alignment
786
            parameters_ws[col + str(parameters_ws_current_row_number-1)] = parameters_data['names'][i]
787
788
            table_current_row_number = parameters_ws_current_row_number
789
790
            for j, value in enumerate(list(parameters_data['timestamps'][i])):
791
                col = format_cell.get_column_letter(table_current_col_number)
792
793
                parameters_ws[col + str(table_current_row_number)].border = f_border
794
                parameters_ws[col + str(table_current_row_number)].font = title_font
795
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
796
                parameters_ws[col + str(table_current_row_number)] = value
797
798
                col = format_cell.get_column_letter(table_current_col_number + 1)
799
800
                parameters_ws[col + str(table_current_row_number)].border = f_border
801
                parameters_ws[col + str(table_current_row_number)].font = title_font
802
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
803
                parameters_ws[col + str(table_current_row_number)] = round(parameters_data['values'][i][j], 2)
804
805
                table_current_row_number += 1
806
807
            table_current_col_number = table_current_col_number + 3
808
809
        ################################################################################################################
810
        # parameters chart and parameters table
811
        ################################################################################################################
812
813
        ws['B' + str(current_sheet_parameters_row_number)].font = title_font
814
        ws['B' + str(current_sheet_parameters_row_number)] = name + ' ' + _('Parameters')
815
816
        current_sheet_parameters_row_number += 1
817
818
        chart_start_row_number = current_sheet_parameters_row_number
819
820
        col_index = 0
821
822
        for i in range(0, parameters_names_len):
823
824
            if len(parameters_data['timestamps'][i]) == 0:
825
                continue
826
827
            line = LineChart()
828
            data_col = 3+col_index*3
829
            labels_col = 2+col_index*3
830
            col_index += 1
831
            line.title = _('Parameters') + ' - ' + \
832
                parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value
833
            labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1,
834
                               max_row=(len(parameters_data['timestamps'][i])+parameters_table_start_row_number))
835
            line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number,
836
                                  max_row=(len(parameters_data['timestamps'][i])+parameters_table_start_row_number))
837
            line.add_data(line_data, titles_from_data=True)
838
            line.set_categories(labels)
839
            line_data = line.series[0]
840
            line_data.marker.symbol = "circle"
841
            line_data.smooth = True
842
            line.x_axis.crosses = 'min'
843
            line.height = 8.25
844
            line.width = 24
845
            line.dLbls = DataLabelList()
846
            line.dLbls.dLblPos = 't'
847
            line.dLbls.showVal = False
848
            line.dLbls.showPercent = False
849
            chart_col = 'B'
850
            chart_cell = chart_col + str(chart_start_row_number)
851
            chart_start_row_number += 6
852
            ws.add_chart(line, chart_cell)
853
854
        current_sheet_parameters_row_number = chart_start_row_number
855
856
        current_sheet_parameters_row_number += 1
857
    ####################################################################################################################
858
    filename = str(uuid.uuid4()) + '.xlsx'
859
    wb.save(filename)
860
861
    return filename
862
863
864
def timestamps_data_all_equal_0(lists):
865
    for i, value in enumerate(list(lists)):
866
        if len(value) > 0:
867
            return False
868
869
    return True
870
871
872
def get_parameters_timestamps_lists_max_len(parameters_timestamps_lists):
873
    max_len = 0
874
    for i, value in enumerate(list(parameters_timestamps_lists)):
875
        if len(value) > max_len:
876
            max_len = len(value)
877
878
    return max_len
879
880
881
def timestamps_data_not_equal_0(lists):
882
    number = 0
883
    for i, value in enumerate(list(lists)):
884
        if len(value) > 0:
885
            number += 1
886
    return number
887
888
889 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...
890
    timestamps = base_period_data['timestamps']
891
892
    if len(timestamps) == 0:
893
        return False
894
895
    for timestamp in timestamps:
896
        if len(timestamp) > 0:
897
            return True
898
899
    return False
900