Passed
Push — master ( 8ba0c1...7a1547 )
by Guangyu
09:24 queued 12s
created

excelexporters.virtualmetersaving.sum_list()   A

Complexity

Conditions 2

Size

Total Lines 5
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 2
nop 1
1
import base64
2
import uuid
3
import os
4
from decimal import Decimal
5
from openpyxl.chart import PieChart, LineChart, BarChart, Reference
6
from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
7
from openpyxl.drawing.image import Image
8
from openpyxl import Workbook
9
from openpyxl.chart.label import DataLabelList
10
import openpyxl.utils.cell as format_cell
11
12
13
########################################################################################################################
14
# PROCEDURES
15
# Step 1: Validate the report data
16
# Step 2: Generate excel file
17
# Step 3: Encode the excel file bytes to Base64
18
########################################################################################################################
19
20
21 View Code Duplication
def export(report,
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
22
           name,
23
           reporting_start_datetime_local,
24
           reporting_end_datetime_local,
25
           period_type):
26
    ####################################################################################################################
27
    # Step 1: Validate the report data
28
    ####################################################################################################################
29
    if report is None:
30
        return None
31
32
    ####################################################################################################################
33
    # Step 2: Generate excel file from the report data
34
    ####################################################################################################################
35
    filename = generate_excel(report,
36
                              name,
37
                              reporting_start_datetime_local,
38
                              reporting_end_datetime_local,
39
                              period_type)
40
    ####################################################################################################################
41
    # Step 3: Encode the excel file to Base64
42
    ####################################################################################################################
43
    binary_file_data = b''
44
    try:
45
        with open(filename, 'rb') as binary_file:
46
            binary_file_data = binary_file.read()
47
    except IOError as ex:
48
        pass
49
50
    # Base64 encode the bytes
51
    base64_encoded_data = base64.b64encode(binary_file_data)
52
    # get the Base64 encoded data using human-readable characters.
53
    base64_message = base64_encoded_data.decode('utf-8')
54
    # delete the file from server
55
    try:
56
        os.remove(filename)
57
    except NotImplementedError as ex:
58
        pass
59
    return base64_message
60
61
62
def generate_excel(report,
63
                   name,
64
                   reporting_start_datetime_local,
65
                   reporting_end_datetime_local,
66
                   period_type):
67
    print(report)
68
    wb = Workbook()
69
    ws = wb.active
70
    ws.title = "VirtualMeterSaving"
71
72
    # Row height
73
    ws.row_dimensions[1].height = 102
74
    for i in range(2, 2000 + 1):
75
        ws.row_dimensions[i].height = 42
76
77
    # Col width
78
    ws.column_dimensions['A'].width = 1.5
79
80
    ws.column_dimensions['B'].width = 25.0
81
82
    for i in range(ord('C'), ord('L')):
83
        ws.column_dimensions[chr(i)].width = 15.0
84
85
    # Font
86
    name_font = Font(name='Arial', size=15, bold=True)
87
    title_font = Font(name='Arial', size=15, bold=True)
88
89
    table_fill = PatternFill(fill_type='solid', fgColor='1F497D')
90
    f_border = Border(left=Side(border_style='medium', color='00000000'),
91
                      right=Side(border_style='medium', color='00000000'),
92
                      bottom=Side(border_style='medium', color='00000000'),
93
                      top=Side(border_style='medium', color='00000000')
94
                      )
95
    b_border = Border(
96
        bottom=Side(border_style='medium', color='00000000'),
97
    )
98
99
    b_c_alignment = Alignment(vertical='bottom',
100
                              horizontal='center',
101
                              text_rotation=0,
102
                              wrap_text=True,
103
                              shrink_to_fit=False,
104
                              indent=0)
105
    c_c_alignment = Alignment(vertical='center',
106
                              horizontal='center',
107
                              text_rotation=0,
108
                              wrap_text=True,
109
                              shrink_to_fit=False,
110
                              indent=0)
111
    b_r_alignment = Alignment(vertical='bottom',
112
                              horizontal='right',
113
                              text_rotation=0,
114
                              wrap_text=True,
115
                              shrink_to_fit=False,
116
                              indent=0)
117
118
    # Img
