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

excelexporters.spacestatistics.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 uuid
5
6
import openpyxl.utils.cell as format_cell
7
from openpyxl import Workbook
8
from openpyxl.chart import LineChart, Reference
9
from openpyxl.chart.label import DataLabelList
10
from openpyxl.drawing.image import Image
11
from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
12
13
14
########################################################################################################################
15
# PROCEDURES
16
# Step 1: Validate the report data
17
# Step 2: Generate excel file
18
# Step 3: Encode the excel file to Base64
19
########################################################################################################################
20
21
22 View Code Duplication
def export(report,
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
23
           name,
24
           base_period_start_datetime_local,
25
           base_period_end_datetime_local,
26
           reporting_start_datetime_local,
27
           reporting_end_datetime_local,
28
           period_type,
29
           language):
30
    ####################################################################################################################
31
    # Step 1: Validate the report data
32
    ####################################################################################################################
33
    if report is None:
34
        return None
35
    print(report)
36
37
    ####################################################################################################################
38
    # Step 2: Generate excel file from the report data
39
    ####################################################################################################################
40
    filename = generate_excel(report,
41
                              name,
42
                              base_period_start_datetime_local,
43
                              base_period_end_datetime_local,
44
                              reporting_start_datetime_local,
45
                              reporting_end_datetime_local,
46
                              period_type,
47
                              language)
48
    ####################################################################################################################
49
    # Step 3: Encode the excel file to Base64
50
    ####################################################################################################################
51
    binary_file_data = b''
52
    try:
53
        with open(filename, 'rb') as binary_file:
54
            binary_file_data = binary_file.read()
55
    except IOError as ex:
56
        print(str(ex))
57
58
    # Base64 encode the bytes
59
    base64_encoded_data = base64.b64encode(binary_file_data)
60
    # get the Base64 encoded data using human-readable characters.
61
    base64_message = base64_encoded_data.decode('utf-8')
62
    # delete the file from server
63
    try:
64
        os.remove(filename)
65
    except NotImplementedError as ex:
66
        print(str(ex))
67
    return base64_message
68
69
70
def generate_excel(report,
71
                   name,
72
                   base_period_start_datetime_local,
73
                   base_period_end_datetime_local,
74
                   reporting_start_datetime_local,
75
                   reporting_end_datetime_local,
76
                   period_type,
77
                   language):
78
    locale_path = './i18n/'
79
    if language == 'zh_CN':
80
        trans = gettext.translation('myems', locale_path, languages=['zh_CN'])
81
    elif language == 'de':
82
        trans = gettext.translation('myems', locale_path, languages=['de'])
83
    elif language == 'en':
84
        trans = gettext.translation('myems', locale_path, languages=['en'])
85
    else:
86
        trans = gettext.translation('myems', locale_path, languages=['en'])
87
    trans.install()
88
    _ = trans.gettext
89
    wb = Workbook()
90
    ws = wb.active
91
    ws.title = "SpaceStatistics"
92
93
    # Row height
94
    ws.row_dimensions[1].height = 102
95
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
    ws.column_dimensions['B'].width = 25.0
102
103
    for i in range(ord('C'), ord('Z')):
104
        ws.column_dimensions[chr(i)].width = 15.0
105
106
    # Font
107
    name_font = Font(name='Arial', size=15, bold=True)
108
    title_font = Font(name='Arial', size=15, bold=True)
109
110
    table_fill = PatternFill(fill_type='solid', fgColor='90ee90')
111
    f_border = Border(left=Side(border_style='medium'),
112
                      right=Side(border_style='medium'),
113
                      bottom=Side(border_style='medium'),
114
                      top=Side(border_style='medium')
115
                      )
116
    b_border = Border(
117
        bottom=Side(border_style='medium'),
118
    )
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: Statistics
191
    # 6: title
192
    # 7: table title
193
    # 8~ca_len table_data
194
    ####################################################################################################################
195
    reporting_period_data = report['reporting_period']
196
197
    if "names" not in reporting_period_data.keys() or \
198
            reporting_period_data['names'] is None or \
199
            len(reporting_period_data['names']) == 0:
200
        filename = str(uuid.uuid4()) + '.xlsx'
201
        wb.save(filename)
202
        return filename
203
204
    ws['B7'].font = title_font
205
    ws['B7'] = name + ' ' + _('Statistics')
206
207
    category = reporting_period_data['names']
208
209
    # table_title
210
    ws['B8'].fill = table_fill
211
    ws['B8'].font = title_font
212
    ws['B8'].alignment = c_c_alignment
213
    ws['B8'] = _('Reporting Period')
214
    ws['B8'].border = f_border
215
216
    ws['C8'].fill = table_fill
217
    ws['C8'].font = title_font
218
    ws['C8'].alignment = c_c_alignment
219
    ws['C8'] = _('Arithmetic Mean')
