Passed
Push — master ( e2d795...875b92 )
by Guangyu
23:15 queued 12s
created

excelexporters.shopfloorenergyitem   F

Complexity

Total Complexity 83

Size/Duplication

Total Lines 698
Duplicated Lines 91.26 %

Importance

Changes 0
Metric Value
wmc 83
eloc 508
dl 637
loc 698
rs 2
c 0
b 0
f 0

7 Functions

Rating   Name   Duplication   Size   Complexity  
A timestamps_data_all_equal_0() 0 6 3
A group_by_category() 0 7 3
A decimal_to_column() 19 19 5
A get_parameters_timestamps_lists_max_len() 0 7 3
F generate_excel() 579 579 62
B export() 39 39 5
A column_to_decimal() 0 6 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like excelexporters.shopfloorenergyitem often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
import base64
2
import uuid
3
import os
4
from openpyxl.chart import (
5
    PieChart,
6
    LineChart,
7
    Reference,
8
)
9
from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
10
from openpyxl.drawing.image import Image
11
from openpyxl import Workbook
12
from openpyxl.chart.label import DataLabelList
13
import openpyxl.utils.cell as format_cell
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
           reporting_start_datetime_local,
26
           reporting_end_datetime_local,
27
           period_type):
28
    ####################################################################################################################
29
    # Step 1: Validate the report data
30
    ####################################################################################################################
31
    if report is None:
32
        return None
33
    print(report)
34
35
    ####################################################################################################################
36
    # Step 2: Generate excel file from the report data
37
    ####################################################################################################################
38
    filename = generate_excel(report,
39
                              name,
40
                              reporting_start_datetime_local,
41
                              reporting_end_datetime_local,
42
                              period_type)
43
    ####################################################################################################################
44
    # Step 3: Encode the excel file to Base64
45
    ####################################################################################################################
46
    try:
47
        with open(filename, 'rb') as binary_file:
48
            binary_file_data = binary_file.read()
49
    except IOError as ex:
50
        pass
51
52
    # Base64 encode the bytes
53
    base64_encoded_data = base64.b64encode(binary_file_data)
0 ignored issues
show
introduced by
The variable binary_file_data does not seem to be defined for all execution paths.
Loading history...
54
    # get the Base64 encoded data using human-readable characters.
55
    base64_message = base64_encoded_data.decode('utf-8')
56
    # delete the file from server
57
    try:
58
        os.remove(filename)
59
    except NotImplementedError as ex:
60
        pass
61
    return base64_message
62
63
64 View Code Duplication
def decimal_to_column(num=65):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
65
    string = ''
66
    num = num - 64
67
    # The column number is not greater than 90
68
    if num <= 26:
69
        return chr(num + 64)
70
    # The column number is greater than 90
71
    while num // 26 > 0:
72
        if num % 26 == 0:
73
            string += 'Z'
74
            num = num // 26 - 1
75
        else:
76
            string += chr(num % 26 + 64)
77
            num //= 26
78
    # Avoid conversion errors that might occur between 741 and 766
79
    if num > 0:
80
        string += chr(num + 64)
81
82
    return string[::-1]
83
84
85
def column_to_decimal(string='A'):
86
    num = 0
87
    for index, key in enumerate(string[::-1]):
88
        num += (ord(key) - 64) * (26 ** index)
89
90
    return num + 64
91
92
93
def get_parameters_timestamps_lists_max_len(parameters_timestamps_lists):
94
    max_len = 0
95
    for i, value in enumerate(list(parameters_timestamps_lists)):
96
        if len(value) > max_len:
97
            max_len = len(value)
98
99
    return max_len
100
101
102
def timestamps_data_all_equal_0(lists):
103
    for i, value in enumerate(list(lists)):
104
        if len(value) > 0:
105
            return False
106
107
    return True
108
109
110 View Code Duplication
def generate_excel(report,
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
111
                   name,
112
                   reporting_start_datetime_local,
113
                   reporting_end_datetime_local,
114
                   period_type):