119
    img = Image("excelexporters/myems.png")
120
    ws.add_image(img, 'A1')
121
122
    # Title
123
    ws['B3'].alignment = b_r_alignment
124
    ws['B3'] = 'Name:'
125
    ws['C3'].border = b_border
126
    ws['C3'].alignment = b_c_alignment
127
    ws['C3'] = name
128
129
    ws['D3'].alignment = b_r_alignment
130
    ws['D3'] = 'Period:'
131
    ws['E3'].border = b_border
132
    ws['E3'].alignment = b_c_alignment
133
    ws['E3'] = period_type
134
135
    ws['B4'].alignment = b_r_alignment
136
    ws['B4'] = 'Reporting Start Datetime:'
137
    ws['C4'].border = b_border
138
    ws['C4'].alignment = b_c_alignment
139
    ws['C4'] = reporting_start_datetime_local
140
141
    ws['D4'].alignment = b_r_alignment
142
    ws['D4'] = 'Reporting End Datetime:'
143
    ws['E4'].border = b_border
144
    ws['E4'].alignment = b_c_alignment
145
    ws['E4'] = reporting_end_datetime_local
146
147
    if "reporting_period" not in report.keys() or \
148
            "names" not in report['reporting_period'].keys() or len(report['reporting_period']['names']) == 0:
149
        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...
150
        wb.save(filename)
151
152
        return filename
153
154
    ####################################################################################################################
155
156
    current_row_number = 6
157
158
    reporting_period_data = report['reporting_period']
159
160
    has_names_data_flag = True
161
162
    if "names" not in reporting_period_data.keys() or \
163
            reporting_period_data['names'] is None or \
164
            len(reporting_period_data['names']) == 0:
165
        has_names_data_flag = False
166
167
    if has_names_data_flag:
168
        ws['B' + str(current_row_number)].font = title_font
169
        ws['B' + str(current_row_number)] = name + ' ' + 'Reporting Period Savings'
170
171
        current_row_number += 1
172
173
        ws.row_dimensions[current_row_number].height = 75
174
        ws['B' + str(current_row_number)].fill = table_fill
175
        ws['B' + str(current_row_number)].border = f_border
176
177
        col = 'C'
178
179
        ws[col + str(current_row_number)].fill = table_fill
180
        ws[col + str(current_row_number)].font = name_font
181
        ws[col + str(current_row_number)].alignment = c_c_alignment
182
        ws[col + str(current_row_number)].border = f_border
183
        ws[col + str(current_row_number)] = \
184
            reporting_period_data['names'] + "  (Baseline - Actual) (" + reporting_period_data['units'] + ")"
185
186
        col = chr(ord(col) + 1)
187
188
        ws[col + str(current_row_number)].fill = table_fill
189
        ws[col + str(current_row_number)].font = name_font
190
        ws[col + str(current_row_number)].alignment = c_c_alignment
191
        ws[col + str(current_row_number)].border = f_border
192
        ws[col + str(current_row_number)] = 'Ton of Standard Coal  (Baseline - Actual) (TCE)'
193
194
        col = chr(ord(col) + 1)
195
196
        ws[col + str(current_row_number)].fill = table_fill
197
        ws[col + str(current_row_number)].font = name_font
198
        ws[col + str(current_row_number)].alignment = c_c_alignment
199
        ws[col + str(current_row_number)].border = f_border
200
        ws[col + str(current_row_number)] = 'Ton of Carbon Dioxide Emissions  (Baseline - Actual) (TCO2E)'
201
202
        current_row_number += 1
203
204
        ws['B' + str(current_row_number)].font = title_font
205
        ws['B' + str(current_row_number)].alignment = c_c_alignment
206
        ws['B' + str(current_row_number)].border = f_border
207
        ws['B' + str(current_row_number)] = 'Savings'
208
209
        col = 'C'
210
211
        ws[col + str(current_row_number)].font = name_font
212
        ws[col + str(current_row_number)].alignment = c_c_alignment
213
        ws[col + str(current_row_number)].border = f_border
214
        ws[col + str(current_row_number)] = round(reporting_period_data['subtotals_saving'], 2)
215
216
        col = chr(ord(col) + 1)
