Passed
Push — master ( c8b356...ca4867 )
by Guangyu
09:12 queued 13s
created

is_base_period_timestamp_exists()   A

Complexity

Conditions 4

Size

Total Lines 11
Code Lines 8

Duplication

Lines 11
Ratio 100 %

Importance

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