115
    wb = Workbook()
116
    ws = wb.active
117
118
    # Row height
119
    ws.row_dimensions[1].height = 102
120
    for i in range(2, 2000 + 1):
121
        ws.row_dimensions[i].height = 42
122
123
    # Col width
124
    ws.column_dimensions['A'].width = 1.5
125
126
    ws.column_dimensions['B'].width = 25.0
127
128
    for i in range(ord('C'), ord('L')):
129
        ws.column_dimensions[chr(i)].width = 15.0
130
131
    # Font
132
    name_font = Font(name='Constantia', size=15, bold=True)
133
    title_font = Font(name='宋体', size=15, bold=True)
134
    data_font = Font(name='Franklin Gothic Book', size=11)
135
136
    table_fill = PatternFill(fill_type='solid', fgColor='1F497D')
137
    f_border = Border(left=Side(border_style='medium', color='00000000'),
138
                      right=Side(border_style='medium', color='00000000'),
139
                      bottom=Side(border_style='medium', color='00000000'),
140
                      top=Side(border_style='medium', color='00000000')
141
                      )
142
    b_border = Border(
143
        bottom=Side(border_style='medium', color='00000000'),
144
    )
145
146
    b_c_alignment = Alignment(vertical='bottom',
147
                              horizontal='center',
148
                              text_rotation=0,
149
                              wrap_text=True,
150
                              shrink_to_fit=False,
151
                              indent=0)
152
    c_c_alignment = Alignment(vertical='center',
153
                              horizontal='center',
154
                              text_rotation=0,
155
                              wrap_text=True,
156
                              shrink_to_fit=False,
157
                              indent=0)
158
    b_r_alignment = Alignment(vertical='bottom',
159
                              horizontal='right',
160
                              text_rotation=0,
161
                              wrap_text=True,
162
                              shrink_to_fit=False,
163
                              indent=0)
164
    c_r_alignment = Alignment(vertical='bottom',
165
                              horizontal='center',
166
                              text_rotation=0,
167
                              wrap_text=True,
168
                              shrink_to_fit=False,
169
                              indent=0)
170
    # Img
171
    img = Image("excelexporters/myems.png")
172
    img.width = img.width * 0.85
173
    img.height = img.height * 0.85
174
    # img = Image("myems.png")
175
    ws.add_image(img, 'B1')
176
177
    # Title
178
    ws.row_dimensions[3].height = 60
179
180
    ws['B3'].font = name_font
181
    ws['B3'].alignment = b_r_alignment
182
    ws['B3'] = 'Name:'
183
    ws['C3'].border = b_border
184
    ws['C3'].alignment = b_c_alignment
185
    ws['C3'].font = name_font
186
    ws['C3'] = name
187
188
    ws['D3'].font = name_font
189
    ws['D3'].alignment = b_r_alignment
190
    ws['D3'] = 'Period:'
191
    ws['E3'].border = b_border
192
    ws['E3'].alignment = b_c_alignment
193
    ws['E3'].font = name_font
194
    ws['E3'] = period_type
195
196
    ws['F3'].font = name_font
197
    ws['F3'].alignment = b_r_alignment
198
    ws['F3'] = 'Date:'
199
    ws['G3'].border = b_border
200
    ws['G3'].alignment = b_c_alignment
201
    ws['G3'].font = name_font
202
    ws['G3'] = reporting_start_datetime_local + "__" + reporting_end_datetime_local
203
    ws.merge_cells("G3:H3")
204
205
    if "reporting_period" not in report.keys() or \
206
            "names" not in report['reporting_period'].keys() or len(report['reporting_period']['names']) == 0:
207
        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...
208
        wb.save(filename)
209
210
        return filename
211
212
    ##################################
213
214
    current_row_number = 6
215
216
    reporting_period_data = report['reporting_period']
217
218
    has_names_data_flag = True