217
218
        ws[col + str(current_row_number)].font = name_font
219
        ws[col + str(current_row_number)].alignment = c_c_alignment
220
        ws[col + str(current_row_number)].border = f_border
221
        ws[col + str(current_row_number)] = round(reporting_period_data['total_in_kgce_saving'] / 1000, 2)
222
223
        col = chr(ord(col) + 1)
224
225
        ws[col + str(current_row_number)].font = name_font
226
        ws[col + str(current_row_number)].alignment = c_c_alignment
227
        ws[col + str(current_row_number)].border = f_border
228
        ws[col + str(current_row_number)] = round(reporting_period_data['total_in_kgco2e_saving'] / 1000, 2)
229
230
        current_row_number += 1
231
232
        ws['B' + str(current_row_number)].font = title_font
233
        ws['B' + str(current_row_number)].alignment = c_c_alignment
234
        ws['B' + str(current_row_number)].border = f_border
235
        ws['B' + str(current_row_number)] = 'Increment Rate'
236
237
        col = 'C'
238
239
        ws[col + str(current_row_number)].font = name_font
240
        ws[col + str(current_row_number)].alignment = c_c_alignment
241
        ws[col + str(current_row_number)].border = f_border
242
        ws[col + str(current_row_number)] = str(
243
            round(reporting_period_data['increment_rates_saving'] * 100, 2)) + '%' \
244
            if reporting_period_data['increment_rates_saving'] is not None else '-'
245
246
        col = chr(ord(col) + 1)
247
248
        ws[col + str(current_row_number)].font = name_font
249
        ws[col + str(current_row_number)].alignment = c_c_alignment
250
        ws[col + str(current_row_number)].border = f_border
251
        ws[col + str(current_row_number)] = str(
252
            round(reporting_period_data['increment_rate_in_kgce_saving'] * 100, 2)) + '%' \
253
            if reporting_period_data['increment_rate_in_kgce_saving'] is not None else '-'
254
255
        col = chr(ord(col) + 1)
256
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['increment_rate_in_kgco2e_saving'] * 100, 2)) + '%' \
262
            if reporting_period_data['increment_rate_in_kgco2e_saving'] 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 + ' ' + 'Ton of Standard Coal(TCE) by Energy Category'
268
269
        current_row_number += 1
270
        table_start_row_number = current_row_number
271
        chart_start_row_number = current_row_number
272
273
        ws.row_dimensions[current_row_number].height = 60
274
        ws['B' + str(current_row_number)].fill = table_fill
275
        ws['B' + str(current_row_number)].border = f_border
276
277
        ws['C' + str(current_row_number)].fill = table_fill
278
        ws['C' + str(current_row_number)].font = name_font
279
        ws['C' + str(current_row_number)].alignment = c_c_alignment
280
        ws['C' + str(current_row_number)].border = f_border
281
        ws['C' + str(current_row_number)] = 'Savings'
282
283
        ws['D' + str(current_row_number)].fill = table_fill
284
        ws['D' + str(current_row_number)].font = name_font
285
        ws['D' + str(current_row_number)].alignment = c_c_alignment
286
        ws['D' + str(current_row_number)].border = f_border
287
        ws['D' + str(current_row_number)] = 'Ton of Standard Coal(TCE) by Energy Category'
288
289
        current_row_number += 1
290
291
        subtotals_in_kgce_saving_sum = reporting_period_data['subtotals_in_kgce_saving']
292
293
        ws['B' + str(current_row_number)].font = title_font
294
        ws['B' + str(current_row_number)].alignment = c_c_alignment
295
        ws['B' + str(current_row_number)].border = f_border
296
        ws['B' + str(current_row_number)] = reporting_period_data['names']
297
298
        ws['C' + str(current_row_number)].font = name_font
299
        ws['C' + str(current_row_number)].alignment = c_c_alignment
300
        ws['C' + str(current_row_number)].border = f_border
301
        ws['C' + str(current_row_number)] = round(reporting_period_data['subtotals_in_kgce_saving'] / 1000, 3)
302
303
        ws['D' + str(current_row_number)].font = name_font
304
        ws['D' + str(current_row_number)].alignment = c_c_alignment
305
        ws['D' + str(current_row_number)].border = f_border
