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

excelexporters.spaceoutput.export()   B

Complexity

Conditions 5

Size

Total Lines 46
Code Lines 32

Duplication

Lines 46
Ratio 100 %

Importance

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

How to fix   Many Parameters   

Many Parameters

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

There are several approaches to avoid long parameter lists:

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