219
220
    if "names" not in reporting_period_data.keys() or \
221
            reporting_period_data['names'] is None or \
222
            len(reporting_period_data['names']) == 0:
223
        has_names_data_flag = False
224
225
    if has_names_data_flag:
226
        ws['B' + str(current_row_number)].font = title_font
227
        ws['B' + str(current_row_number)] = name + ' 报告期消耗'
228
229
        current_row_number += 1
230
231
        category = reporting_period_data['names']
232
        ca_len = len(category)
233
234
        ws.row_dimensions[current_row_number].height = 60
235
        ws['B' + str(current_row_number)].fill = table_fill
236
        ws['B' + str(current_row_number)].border = f_border
237
238
        col = 'C'
239
240
        for i in range(0, ca_len):
241
            ws[col + str(current_row_number)].fill = table_fill
242
            ws[col + str(current_row_number)].font = name_font
243
            ws[col + str(current_row_number)].alignment = c_c_alignment
244
            ws[col + str(current_row_number)].border = f_border
245
            ws[col + str(current_row_number)] = \
246
                reporting_period_data['names'][i] + " " + reporting_period_data['energy_category_names'][i] + \
247
                " (" + reporting_period_data['units'][i] + ")"
248
249
            col = chr(ord(col) + 1)
250
251
        current_row_number += 1
252
253
        ws['B' + str(current_row_number)].font = title_font
254
        ws['B' + str(current_row_number)].alignment = c_c_alignment
255
        ws['B' + str(current_row_number)].border = f_border
256
        ws['B' + str(current_row_number)] = '消耗'
257
258
        col = 'C'
259
260
        for i in range(0, ca_len):
261
            ws[col + str(current_row_number)].font = name_font
262
            ws[col + str(current_row_number)].alignment = c_c_alignment
263
            ws[col + str(current_row_number)].border = f_border
264
            ws[col + str(current_row_number)] = round(reporting_period_data['subtotals'][i], 2)
265
266
            col = chr(ord(col) + 1)
267
268
        current_row_number += 1
269
270
        ws['B' + str(current_row_number)].font = title_font
271
        ws['B' + str(current_row_number)].alignment = c_c_alignment
272
        ws['B' + str(current_row_number)].border = f_border
273
        ws['B' + str(current_row_number)] = '单位面积值'
274
275
        col = 'C'
276
277
        for i in range(0, ca_len):
278
            ws[col + str(current_row_number)].font = name_font
279
            ws[col + str(current_row_number)].alignment = c_c_alignment
280
            ws[col + str(current_row_number)].border = f_border
281
            ws[col + str(current_row_number)] = round(reporting_period_data['subtotals_per_unit_area'][i], 2)
282
283
            col = chr(ord(col) + 1)
284
285
        current_row_number += 1
286
287
        ws['B' + str(current_row_number)].font = title_font
288
        ws['B' + str(current_row_number)].alignment = c_c_alignment
289
        ws['B' + str(current_row_number)].border = f_border
290
        ws['B' + str(current_row_number)] = '环比'
291
292
        col = 'C'
293
294
        for i in range(0, ca_len):
295
            ws[col + str(current_row_number)].font = name_font
296
            ws[col + str(current_row_number)].alignment = c_c_alignment
297
            ws[col + str(current_row_number)].border = f_border
298
            ws[col + str(current_row_number)] = str(
299
                round(reporting_period_data['increment_rates'][i] * 100, 2)) + '%' \
300
                if reporting_period_data['increment_rates'][i] is not None else '-'
301
302
            col = chr(ord(col) + 1)
303
304
        current_row_number += 2
305
306
        category_dict = group_by_category(reporting_period_data['energy_category_names'])
307
308
        for category_dict_name, category_dict_values in category_dict.items():
309
310
            ws['B' + str(current_row_number)].font = title_font
311
            ws['B' + str(current_row_number)] = \
312
                name + ' ' + category_dict_name + ' (' + reporting_period_data['units'][category_dict_values[0]] + \