306
        ws['D' + str(current_row_number)] = str(round(reporting_period_data['subtotals_in_kgce_saving'] /
307
                                                      subtotals_in_kgce_saving_sum * 100, 2)) + '%' \
308
            if abs(subtotals_in_kgce_saving_sum) > 0 else '-'
309
310
        current_row_number += 5
311
312
        table_end_row_number = current_row_number - 1
313
314
        pie = PieChart()
315
        pie.title = name + ' ' + 'Ton of Standard Coal(TCE) by Energy Category'
316
        labels = Reference(ws, min_col=2, min_row=table_start_row_number + 1, max_row=table_end_row_number)
317
        pie_data = Reference(ws, min_col=3, min_row=table_start_row_number, max_row=table_end_row_number)
318
        pie.add_data(pie_data, titles_from_data=True)
319
        pie.set_categories(labels)
320
        pie.height = 7.25
321
        pie.width = 9
322
        s1 = pie.series[0]
323
        s1.dLbls = DataLabelList()
324
        s1.dLbls.showCatName = False
325
        s1.dLbls.showVal = True
326
        s1.dLbls.showPercent = True
327
        ws.add_chart(pie, 'E' + str(chart_start_row_number))
328
329
        ws['B' + str(current_row_number)].font = title_font
330
        ws['B' + str(current_row_number)] = name + ' ' + 'Ton of Carbon Dioxide Emissions(TCO2E) by Energy Category'
331
332
        current_row_number += 1
333
        table_start_row_number = current_row_number
334
        chart_start_row_number = current_row_number
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
340
        ws['C' + str(current_row_number)].fill = table_fill
341
        ws['C' + str(current_row_number)].font = name_font
342
        ws['C' + str(current_row_number)].alignment = c_c_alignment
343
        ws['C' + str(current_row_number)].border = f_border
344
        ws['C' + str(current_row_number)] = 'Savings'
345
346
        ws['D' + str(current_row_number)].fill = table_fill
347
        ws['D' + str(current_row_number)].font = name_font
348
        ws['D' + str(current_row_number)].alignment = c_c_alignment
349
        ws['D' + str(current_row_number)].border = f_border
350
        ws['D' + str(current_row_number)] = 'Ton of Carbon Dioxide Emissions(TCO2E) by Energy Category'
351
352
        current_row_number += 1
353
354
        subtotals_in_kgco2e_saving_sum = reporting_period_data['subtotals_in_kgco2e_saving']
355
356
        ws['B' + str(current_row_number)].font = title_font
357
        ws['B' + str(current_row_number)].alignment = c_c_alignment
358
        ws['B' + str(current_row_number)].border = f_border
359
        ws['B' + str(current_row_number)] = reporting_period_data['names']
360
361
        ws['C' + str(current_row_number)].font = name_font
362
        ws['C' + str(current_row_number)].alignment = c_c_alignment
363
        ws['C' + str(current_row_number)].border = f_border
364
        ws['C' + str(current_row_number)] = round(reporting_period_data['subtotals_in_kgco2e_saving'] / 1000, 3)
365
366
        ws['D' + str(current_row_number)].font = name_font
367
        ws['D' + str(current_row_number)].alignment = c_c_alignment
368
        ws['D' + str(current_row_number)].border = f_border
369
        ws['D' + str(current_row_number)] = str(round(reporting_period_data['subtotals_in_kgco2e_saving'] /
370
                                                      subtotals_in_kgco2e_saving_sum * 100, 2)) + '%' \
371
            if abs(subtotals_in_kgco2e_saving_sum) > 0 else '-'
372
373
        current_row_number += 1
374
375
        table_end_row_number = current_row_number - 1
376
377
        current_row_number += 4
378
379
        pie = PieChart()
380
        pie.title = name + ' ' + 'Ton of Carbon Dioxide Emissions(TCO2E) by Energy Category'
381
        labels = Reference(ws, min_col=2, min_row=table_start_row_number + 1, max_row=table_end_row_number)
382
        pie_data = Reference(ws, min_col=3, min_row=table_start_row_number, max_row=table_end_row_number)
383
        pie.add_data(pie_data, titles_from_data=True)
384
        pie.set_categories(labels)