220
    ws['C8'].border = f_border
221
222
    ws['D8'].fill = table_fill
223
    ws['D8'].font = title_font
224
    ws['D8'].alignment = c_c_alignment
225
    ws['D8'] = _('Median (Middle Value)')
226
    ws['D8'].border = f_border
227
228
    ws['E8'].fill = table_fill
229
    ws['E8'].font = title_font
230
    ws['E8'].alignment = c_c_alignment
231
    ws['E8'] = _('Minimum Value')
232
    ws['E8'].border = f_border
233
234
    ws['F8'].fill = table_fill
235
    ws['F8'].font = title_font
236
    ws['F8'].alignment = c_c_alignment
237
    ws['F8'] = _('Maximum Value')
238
    ws['F8'].border = f_border
239
240
    ws['G8'].fill = table_fill
241
    ws['G8'].font = title_font
242
    ws['G8'].alignment = c_c_alignment
243
    ws['G8'] = _('Sample Standard Deviation')
244
    ws['G8'].border = f_border
245
246
    ws['H8'].fill = table_fill
247
    ws['H8'].font = title_font
248
    ws['H8'].alignment = c_c_alignment
249
    ws['H8'] = _('Sample Variance')
250
    ws['H8'].border = f_border
251
252
    # table_data
253
254
    for i, value in enumerate(category):
255
        row = i*2 + 9
256
        ws['B' + str(row)].font = name_font
257
        ws['B' + str(row)].alignment = c_c_alignment