313
                ') 分项消耗占比'
314
315
            current_row_number += 1
316
            table_start_row_number = current_row_number
317
318
            ws['B' + str(current_row_number)].fill = table_fill
319
            ws['B' + str(current_row_number)].border = f_border
320
321
            ws['C' + str(current_row_number)].font = name_font
322
            ws['C' + str(current_row_number)].fill = table_fill
323
            ws['C' + str(current_row_number)].alignment = c_c_alignment
324
            ws['C' + str(current_row_number)].border = f_border
325
            ws['C' + str(current_row_number)] = '消耗'
326
327
            current_row_number += 1
328
329
            for i in category_dict_values:
330
                ws['B' + str(current_row_number)].font = title_font
331
                ws['B' + str(current_row_number)].alignment = c_c_alignment
332
                ws['B' + str(current_row_number)].border = f_border
333
                ws['B' + str(current_row_number)] = \
334
                    reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")"
335
                ws['C' + str(current_row_number)].font = name_font
336
                ws['C' + str(current_row_number)].alignment = c_c_alignment
337
                ws['C' + str(current_row_number)].border = f_border
338
                ws['C' + str(current_row_number)] = round(reporting_period_data['subtotals'][i], 3)
339
340
                current_row_number += 1
341
342
            table_end_row_number = current_row_number - 1
343
344
            pie = PieChart()
345
            pie.title = \
346
                name + ' ' + category_dict_name + ' (' + reporting_period_data['units'][category_dict_values[0]] + \
347
                ') 分项消耗占比'
348
            labels = Reference(ws, min_col=2, min_row=table_start_row_number + 1, max_row=table_end_row_number)
349
            pie_data = Reference(ws, min_col=3, min_row=table_start_row_number, max_row=table_end_row_number)
350
            pie.add_data(pie_data, titles_from_data=True)
351
            pie.set_categories(labels)
352
            pie.height = 6.6
353
            pie.width = 9
354
            s1 = pie.series[0]
355
            s1.dLbls = DataLabelList()
356
            s1.dLbls.showCatName = False
357
            s1.dLbls.showVal = True
358
            s1.dLbls.showPercent = True
359
            ws.add_chart(pie, 'D' + str(table_start_row_number))
360
361
            if len(category_dict_values) < 4:
362
                current_row_number = current_row_number - len(category_dict_values) + 4
363
364
            current_row_number += 1
365
366
    #####################################
367
368
    has_values_data = True
369
    has_timestamps_data = True
370
371
    if 'values' not in reporting_period_data.keys() or \
372
            reporting_period_data['values'] is None or \
373
            len(reporting_period_data['values']) == 0:
374
        has_values_data = False
375
376
    if 'timestamps' not in reporting_period_data.keys() or \
377
            reporting_period_data['timestamps'] is None or \
378
            len(reporting_period_data['timestamps']) == 0 or \
379
            len(reporting_period_data['timestamps'][0]) == 0:
380
        has_timestamps_data = False
381
382
    chart_start_row_number = current_row_number + 1
383
384
    if has_values_data and has_timestamps_data:
385
        ca_len = len(reporting_period_data['names'])
386
        time = reporting_period_data['timestamps'][0]
387
        parameters_names_len = len(report['parameters']['names'])
388
        parameters_parameters_datas_len = 0
389
390
        ws['B' + str(current_row_number)].font = title_font
391
        ws['B' + str(current_row_number)] = name + ' 详细数据'
392
393
        for i in range(0, parameters_names_len):
394
            if len(report['parameters']['timestamps'][i]) == 0:
395
                continue
396
            parameters_parameters_datas_len += 1
397
        current_row_number = current_row_number + (ca_len + parameters_parameters_datas_len) * 6 + 2
398
        table_start_row_number = current_row_number
399
400
        ws.row_dimensions[current_row_number].height = 60
401
        ws['B' + str(current_row_number)].fill = table_fill