385
        pie.height = 7.25
386
        pie.width = 9
387
        s1 = pie.series[0]
388
        s1.dLbls = DataLabelList()
389
        s1.dLbls.showCatName = False
390
        s1.dLbls.showVal = True
391
        s1.dLbls.showPercent = True
392
        ws.add_chart(pie, 'E' + str(chart_start_row_number))
393
394
    ####################################################################################################################
395
396
    has_values_saving_data = True
397
    has_timestamps_data = True
398
399
    if 'values_saving' not in reporting_period_data.keys() or \
400
            reporting_period_data['values_saving'] is None or \
401
            len(reporting_period_data['values_saving']) == 0:
402
        has_values_saving_data = False
403
404
    if 'timestamps' not in reporting_period_data.keys() or \
405
            reporting_period_data['timestamps'] is None or \
406
            len(reporting_period_data['timestamps']) == 0 or \
407
            len(reporting_period_data['timestamps'][0]) == 0:
408
        has_timestamps_data = False
409
410
    current_row_number += 1
411
    chart_start_row_number = current_row_number
412
    if has_values_saving_data and has_timestamps_data:
413
        time = reporting_period_data['timestamps']
414
        parameters_names_len = len(report['parameters']['names'])
415
        parameters_parameters_datas_len = 0
416
417
        ws['B' + str(current_row_number - 1)].font = title_font
418
        ws['B' + str(current_row_number - 1)] = name + ' ' + 'Detailed Data'
419
420
        for i in range(0, parameters_names_len):
421
            if len(report['parameters']['timestamps'][i]) == 0:
422
                continue
423
            parameters_parameters_datas_len += 1
424
425
        current_row_number = current_row_number + (1 + parameters_parameters_datas_len) * 6 + 2
426
        table_start_row_number = current_row_number
427
428
        ws.row_dimensions[current_row_number].height = 60
429
        ws['B' + str(current_row_number)].fill = table_fill
430
        ws['B' + str(current_row_number)].font = title_font
431
        ws['B' + str(current_row_number)].alignment = c_c_alignment
432
        ws['B' + str(current_row_number)].border = f_border
433
        ws['B' + str(current_row_number)] = 'Datetime'
434
435
        col = 'C'
436
437
        ws[col + str(current_row_number)].fill = table_fill
438
        ws[col + str(current_row_number)].font = title_font
439
        ws[col + str(current_row_number)].alignment = c_c_alignment
440
        ws[col + str(current_row_number)].border = f_border
441
        ws[col + str(current_row_number)] = \
442
            reporting_period_data['names'] + ':Actual' + " (" + reporting_period_data['units'] + ")"
443
        col = chr(ord(col) + 1)
444
445
        ws[col + str(current_row_number)].fill = table_fill
446
        ws[col + str(current_row_number)].font = title_font
447
        ws[col + str(current_row_number)].alignment = c_c_alignment
448
        ws[col + str(current_row_number)].border = f_border
449
        ws[col + str(current_row_number)] = \
450
            reporting_period_data['names'] + ':Baseline' + " (" + reporting_period_data['units'] + ")"
451
        col = chr(ord(col) + 1)
452
453
        ws[col + str(current_row_number)].fill = table_fill
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)] = \
458
            reporting_period_data['names'] + ':Saving' + " (" + reporting_period_data['units'] + ")"
459
460
        current_row_number += 1
461
        print(time)
462
        for i in range(0, len(time)):
463
            ws['B' + str(current_row_number)].font = title_font
464
            ws['B' + str(current_row_number)].alignment = c_c_alignment
465
            ws['B' + str(current_row_number)].border = f_border
466
            ws['B' + str(current_row_number)] = time[i]
467
468
            col = 'C'
469
470
            ws[col + str(current_row_number)].font = title_font
471
            ws[col + str(current_row_number)].alignment = c_c_alignment
472
            ws[col + str(current_row_number)].border = f_border
473
            ws[col + str(current_row_number)] = round(reporting_period_data['values_actual'][i], 2) \
474
                if reporting_period_data['values_actual'] is not None else 0.00
475
            col = chr(ord(col) + 1)
476
477
            ws[col + str(current_row_number)].font = title_font
