Passed
Push — master ( 283033...66ce56 )
by Guangyu
07:51 queued 11s
created

myems-api/excelexporters/storesaving.py (1 issue)

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