402
        ws['B' + str(current_row_number)].font = title_font
403
        ws['B' + str(current_row_number)].alignment = c_c_alignment
404
        ws['B' + str(current_row_number)].border = f_border
405
        ws['B' + str(current_row_number)] = '日期时间'
406
407
        col = 'C'
408
409
        for i in range(0, ca_len):
410
            ws[col + str(current_row_number)].fill = table_fill
411
            ws[col + str(current_row_number)].font = title_font
412
            ws[col + str(current_row_number)].alignment = c_c_alignment
413
            ws[col + str(current_row_number)].border = f_border
414
            ws[col + str(current_row_number)] = \
415
                reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")"
416
            col = chr(ord(col) + 1)
417
418
        current_row_number += 1
419
420
        for i in range(0, len(time)):
421
            ws['B' + str(current_row_number)].font = title_font
422
            ws['B' + str(current_row_number)].alignment = c_c_alignment
423
            ws['B' + str(current_row_number)].border = f_border
424
            ws['B' + str(current_row_number)] = time[i]
425
426
            col = 'C'
427
            for j in range(0, ca_len):
428
                ws[col + str(current_row_number)].font = title_font
429
                ws[col + str(current_row_number)].alignment = c_c_alignment
430
                ws[col + str(current_row_number)].border = f_border
431
                ws[col + str(current_row_number)] = round(reporting_period_data['values'][j][i], 2) \
432
                    if reporting_period_data['values'][j][i] is not None else 0.00
433
                col = chr(ord(col) + 1)
434
435
            current_row_number += 1
436
437
        table_end_row_number = current_row_number - 1
438
439
        ws['B' + str(current_row_number)].font = title_font
440
        ws['B' + str(current_row_number)].alignment = c_c_alignment
441
        ws['B' + str(current_row_number)].border = f_border
442
        ws['B' + str(current_row_number)] = '小计'
443
444
        col = 'C'
445
446
        for i in range(0, ca_len):
447
            ws[col + str(current_row_number)].font = title_font
448
            ws[col + str(current_row_number)].alignment = c_c_alignment
449
            ws[col + str(current_row_number)].border = f_border
450
            ws[col + str(current_row_number)] = round(reporting_period_data['subtotals'][i], 2)
451
            col = chr(ord(col) + 1)
452
453
        current_row_number += 2
454
455
        format_time_width_number = 1.0
456
        min_len_number = 1.0
457
        min_width_number = 11.0  # format_time_width_number * min_len_number + 4 and min_width_number > 11.0
458
459
        if period_type == 'hourly':
460
            format_time_width_number = 4.0
461
            min_len_number = 2
462
            min_width_number = 12.0
463
        elif period_type == 'daily':
464
            format_time_width_number = 2.5
465
            min_len_number = 4
466
            min_width_number = 14.0
467
        elif period_type == 'monthly':
468
            format_time_width_number = 2.1
469
            min_len_number = 4
470
            min_width_number = 12.4
471
        elif period_type == 'yearly':
472
            format_time_width_number = 1.5
473
            min_len_number = 5
474
            min_width_number = 11.5
475
476
        for i in range(0, ca_len):
477
            line = LineChart()
478
            line.title = '报告期消耗 - ' + \
479
                         reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")"
480
            labels = Reference(ws, min_col=2, min_row=table_start_row_number + 1, max_row=table_end_row_number)
481
            line_data = Reference(ws, min_col=3 + i, min_row=table_start_row_number, max_row=table_end_row_number)
482
            line.add_data(line_data, titles_from_data=True)
483
            line.set_categories(labels)
484
            line_data = line.series[0]
485
            line_data.marker.symbol = "circle"
486
            line_data.smooth = True
487
            line.x_axis.crosses = 'min'
488
            line.height = 8.25
489
            line.width = format_time_width_number * len(time) if len(time) > min_len_number else min_width_number
490
            if line.width > 24:
491
                line.width = 24