478
            ws[col + str(current_row_number)].alignment = c_c_alignment
479
            ws[col + str(current_row_number)].border = f_border
480
            ws[col + str(current_row_number)] = round(reporting_period_data['values_baseline'][i], 2) \
481
                if reporting_period_data['values_baseline'][i] is not None else 0.00
482
            col = chr(ord(col) + 1)
483
484
            ws[col + str(current_row_number)].font = title_font
485
            ws[col + str(current_row_number)].alignment = c_c_alignment
486
            ws[col + str(current_row_number)].border = f_border
487
            ws[col + str(current_row_number)] = round(reporting_period_data['values_saving'][i], 2) \
488
                if reporting_period_data['values_saving'][i] is not None else 0.00
489
490
            current_row_number += 1
491
492
        table_end_row_number = current_row_number - 1
493
494
        ws['B' + str(current_row_number)].font = title_font
495
        ws['B' + str(current_row_number)].alignment = c_c_alignment
496
        ws['B' + str(current_row_number)].border = f_border
497
        ws['B' + str(current_row_number)] = 'Subtotal'
498
499
        col = 'C'
500
501
        ws[col + str(current_row_number)].font = title_font
502
        ws[col + str(current_row_number)].alignment = c_c_alignment
503
        ws[col + str(current_row_number)].border = f_border
504
        ws[col + str(current_row_number)] = round(reporting_period_data['subtotals_actual'], 2)
505
        col = chr(ord(col) + 1)
506
507
        ws[col + str(current_row_number)].font = title_font
508
        ws[col + str(current_row_number)].alignment = c_c_alignment
509
        ws[col + str(current_row_number)].border = f_border
510
        ws[col + str(current_row_number)] = round(reporting_period_data['subtotals_baseline'], 2)
511
        col = chr(ord(col) + 1)
512
513
        ws[col + str(current_row_number)].font = title_font
514
        ws[col + str(current_row_number)].alignment = c_c_alignment
515
        ws[col + str(current_row_number)].border = f_border
516
        ws[col + str(current_row_number)] = round(reporting_period_data['subtotals_saving'], 2)
517
        current_row_number += 2
518
519
        format_time_width_number = 1.0
520
        min_len_number = 1.0
521
        min_width_number = 11.0
522
523
        if period_type == 'hourly':
524
            format_time_width_number = 4.0
525
            min_len_number = 2
526
            min_width_number = 12.0
527
        elif period_type == 'daily':
528
            format_time_width_number = 2.5
529
            min_len_number = 4
530
            min_width_number = 14.0
531
        elif period_type == 'monthly':
532
            format_time_width_number = 2.1
533
            min_len_number = 4
534
            min_width_number = 12.4
535
        elif period_type == 'yearly':
536
            format_time_width_number = 1.5
537
            min_len_number = 5
538
            min_width_number = 11.5
539
540
        line = LineChart()
541
        line.title = 'Reporting Period Savings - ' + \
542
                     reporting_period_data['names'] + " (" + reporting_period_data['units'] + ")"
543
        labels = Reference(ws, min_col=2, min_row=table_start_row_number + 1, max_row=table_end_row_number)
544
        line_data = Reference(ws, min_col=3, max_col=4, min_row=table_start_row_number, max_row=table_end_row_number)
545
        line.add_data(line_data, titles_from_data=True)
546
        line.set_categories(labels)
547
        line_data = line.series[0]
548
        line_data.marker.symbol = "circle"
549
        line_data.smooth = True
550
        line.height = 8.25
551
        line.width = format_time_width_number * len(time) if len(time) > min_len_number else min_width_number
552
        if line.width > 24:
553
            line.width = 24
554
        line.x_axis.crosses = 'min'
555
        line.dLbls = DataLabelList()
556
        line.dLbls.dLblPos = 't'
557
        line.dLbls.showVal = True
558
        line.dLbls.showPercent = False
559
        chart_col = 'B'
560
        chart_cell = chart_col + str(chart_start_row_number)
561
        ws.add_chart(line, chart_cell)
562
563
        bar = BarChart()
564
        bar.type = "col"
565
        bar.style = 10
566
        bar.height = 8.25
567
        bar.width = line.width