258
        ws['B' + str(row)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + " )"
259
        ws['B' + str(row)].border = f_border
260
261
        ws['B' + str(row + 1)].font = name_font
262
        ws['B' + str(row + 1)].alignment = c_c_alignment
263
        ws['B' + str(row + 1)] = _('Increment Rate')
264
        ws['B' + str(row + 1)].border = f_border
265
266
        ws['C' + str(row)].font = name_font
267
        ws['C' + str(row)].alignment = c_c_alignment
268
        ws['C' + str(row)] = round(reporting_period_data['means'][i], 2) \
269
            if reporting_period_data['means'][i] is not None else ''
270
        ws['C' + str(row)].border = f_border
271
        ws['C' + str(row)].number_format = '0.00'
272
273
        ws['C' + str(row + 1)].font = name_font
274
        ws['C' + str(row + 1)].alignment = c_c_alignment
275
        ws['C' + str(row + 1)] = str(round(reporting_period_data['means_increment_rate'][i] * 100, 2)) + "%" \
276
            if reporting_period_data['means_increment_rate'][i] is not None else '0.00%'
277
        ws['C' + str(row + 1)].border = f_border
278
279
        ws['D' + str(row)].font = name_font
280
        ws['D' + str(row)].alignment = c_c_alignment
281
        ws['D' + str(row)] = round(reporting_period_data['medians'][i], 2) \
282
            if reporting_period_data['medians'][i] is not None else ''
283
        ws['D' + str(row)].border = f_border
284
        ws['D' + str(row)].number_format = '0.00'
285
286
        ws['D' + str(row + 1)].font = name_font
287
        ws['D' + str(row + 1)].alignment = c_c_alignment
288
        ws['D' + str(row + 1)] = str(round(reporting_period_data['medians_increment_rate'][i] * 100, 2)) + "%" \
289
            if reporting_period_data['medians_increment_rate'][i] is not None else '0.00%'
290
        ws['D' + str(row + 1)].border = f_border
291
292
        ws['E' + str(row)].font = name_font
293
        ws['E' + str(row)].alignment = c_c_alignment
294
        ws['E' + str(row)] = round(reporting_period_data['minimums'][i], 2) \
295
            if reporting_period_data['minimums'][i] is not None else ''
296
        ws['E' + str(row)].border = f_border
297
        ws['E' + str(row)].number_format = '0.00'
298
299
        ws['E' + str(row + 1)].font = name_font
300
        ws['E' + str(row + 1)].alignment = c_c_alignment
301
        ws['E' + str(row + 1)] = str(round(reporting_period_data['minimums_increment_rate'][i] * 100, 2)) + "%" \
302
            if reporting_period_data['minimums_increment_rate'][i] is not None else '0.00%'
303
        ws['E' + str(row + 1)].border = f_border
304
305
        ws['F' + str(row)].font = name_font
306
        ws['F' + str(row)].alignment = c_c_alignment
307
        ws['F' + str(row)] = round(reporting_period_data['maximums'][i], 2) \
308
            if reporting_period_data['maximums'][i] is not None else ''
309
        ws['F' + str(row)].border = f_border
310
        ws['F' + str(row)].number_format = '0.00'
311
312
        ws['F' + str(row + 1)].font = name_font
313
        ws['F' + str(row + 1)].alignment = c_c_alignment
314
        ws['F' + str(row + 1)] = str(round(reporting_period_data['maximums_increment_rate'][i] * 100, 2)) + "%" \
315
            if reporting_period_data['maximums_increment_rate'][i] is not None else '0.00%'
316
        ws['F' + str(row + 1)].border = f_border
317
318
        ws['G' + str(row)].font = name_font
319
        ws['G' + str(row)].alignment = c_c_alignment
320
        ws['G' + str(row)] = round(reporting_period_data['stdevs'][i], 2) \
321
            if reporting_period_data['stdevs'][i] is not None else ''
322
        ws['G' + str(row)].border = f_border
323
        ws['G' + str(row)].number_format = '0.00'
324
325
        ws['G' + str(row + 1)].font = name_font
326
        ws['G' + str(row + 1)].alignment = c_c_alignment
327
        ws['G' + str(row + 1)] = str(round(reporting_period_data['stdevs_increment_rate'][i] * 100, 2)) + "%" \
328
            if reporting_period_data['stdevs_increment_rate'][i] is not None else '0.00%'
329
        ws['G' + str(row + 1)].border = f_border
330
331
        ws['H' + str(row)].font = name_font
332
        ws['H' + str(row)].alignment = c_c_alignment
333
        ws['H' + str(row)] = round(reporting_period_data['variances'][i], 2) \
334
            if reporting_period_data['variances'][i] is not None else ''
335
        ws['H' + str(row)].border = f_border
336
        ws['H' + str(row)].number_format = '0.00'
337
338
        ws['H' + str(row + 1)].font = name_font
339
        ws['H' + str(row + 1)].alignment = c_c_alignment
340
        ws['H' + str(row + 1)] = str(round(reporting_period_data['variances_increment_rate'][i] * 100, 2)) + "%" \
341
            if reporting_period_data['variances_increment_rate'][i] is not None else '0.00%'
342
        ws['H' + str(row + 1)].border = f_border
343
    ####################################################################################################################
344
    # Second: Reporting Period Consumption
345
    # 10 + ca_len * 2: title
346
    # 11 + ca_len * 2: table title
347
    # per_unit_area_start_row_number + 2 ~ per_unit_area_start_row_number + 2 + ca_len :  table_data
348
    ####################################################################################################################
349
350
    names = reporting_period_data['names']
351
    ca_len = len(names)
352
353
    per_unit_area_start_row_number = 10 + ca_len * 2
354
355
    ws['B' + str(per_unit_area_start_row_number)].font = title_font
356
    ws['B' + str(per_unit_area_start_row_number)] = name + ' ' + _('Per Unit Area')
357
    ws['D' + str(per_unit_area_start_row_number)].font = title_font
358
    ws['D' + str(per_unit_area_start_row_number)] = str(report['space']['area']) + 'M²'
359
360
    category = reporting_period_data['names']
361
362
    # table_title
363
    ws['B' + str(per_unit_area_start_row_number + 1)].fill = table_fill
364
    ws['B' + str(per_unit_area_start_row_number + 1)].font = title_font
365
    ws['B' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
366
    ws['B' + str(per_unit_area_start_row_number + 1)] = _('Reporting Period')
367
    ws['B' + str(per_unit_area_start_row_number + 1)].border = f_border
368
369
    ws['C' + str(per_unit_area_start_row_number + 1)].fill = table_fill
370
    ws['C' + str(per_unit_area_start_row_number + 1)].font = title_font
371
    ws['C' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
372
    ws['C' + str(per_unit_area_start_row_number + 1)] = _('Arithmetic Mean')
373
    ws['C' + str(per_unit_area_start_row_number + 1)].border = f_border
374
375
    ws['D' + str(per_unit_area_start_row_number + 1)].fill = table_fill
376
    ws['D' + str(per_unit_area_start_row_number + 1)].font = title_font
377
    ws['D' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
378
    ws['D' + str(per_unit_area_start_row_number + 1)] = _('Median (Middle Value)')
379
    ws['D' + str(per_unit_area_start_row_number + 1)].border = f_border
380
381
    ws['E' + str(per_unit_area_start_row_number + 1)].fill = table_fill
382
    ws['E' + str(per_unit_area_start_row_number + 1)].font = title_font
383
    ws['E' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
384
    ws['E' + str(per_unit_area_start_row_number + 1)] = _('Minimum Value')
385
    ws['E' + str(per_unit_area_start_row_number + 1)].border = f_border
386
387
    ws['F' + str(per_unit_area_start_row_number + 1)].fill = table_fill
388
    ws['F' + str(per_unit_area_start_row_number + 1)].font = title_font
389
    ws['F' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
390
    ws['F' + str(per_unit_area_start_row_number + 1)] = _('Maximum Value')
391
    ws['F' + str(per_unit_area_start_row_number + 1)].border = f_border
392
393
    ws['G' + str(per_unit_area_start_row_number + 1)].fill = table_fill
394
    ws['G' + str(per_unit_area_start_row_number + 1)].font = title_font
395
    ws['G' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
396
    ws['G' + str(per_unit_area_start_row_number + 1)] = _('Sample Standard Deviation')
397
    ws['G' + str(per_unit_area_start_row_number + 1)].border = f_border
398
399
    ws['H' + str(per_unit_area_start_row_number + 1)].fill = table_fill
400
    ws['H' + str(per_unit_area_start_row_number + 1)].font = title_font
401
    ws['H' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
402
    ws['H' + str(per_unit_area_start_row_number + 1)] = _('Sample Variance')
403
    ws['H' + str(per_unit_area_start_row_number + 1)].border = f_border
404
405
    # table_data
406
407
    for i, value in enumerate(category):
408
        row_data = per_unit_area_start_row_number + 2 + i
409
        ws['B' + str(row_data)].font = name_font
410
        ws['B' + str(row_data)].alignment = c_c_alignment
411
        ws['B' + str(row_data)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][
412
            i] + "/M²)"
413
        ws['B' + str(row_data)].border = f_border
414
415
        ws['C' + str(row_data)].font = name_font
416
        ws['C' + str(row_data)].alignment = c_c_alignment
417
        if reporting_period_data['means_per_unit_area'][i] \
418
                or reporting_period_data['means_per_unit_area'][i] == 0:
419
            ws['C' + str(row_data)] = round(reporting_period_data['means_per_unit_area'][i], 2)
420
        ws['C' + str(row_data)].border = f_border
421
        ws['C' + str(row_data)].number_format = '0.00'
422
423
        ws['D' + str(row_data)].font = name_font
424
        ws['D' + str(row_data)].alignment = c_c_alignment
425
        if reporting_period_data['medians_per_unit_area'][i] \
426
                or reporting_period_data['medians_per_unit_area'][i] == 0:
427
            ws['D' + str(row_data)] = round(reporting_period_data['medians_per_unit_area'][i], 2)
428
        ws['D' + str(row_data)].border = f_border
429
        ws['D' + str(row_data)].number_format = '0.00'
430
431
        ws['E' + str(row_data)].font = name_font
432
        ws['E' + str(row_data)].alignment = c_c_alignment
433
        if reporting_period_data['minimums_per_unit_area'][i] \
434
                or reporting_period_data['minimums_per_unit_area'][i] == 0:
435
            ws['E' + str(row_data)] = round(reporting_period_data['minimums_per_unit_area'][i], 2)
436
        ws['E' + str(row_data)].border = f_border
437
        ws['E' + str(row_data)].number_format = '0.00'
438
439
        ws['F' + str(row_data)].font = name_font
440
        ws['F' + str(row_data)].alignment = c_c_alignment
441
        if reporting_period_data['maximums_per_unit_area'][i] \
442
                or reporting_period_data['maximums_per_unit_area'][i] == 0:
443
            ws['F' + str(row_data)] = round(reporting_period_data['maximums_per_unit_area'][i], 2)
444
        ws['F' + str(row_data)].border = f_border
445
        ws['F' + str(row_data)].number_format = '0.00'
446
447
        ws['G' + str(row_data)].font = name_font
448
        ws['G' + str(row_data)].alignment = c_c_alignment
449
        if (reporting_period_data['stdevs_per_unit_area'][i]) \
450
                or reporting_period_data['stdevs_per_unit_area'][i] == 0:
451
            ws['G' + str(row_data)] = round(reporting_period_data['stdevs_per_unit_area'][i], 2)
452
        ws['G' + str(row_data)].border = f_border
453
        ws['G' + str(row_data)].number_format = '0.00'
454
455
        ws['H' + str(row_data)].font = name_font
456
        ws['H' + str(row_data)].alignment = c_c_alignment
457
        if reporting_period_data['variances_per_unit_area'][i] \
458
                or reporting_period_data['variances_per_unit_area'][i] == 0:
459
            ws['H' + str(row_data)] = round(reporting_period_data['variances_per_unit_area'][i], 2)
460
        ws['H' + str(row_data)].border = f_border
461
        ws['H' + str(row_data)].number_format = '0.00'
462
463
    ####################################################################################################################
464
    # Third: Detailed Data
465
    ####################################################################################################################
466
    current_row_number = per_unit_area_start_row_number + 2 + len(category) + 1
467
468
    table_start_draw_flag = current_row_number + 1
469 View Code Duplication
    if "timestamps" 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...
470
            reporting_period_data['timestamps'] is None or \
471
            len(reporting_period_data['timestamps']) == 0:
472
        pass
473
    else:
474
        if not is_base_period_timestamp_exists_flag:
475
            reporting_period_data = report['reporting_period']
476
            times = reporting_period_data['timestamps']
477
            ca_len = len(report['reporting_period']['names'])
478
            real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
479
            ws['B' + str(current_row_number)].font = title_font
480
            ws['B' + str(current_row_number)] = name + ' ' + _('Detailed Data')
481
482
            current_row_number += 1
483
            # 1: Stand for blank line  2: Stand for title
484
            current_row_number += ca_len * 6 + real_timestamps_len * 6 + 1 + 2
485
            table_start_row_number = current_row_number
486
487
            time = times[0]
488
            has_data = False
489
490
            if len(time) > 0:
491
                has_data = True
492
493
            if has_data:
494
495
                ws.row_dimensions[current_row_number].height = 60
496
                current_col_number = 2
497
                col = format_cell.get_column_letter(current_col_number)
498
                ws[col + str(current_row_number)].fill = table_fill
499
                ws[col + str(current_row_number)].font = title_font
500
                ws[col + str(current_row_number)].border = f_border
501
                ws[col + str(current_row_number)].alignment = c_c_alignment
502
                ws[col + str(current_row_number)] = _('Datetime')
503
504
                for i in range(0, ca_len):
505
                    current_col_number += 1
506
                    col = format_cell.get_column_letter(current_col_number)
507
508
                    ws[col + str(current_row_number)].fill = table_fill
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)] = reporting_period_data['names'][i] + \
512
                        " (" + reporting_period_data['units'][i] + ")"
513
                    ws[col + str(current_row_number)].border = f_border
514
515
                current_row_number += 1
516
517
                for i in range(0, len(time)):
518
                    current_col_number = 2
519
                    col = format_cell.get_column_letter(current_col_number)
520
                    ws[col + str(current_row_number)].font = title_font
521
                    ws[col + str(current_row_number)].alignment = c_c_alignment
522
                    ws[col + str(current_row_number)] = time[i]
523
                    ws[col + str(current_row_number)].border = f_border
524
525
                    for j in range(0, ca_len):
526
                        current_col_number += 1
527
                        col = format_cell.get_column_letter(current_col_number)
528
529
                        ws[col + str(current_row_number)].font = title_font
530
                        ws[col + str(current_row_number)].alignment = c_c_alignment
531
                        ws[col + str(current_row_number)] = round(reporting_period_data['values'][j][i], 2)
532
                        ws[col + str(current_row_number)].border = f_border
533
534
                    current_row_number += 1
535
536
                table_end_row_number = current_row_number - 1
537
538
                current_col_number = 2
539
                col = format_cell.get_column_letter(current_col_number)
540
                ws[col + str(current_row_number)].font = title_font
541
                ws[col + str(current_row_number)].alignment = c_c_alignment
542
                ws[col + str(current_row_number)] = _('Subtotal')
543
                ws[col + str(current_row_number)].border = f_border
544
545
                for i in range(0, ca_len):
546
                    current_col_number += 1
547
                    col = format_cell.get_column_letter(current_col_number)
548
549
                    ws[col + str(current_row_number)].font = title_font
550
                    ws[col + str(current_row_number)].alignment = c_c_alignment
551
                    ws[col + str(current_row_number)] = round(reporting_period_data['subtotals'][i], 2)
552
                    ws[col + str(current_row_number)].border = f_border
553
554
                    # line
555
                    line = LineChart()
556
                    line.title = _('Reporting Period Consumption') + ' - ' \
557
                        + reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")"
558
                    labels = Reference(ws, min_col=2, min_row=table_start_row_number + 1, max_row=table_end_row_number)
559
                    line_data = Reference(ws, min_col=3 + i, min_row=table_start_row_number,
560
                                          max_row=table_end_row_number)
561
                    line.add_data(line_data, titles_from_data=True)
562
                    line.set_categories(labels)
563
                    line_data = line.series[0]
564
                    line_data.marker.symbol = "circle"
565
                    line_data.smooth = True
566
                    line.x_axis.crosses = 'min'
567
                    line.height = 8.25
568
                    line.width = 24
569
                    line.dLbls = DataLabelList()
570
                    line.dLbls.dLblPos = 't'
571
                    line.dLbls.showVal = True
572
                    line.dLbls.showPercent = False
573
                    chart_col = 'B'
574
                    chart_cell = chart_col + str(table_start_draw_flag + 6 * i)
575
                    ws.add_chart(line, chart_cell)
576
577
                current_row_number += 2
578
        else:
579
            base_period_data = report['base_period']
580
            reporting_period_data = report['reporting_period']
581
            base_period_timestamps = base_period_data['timestamps']
582
            reporting_period_timestamps = reporting_period_data['timestamps']
583
            # Tip:
584
            #     base_period_data['names'] == reporting_period_data['names']
585
            #     base_period_data['units'] == reporting_period_data['units']
586
            base_period_data_ca_len = len(base_period_data['names'])
587
            reporting_period_data_ca_len = len(reporting_period_data['names'])
588
            real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
589
            ws['B' + str(current_row_number)].font = title_font
590
            ws['B' + str(current_row_number)] = name + ' ' + _('Detailed Data')
591
592
            current_row_number += 1
593
            # 1: Stand for blank line  2: Stand for title
594
            current_row_number += reporting_period_data_ca_len * 6 + real_timestamps_len * 6 + 1 + 2
595
            table_start_row_number = current_row_number
596
597
            has_data = False
598
599
            if len(base_period_timestamps[0]) or len(reporting_period_timestamps[0]) > 0:
600
                has_data = True
601
602
            if has_data:
603
                ws.row_dimensions[current_row_number].height = 60
604
                current_col_number = 2
605
                col = format_cell.get_column_letter(current_col_number)
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)].border = f_border
609
                ws[col + str(current_row_number)].alignment = c_c_alignment
610
                ws[col + str(current_row_number)] = _('Base Period') + " - " + _('Datetime')
611
612
                for i in range(0, base_period_data_ca_len):
613
                    current_col_number += 1
614
                    col = format_cell.get_column_letter(current_col_number)
615
616
                    ws[col + str(current_row_number)].fill = table_fill
617
                    ws[col + str(current_row_number)].font = title_font
618
                    ws[col + str(current_row_number)].alignment = c_c_alignment
619
                    ws[col + str(current_row_number)] = _('Base Period') + " - " + base_period_data['names'][i] + \
620
                        " (" + base_period_data['units'][i] + ")"
621
                    ws[col + str(current_row_number)].border = f_border
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_row_number += 1
643
644
                max_timestamps_len = len(base_period_timestamps[0]) \
645
                    if len(base_period_timestamps[0]) >= len(reporting_period_timestamps[0]) \
646
                    else len(reporting_period_timestamps[0])
647
648
                for i in range(0, max_timestamps_len):
649
                    current_col_number = 2
650
                    col = format_cell.get_column_letter(current_col_number)
651
                    ws[col + str(current_row_number)].font = title_font
652
                    ws[col + str(current_row_number)].alignment = c_c_alignment
653
                    ws[col + str(current_row_number)] = base_period_timestamps[0][i] \
654
                        if i < len(base_period_timestamps[0]) else None
655
                    ws[col + str(current_row_number)].border = f_border
656
657
                    for j in range(0, base_period_data_ca_len):
658
                        current_col_number += 1
659
                        col = format_cell.get_column_letter(current_col_number)
660
661
                        ws[col + str(current_row_number)].font = title_font
662
                        ws[col + str(current_row_number)].alignment = c_c_alignment
663
                        ws[col + str(current_row_number)] = round(base_period_data['values'][j][i], 2) \
664
                            if i < len(base_period_data['values'][j]) else None
665
                        ws[col + str(current_row_number)].border = f_border
666
                    current_col_number += 1
667
                    col = format_cell.get_column_letter(current_col_number)
668
669
                    ws[col + str(current_row_number)].font = title_font
670
                    ws[col + str(current_row_number)].alignment = c_c_alignment
671
                    ws[col + str(current_row_number)] = reporting_period_timestamps[0][i] \
672
                        if i < len(reporting_period_timestamps[0]) else None
673
                    ws[col + str(current_row_number)].border = f_border
674
675
                    for j in range(0, reporting_period_data_ca_len):
676
                        current_col_number += 1
677
                        col = format_cell.get_column_letter(current_col_number)
678
679
                        ws[col + str(current_row_number)].font = title_font
680
                        ws[col + str(current_row_number)].alignment = c_c_alignment
681
                        ws[col + str(current_row_number)] = round(reporting_period_data['values'][j][i], 2) \
682
                            if i < len(reporting_period_data['values'][j]) else None
683
                        ws[col + str(current_row_number)].border = f_border
684
685
                    current_row_number += 1
686
687
                current_col_number = 2
688
                col = format_cell.get_column_letter(current_col_number)
689
                ws[col + str(current_row_number)].font = title_font
690
                ws[col + str(current_row_number)].alignment = c_c_alignment
691
                ws[col + str(current_row_number)] = _('Subtotal')
692
                ws[col + str(current_row_number)].border = f_border
693
694
                for i in range(0, base_period_data_ca_len):
695
                    current_col_number += 1
696
                    col = format_cell.get_column_letter(current_col_number)
697
                    ws[col + str(current_row_number)].font = title_font
698
                    ws[col + str(current_row_number)].alignment = c_c_alignment
699
                    ws[col + str(current_row_number)] = round(base_period_data['subtotals'][i], 2)
700
                    ws[col + str(current_row_number)].border = f_border
701
702
                current_col_number += 1
703
                col = format_cell.get_column_letter(current_col_number)
704
705
                ws[col + str(current_row_number)].font = title_font
706
                ws[col + str(current_row_number)].alignment = c_c_alignment
707
                ws[col + str(current_row_number)] = _('Subtotal')
708
                ws[col + str(current_row_number)].border = f_border
709
710
                for i in range(0, reporting_period_data_ca_len):
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_data['subtotals'][i], 2)
716
                    ws[col + str(current_row_number)].border = f_border
717
718
                for i in range(0, reporting_period_data_ca_len):
719
                    # line
720
                    line = LineChart()
721
                    line.title = _('Base Period Consumption') + ' / ' \
722
                        + _('Reporting Period Consumption') + ' - ' \
723
                        + reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")"
724
                    labels = Reference(ws, min_col=2 + base_period_data_ca_len + 1,
725
                                       min_row=table_start_row_number + 1,
726
                                       max_row=table_start_row_number + len(reporting_period_timestamps[0]))
727
                    base_line_data = Reference(ws, min_col=3 + i, min_row=table_start_row_number,
728
                                               max_row=table_start_row_number + len(reporting_period_timestamps[0]))
729
                    reporting_line_data = Reference(ws, min_col=3 + base_period_data_ca_len + 1 + i,
730
                                                    min_row=table_start_row_number,
731
                                                    max_row=table_start_row_number
732
                                                    + len(reporting_period_timestamps[0]))
733
                    line.add_data(base_line_data, titles_from_data=True)
734
                    line.add_data(reporting_line_data, titles_from_data=True)
735
                    line.set_categories(labels)
736
                    for j in range(len(line.series)):
737
                        line.series[j].marker.symbol = "circle"
738
                        line.series[j].smooth = True
739
                    line.x_axis.crosses = 'min'
740
                    line.height = 8.25
741
                    line.width = 24
742
                    line.dLbls = DataLabelList()
743
                    line.dLbls.dLblPos = 't'
744
                    line.dLbls.showVal = True
745
                    line.dLbls.showPercent = False
746
                    chart_col = 'B'
747
                    chart_cell = chart_col + str(table_start_draw_flag + 6 * i)
748
                    ws.add_chart(line, chart_cell)
749
750
                current_row_number += 2
751
752
    ####################################################################################################################
753
    current_sheet_parameters_row_number = table_start_draw_flag + len(reporting_period_data['names']) * 6 + 1
754 View Code Duplication
    if 'parameters' not in report.keys() or \
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
755
            report['parameters'] is None or \
756
            'names' not in report['parameters'].keys() or \
757
            report['parameters']['names'] is None or \
758
            len(report['parameters']['names']) == 0 or \
759
            'timestamps' not in report['parameters'].keys() or \
760
            report['parameters']['timestamps'] is None or \
761
            len(report['parameters']['timestamps']) == 0 or \
762
            'values' not in report['parameters'].keys() or \
763
            report['parameters']['values'] is None or \
764
            len(report['parameters']['values']) == 0 or \
765
            timestamps_data_all_equal_0(report['parameters']['timestamps']):
766
        pass
767
    else:
768
        ################################################################################################################
769
        # new worksheet
770
        ################################################################################################################
771
        parameters_data = report['parameters']
772
        parameters_names_len = len(parameters_data['names'])
773
774
        file_name = ws.title
775
        parameters_ws = wb.create_sheet(file_name + _('Parameters'))
776
777
        parameters_timestamps_data_max_len = \
778
            get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps']))
779
780
        # Row height
781
        parameters_ws.row_dimensions[1].height = 102
782
        for i in range(2, 7 + 1):
783
            parameters_ws.row_dimensions[i].height = 42
784
785
        for i in range(8, parameters_timestamps_data_max_len + 10):
786
            parameters_ws.row_dimensions[i].height = 60
787
788
        # Col width
789
        parameters_ws.column_dimensions['A'].width = 1.5
790
791
        parameters_ws.column_dimensions['B'].width = 25.0
792
793
        for i in range(3, 12 + parameters_names_len * 3):
794
            parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0
795
796
        # Img
797
        img = Image("excelexporters/myems.png")
798
        parameters_ws.add_image(img, 'A1')
799
800
        # Title
801
        parameters_ws['B3'].alignment = b_r_alignment
802
        parameters_ws['B3'] = _('Name') + ':'
803
        parameters_ws['C3'].border = b_border
804
        parameters_ws['C3'].alignment = b_c_alignment
805
        parameters_ws['C3'] = name
806
807
        parameters_ws['D3'].alignment = b_r_alignment
808
        parameters_ws['D3'] = _('Period Type') + ':'
809
        parameters_ws['E3'].border = b_border
810
        parameters_ws['E3'].alignment = b_c_alignment
811
        parameters_ws['E3'] = period_type
812
813
        parameters_ws['B4'].alignment = b_r_alignment
814
        parameters_ws['B4'] = _('Reporting Start Datetime') + ':'
815
        parameters_ws['C4'].border = b_border
816
        parameters_ws['C4'].alignment = b_c_alignment
817
        parameters_ws['C4'] = reporting_start_datetime_local
818
819
        parameters_ws['D4'].alignment = b_r_alignment
820
        parameters_ws['D4'] = _('Reporting End Datetime') + ':'
821
        parameters_ws['E4'].border = b_border
822
        parameters_ws['E4'].alignment = b_c_alignment
823
        parameters_ws['E4'] = reporting_end_datetime_local
824
825
        parameters_ws_current_row_number = 6
826
827
        parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font
828
        parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' ' + _('Parameters')
829
830
        parameters_ws_current_row_number += 1
831
832
        parameters_table_start_row_number = parameters_ws_current_row_number
833
834
        parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80
835
836
        parameters_ws_current_row_number += 1
837
838
        table_current_col_number = 2
839
840
        for i in range(0, parameters_names_len):
841
842
            if len(parameters_data['timestamps'][i]) == 0:
843
                continue
844
845
            col = format_cell.get_column_letter(table_current_col_number)
846
847
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
848
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
849
850
            col = format_cell.get_column_letter(table_current_col_number + 1)
851
852
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
853
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
854
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].font = name_font
855
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].alignment = c_c_alignment
856
            parameters_ws[col + str(parameters_ws_current_row_number - 1)] = parameters_data['names'][i]
857
858
            table_current_row_number = parameters_ws_current_row_number
859
860
            for j, value in enumerate(list(parameters_data['timestamps'][i])):
861
                col = format_cell.get_column_letter(table_current_col_number)
862
863
                parameters_ws[col + str(table_current_row_number)].border = f_border
864
                parameters_ws[col + str(table_current_row_number)].font = title_font
865
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
866
                parameters_ws[col + str(table_current_row_number)] = value
867
868
                col = format_cell.get_column_letter(table_current_col_number + 1)
869
870
                parameters_ws[col + str(table_current_row_number)].border = f_border
871
                parameters_ws[col + str(table_current_row_number)].font = title_font
872
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
873
                parameters_ws[col + str(table_current_row_number)] = round(parameters_data['values'][i][j], 2)
874
875
                table_current_row_number += 1
876
877
            table_current_col_number = table_current_col_number + 3
878
879
        ################################################################################################################
880
        # parameters chart and parameters table
881
        ################################################################################################################
882
883
        ws['B' + str(current_sheet_parameters_row_number)].font = title_font
884
        ws['B' + str(current_sheet_parameters_row_number)] = name + ' ' + _('Parameters')
885
886
        current_sheet_parameters_row_number += 1
887
888
        chart_start_row_number = current_sheet_parameters_row_number
889
890
        col_index = 0
891
892
        for i in range(0, parameters_names_len):
893
894
            if len(parameters_data['timestamps'][i]) == 0:
895
                continue
896
897
            line = LineChart()
898
            data_col = 3 + col_index * 3
899
            labels_col = 2 + col_index * 3
900
            col_index += 1
901
            line.title = _('Parameters') + ' - ' + \
902
                parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value
903
            labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1,
904
                               max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
905
            line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number,
906
                                  max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
907
            line.add_data(line_data, titles_from_data=True)
908
            line.set_categories(labels)
909
            line_data = line.series[0]
910
            line_data.marker.symbol = "circle"
911
            line_data.smooth = True
912
            line.x_axis.crosses = 'min'
913
            line.height = 8.25
914
            line.width = 24
915
            line.dLbls = DataLabelList()
916
            line.dLbls.dLblPos = 't'
917
            line.dLbls.showVal = False
918
            line.dLbls.showPercent = False
919
            chart_col = 'B'
920
            chart_cell = chart_col + str(chart_start_row_number)
921
            chart_start_row_number += 6
922
            ws.add_chart(line, chart_cell)
923
924
        current_sheet_parameters_row_number = chart_start_row_number
925
926
        current_sheet_parameters_row_number += 1
927
    ####################################################################################################################
928
    filename = str(uuid.uuid4()) + '.xlsx'
929
    wb.save(filename)
930
931
    return filename
932
933
934
def timestamps_data_all_equal_0(lists):
935
    for i, value in enumerate(list(lists)):
936
        if len(value) > 0:
937
            return False
938
939
    return True
940
941
942
def get_parameters_timestamps_lists_max_len(parameters_timestamps_lists):
943
    max_len = 0
944
    for i, value in enumerate(list(parameters_timestamps_lists)):
945
        if len(value) > max_len:
946
            max_len = len(value)
947
948
    return max_len
949
950
951
def timestamps_data_not_equal_0(lists):
952
    number = 0
953
    for i, value in enumerate(list(lists)):
954
        if len(value) > 0:
955
            number += 1
956
    return number
957
958
959 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...
960
    timestamps = base_period_data['timestamps']
961
962
    if len(timestamps) == 0:
963
        return False
964
965
    for timestamp in timestamps:
966
        if len(timestamp) > 0:
967
            return True
968
969
    return False
970