492
            line.dLbls = DataLabelList()
493
            line.dLbls.dLblPos = 't'
494
            line.dLbls.showVal = True
495
            line.dLbls.showPercent = False
496
            chart_col = 'B'
497
            chart_cell = chart_col + str(chart_start_row_number + 6 * i)
498
            ws.add_chart(line, chart_cell)
499
500
    ##########################################
501
    has_parameters_names_and_timestamps_and_values_data = True
502
503
    ca_len = len(report['reporting_period']['names'])
504
    current_sheet_parameters_row_number = chart_start_row_number + ca_len * 6
505
    if 'parameters' not in report.keys() or \
506
            report['parameters'] is None or \
507
            'names' not in report['parameters'].keys() or \
508
            report['parameters']['names'] is None or \
509
            len(report['parameters']['names']) == 0 or \
510
            'timestamps' not in report['parameters'].keys() or \
511
            report['parameters']['timestamps'] is None or \
512
            len(report['parameters']['timestamps']) == 0 or \
513
            'values' not in report['parameters'].keys() or \
514
            report['parameters']['values'] is None or \
515
            len(report['parameters']['values']) == 0 or \
516
            timestamps_data_all_equal_0(report['parameters']['timestamps']):
517
        has_parameters_names_and_timestamps_and_values_data = False
518
    if has_parameters_names_and_timestamps_and_values_data:
519
520
        ###############################
521
        # new worksheet
522
        ###############################
523
524
        parameters_data = report['parameters']
525
526
        parameters_names_len = len(parameters_data['names'])
527
528
        parameters_ws = wb.create_sheet('相关参数')
529
530
        parameters_timestamps_data_max_len = \
531
            get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps']))
532
533
        # Row height
534
        parameters_ws.row_dimensions[1].height = 102
535
        for i in range(2, 7 + 1):
536
            parameters_ws.row_dimensions[i].height = 42
537
538
        for i in range(8, parameters_timestamps_data_max_len + 10):
539
            parameters_ws.row_dimensions[i].height = 60
540
541
        # Col width
542
        parameters_ws.column_dimensions['A'].width = 1.5
543
544
        parameters_ws.column_dimensions['B'].width = 25.0
545
546
        for i in range(3, 12 + parameters_names_len * 3):
547
            parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0
548
549
        # Img
550
        img = Image("excelexporters/myems.png")
551
        img.width = img.width * 0.85
552
        img.height = img.height * 0.85
553
        # img = Image("myems.png")
554
        parameters_ws.add_image(img, 'B1')
555
556
        # Title
557
        parameters_ws.row_dimensions[3].height = 60
558
559
        parameters_ws['B3'].font = name_font
560
        parameters_ws['B3'].alignment = b_r_alignment
561
        parameters_ws['B3'] = 'Name:'
562
        parameters_ws['C3'].border = b_border
563
        parameters_ws['C3'].alignment = b_c_alignment
564
        parameters_ws['C3'].font = name_font
565
        parameters_ws['C3'] = name
566
567
        parameters_ws['D3'].font = name_font
568
        parameters_ws['D3'].alignment = b_r_alignment
569
        parameters_ws['D3'] = 'Period:'
570
        parameters_ws['E3'].border = b_border
571
        parameters_ws['E3'].alignment = b_c_alignment
572
        parameters_ws['E3'].font = name_font
573
        parameters_ws['E3'] = period_type
574
575
        parameters_ws['F3'].font = name_font
576
        parameters_ws['F3'].alignment = b_r_alignment
577
        parameters_ws['F3'] = 'Date:'
578
        parameters_ws['G3'].border = b_border
579
        parameters_ws['G3'].alignment = b_c_alignment
580
        parameters_ws['G3'].font = name_font
581
        parameters_ws['G3'] = reporting_start_datetime_local + "__" + reporting_end_datetime_local
582
        parameters_ws.merge_cells("G3:H3")
583
584
        parameters_ws_current_row_number = 6