568
        bar.title = 'Reporting Period Savings - ' + \
569
                    reporting_period_data['names'] + " (" + reporting_period_data['units'] + ")"
570
        labels = Reference(ws, min_col=2, min_row=table_start_row_number + 1, max_row=table_end_row_number)
571
        bar_data = Reference(ws, min_col=5, min_row=table_start_row_number, max_row=table_end_row_number)
572
        bar.add_data(bar_data, titles_from_data=True)
573
        bar.set_categories(labels)
574
        bar.dLbls = DataLabelList()
575
        bar.dLbls.showVal = True
576
        bar.dLbls.showPercent = False
577
        chart_col = 'B'
578
        chart_cell = chart_col + str(chart_start_row_number + 1 * 6 + 1)
579
        bar.shape = 4
580
        ws.add_chart(bar, chart_cell)
581
582
    ####################################################################################################################
583
    has_parameters_names_and_timestamps_and_values_data = True
584
585
    current_sheet_parameters_row_number = chart_start_row_number + 1 * 6
586
    if 'parameters' not in report.keys() or \
587
            report['parameters'] is None or \
588
            'names' not in report['parameters'].keys() or \
589
            report['parameters']['names'] is None or \
590
            len(report['parameters']['names']) == 0 or \
591
            'timestamps' not in report['parameters'].keys() or \
592
            report['parameters']['timestamps'] is None or \
593
            len(report['parameters']['timestamps']) == 0 or \
594
            'values' not in report['parameters'].keys() or \
595
            report['parameters']['values'] is None or \
596
            len(report['parameters']['values']) == 0 or \
597
            timestamps_data_all_equal_0(report['parameters']['timestamps']):
598
        has_parameters_names_and_timestamps_and_values_data = False
599 View Code Duplication
    if has_parameters_names_and_timestamps_and_values_data:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
600
601
        ################################################################################################################
602
        # new worksheet
603
        ################################################################################################################
604
605
        parameters_data = report['parameters']
606
607
        parameters_names_len = len(parameters_data['names'])
608
609
        file_name = ws.title
610
        parameters_ws = wb.create_sheet(file_name + 'Parameters')
611
612
        parameters_timestamps_data_max_len = \
613
            get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps']))
614
615
        # Row height
616
        parameters_ws.row_dimensions[1].height = 102
617
        for i in range(2, 7 + 1):
618
            parameters_ws.row_dimensions[i].height = 42
619
620
        for i in range(8, parameters_timestamps_data_max_len + 10):
621
            parameters_ws.row_dimensions[i].height = 60
622
623
        # Col width
624
        parameters_ws.column_dimensions['A'].width = 1.5
625
626
        parameters_ws.column_dimensions['B'].width = 25.0
627
628
        for i in range(3, 12 + parameters_names_len * 3):
629
            parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0
630
631
        # Img
632
        img = Image("excelexporters/myems.png")
633
        parameters_ws.add_image(img, 'A1')
634
635
        # Title
636
        parameters_ws['B3'].alignment = b_r_alignment
637
        parameters_ws['B3'] = 'Name:'
638
        parameters_ws['C3'].border = b_border
639
        parameters_ws['C3'].alignment = b_c_alignment
640
        parameters_ws['C3'] = name
641
642
        parameters_ws['D3'].alignment = b_r_alignment
643
        parameters_ws['D3'] = 'Period:'
644
        parameters_ws['E3'].border = b_border
645
        parameters_ws['E3'].alignment = b_c_alignment
646
        parameters_ws['E3'] = period_type
647
648
        parameters_ws['B4'].alignment = b_r_alignment
649
        parameters_ws['B4'] = 'Reporting Start Datetime:'
650
        parameters_ws['C4'].border = b_border
651
        parameters_ws['C4'].alignment = b_c_alignment
652
        parameters_ws['C4'] = reporting_start_datetime_local
653
654
        parameters_ws['D4'].alignment = b_r_alignment
655
        parameters_ws['D4'] = 'Reporting End Datetime:'
656
        parameters_ws['E4'].border = b_border
657
        parameters_ws['E4'].alignment = b_c_alignment
658
        parameters_ws['E4'] = reporting_end_datetime_local