585
586
        parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font
587
        parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' 相关参数'
588
589
        parameters_ws_current_row_number += 1
590
591
        parameters_table_start_row_number = parameters_ws_current_row_number
592
593
        parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80
594
595
        parameters_ws_current_row_number += 1
596
597
        table_current_col_number = 'B'
598
599
        for i in range(0, parameters_names_len):
600
601
            if len(parameters_data['timestamps'][i]) == 0:
602
                continue
603
604
            parameters_ws[table_current_col_number + str(parameters_ws_current_row_number - 1)].fill = table_fill
605
            parameters_ws[table_current_col_number + str(parameters_ws_current_row_number - 1)].border = f_border
606
607
            col = decimal_to_column(column_to_decimal(table_current_col_number) + 1)
608
609
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
610
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
611
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].font = name_font
612
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].alignment = c_c_alignment
613
            parameters_ws[col + str(parameters_ws_current_row_number - 1)] = parameters_data['names'][i]
614
615
            table_current_row_number = parameters_ws_current_row_number
616
617
            for j, value in enumerate(list(parameters_data['timestamps'][i])):
618
                col = table_current_col_number
619
620
                parameters_ws[col + str(table_current_row_number)].border = f_border
621
                parameters_ws[col + str(table_current_row_number)].font = title_font
622
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
623
                parameters_ws[col + str(table_current_row_number)] = value
624
625
                col = decimal_to_column(column_to_decimal(col) + 1)
626
627
                parameters_ws[col + str(table_current_row_number)].border = f_border
628
                parameters_ws[col + str(table_current_row_number)].font = title_font
629
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
630
                parameters_ws[col + str(table_current_row_number)] = round(parameters_data['values'][i][j], 2)
631
632
                table_current_row_number += 1
633
634
            table_current_col_number = decimal_to_column(column_to_decimal(table_current_col_number) + 3)
635
636
        ########################################################
637
        # parameters chart and parameters table
638
        ########################################################
639
640
        ws['B' + str(current_sheet_parameters_row_number)].font = title_font
641
        ws['B' + str(current_sheet_parameters_row_number)] = name + ' 相关参数'
642
643
        current_sheet_parameters_row_number += 1
644
645
        chart_start_row_number = current_sheet_parameters_row_number
646
647
        col_index = 0
648
649
        for i in range(0, parameters_names_len):
650
651
            if len(parameters_data['timestamps'][i]) == 0:
652
                continue
653
654
            line = LineChart()
655
            data_col = 3 + col_index * 3
656
            labels_col = 2 + col_index * 3
657
            col_index += 1
658
            line.title = '相关参数 - ' + \
659
                         parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value
660
            labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1,
661
                               max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
662
            line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number,
663
                                  max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
664
            line.add_data(line_data, titles_from_data=True)
665
            line.set_categories(labels)
666
            line_data = line.series[0]
667
            line_data.marker.symbol = "circle"
668
            line_data.smooth = True
669
            line.x_axis.crosses = 'min'
670
            line.height = 8.25
671
            line.width = 24
672
            line.dLbls = DataLabelList()
673
            line.dLbls.dLblPos = 't'
674
            line.dLbls.showVal = False
675
            line.dLbls.showPercent = False
676
            chart_col = 'B'
677
            chart_cell = chart_col + str(chart_start_row_number)
678
            chart_start_row_number += 6
679
            ws.add_chart(line, chart_cell)
680
681
        current_sheet_parameters_row_number = chart_start_row_number
682
683
        current_sheet_parameters_row_number += 1
684
685
    filename = str(uuid.uuid4()) + '.xlsx'
686
    wb.save(filename)
687
688
    return filename
689
690
691
def group_by_category(category_list):
692
    category_dict = dict()
693
    for i, value in enumerate(category_list):
694
        if value not in category_dict.keys():
695
            category_dict[value] = list()
696
        category_dict[value].append(i)
697
    return category_dict
698