659
660
        parameters_ws_current_row_number = 6
661
662
        parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font
663
        parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' ' + 'Parameters'
664
665
        parameters_ws_current_row_number += 1
666
667
        parameters_table_start_row_number = parameters_ws_current_row_number
668
669
        parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80
670
671
        parameters_ws_current_row_number += 1
672
673
        table_current_col_number = 2
674
675
        for i in range(0, parameters_names_len):
676
677
            if len(parameters_data['timestamps'][i]) == 0:
678
                continue
679
680
            col = format_cell.get_column_letter(table_current_col_number)
681
682
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
683
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
684
685
            col = format_cell.get_column_letter(table_current_col_number + 1)
686
687
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
688
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
689
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].font = name_font
690
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].alignment = c_c_alignment
691
            parameters_ws[col + str(parameters_ws_current_row_number - 1)] = parameters_data['names'][i]
692
693
            table_current_row_number = parameters_ws_current_row_number
694
695
            for j, value in enumerate(list(parameters_data['timestamps'][i])):
696
                col = format_cell.get_column_letter(table_current_col_number)
697
698
                parameters_ws[col + str(table_current_row_number)].border = f_border
699
                parameters_ws[col + str(table_current_row_number)].font = title_font
700
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
701
                parameters_ws[col + str(table_current_row_number)] = value
702
703
                col = format_cell.get_column_letter(table_current_col_number + 1)
704
705
                parameters_ws[col + str(table_current_row_number)].border = f_border
706
                parameters_ws[col + str(table_current_row_number)].font = title_font
707
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
708
                parameters_ws[col + str(table_current_row_number)] = round(parameters_data['values'][i][j], 2)
709
710
                table_current_row_number += 1
711
712
            table_current_col_number = table_current_col_number + 3
713
714
        ################################################################################################################
715
        # parameters chart and parameters table
716
        ################################################################################################################
717
718
        ws['B' + str(current_sheet_parameters_row_number)].font = title_font
719
        ws['B' + str(current_sheet_parameters_row_number)] = name + ' ' + 'Parameters'
720
721
        current_sheet_parameters_row_number += 1
722
723
        chart_start_row_number = current_sheet_parameters_row_number
724
725
        col_index = 0
726
727
        for i in range(0, parameters_names_len):
728
729
            if len(parameters_data['timestamps'][i]) == 0:
730
                continue
731
732
            line = LineChart()
733
            data_col = 3 + col_index * 3
734
            labels_col = 2 + col_index * 3
735
            col_index += 1
736
            line.title = 'Parameters - ' + \
737
                         parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value
738
            labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1,
739
                               max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
740
            line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number,
741
                                  max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
742
            line.add_data(line_data, titles_from_data=True)
743
            line.set_categories(labels)
744
            line_data = line.series[0]
745
            line_data.marker.symbol = "circle"
746
            line_data.smooth = True
747
            line.x_axis.crosses = 'min'
748
            line.height = 8.25
749
            line.width = 24
750
            line.dLbls = DataLabelList()
751
            line.dLbls.dLblPos = 't'
752
            line.dLbls.showVal = False
753
            line.dLbls.showPercent = False
754
            chart_col = 'B'
755
            chart_cell = chart_col + str(chart_start_row_number)
756
            chart_start_row_number += 6
757
            ws.add_chart(line, chart_cell)
758
759
        current_sheet_parameters_row_number = chart_start_row_number
760
761
        current_sheet_parameters_row_number += 1
762
763
    filename = str(uuid.uuid4()) + '.xlsx'
764
    wb.save(filename)
765
766
    return filename
767
768
769
def sum_list(lists):
770
    total = Decimal(0)
771
    for i in range(0, len(lists)):
772
        total += lists[i]
773
    return total
774
775
776
def get_parameters_timestamps_lists_max_len(parameters_timestamps_lists):
777
    max_len = 0
778
    for i, value in enumerate(list(parameters_timestamps_lists)):
779
        if len(value) > max_len:
780
            max_len = len(value)
781
782
    return max_len
783
784
785
def timestamps_data_all_equal_0(lists):
786
    for i, value in enumerate(list(lists)):
787
        if len(value) > 0:
788
            return False
789
790
    return True
791