Code Duplication    Length = 467-470 lines in 3 locations

excelexporters/spacestatistics.py 1 location

@@ 62-531 (lines=470) @@
59
    return base64_message
60
61
62
def generate_excel(report,
63
                   name,
64
                   reporting_start_datetime_local,
65
                   reporting_end_datetime_local,
66
                   period_type):
67
    wb = Workbook()
68
    ws = wb.active
69
70
    # Row height
71
    ws.row_dimensions[1].height = 121
72
73
    for i in range(2, 37 + 1):
74
        ws.row_dimensions[i].height = 30
75
76
    for i in range(38, 90 + 1):
77
        ws.row_dimensions[i].height = 30
78
79
    # Col width
80
    ws.column_dimensions['A'].width = 1.5
81
    ws.column_dimensions['B'].width = 20.0
82
83
    for i in range(ord('C'), ord('I')):
84
        ws.column_dimensions[chr(i)].width = 15.0
85
86
    # Font
87
    name_font = Font(name='Constantia', size=15, bold=True)
88
    title_font = Font(name='宋体', size=15, bold=True)
89
    # data_font = Font(name='Franklin Gothic Book', size=11)
90
91
    table_fill = PatternFill(fill_type='solid', fgColor='1F497D')
92
    f_border = Border(left=Side(border_style='medium', color='00000000'),
93
                      right=Side(border_style='medium', color='00000000'),
94
                      bottom=Side(border_style='medium', color='00000000'),
95
                      top=Side(border_style='medium', color='00000000')
96
                      )
97
    b_border = Border(
98
        bottom=Side(border_style='medium', color='00000000'),
99
    )
100
101
    b_c_alignment = Alignment(vertical='bottom',
102
                              horizontal='center',
103
                              text_rotation=0,
104
                              wrap_text=False,
105
                              shrink_to_fit=False,
106
                              indent=0)
107
    c_c_alignment = Alignment(vertical='center',
108
                              horizontal='center',
109
                              text_rotation=0,
110
                              wrap_text=False,
111
                              shrink_to_fit=False,
112
                              indent=0)
113
    b_r_alignment = Alignment(vertical='bottom',
114
                              horizontal='right',
115
                              text_rotation=0,
116
                              wrap_text=False,
117
                              shrink_to_fit=False,
118
                              indent=0)
119
    # c_r_alignment = Alignment(vertical='bottom',
120
    #                           horizontal='center',
121
    #                           text_rotation=0,
122
    #                           wrap_text=False,
123
    #                           shrink_to_fit=False,
124
    #                           indent=0)
125
126
    # Img
127
    img = Image("excelexporters/myems.png")
128
    # img = Image("myems.png")
129
    ws.add_image(img, 'B1')
130
131
    # Title
132
    ws['B3'].font = name_font
133
    ws['B3'].alignment = b_r_alignment
134
    ws['B3'] = 'Name:'
135
    ws['C3'].border = b_border
136
    ws['C3'].alignment = b_c_alignment
137
    ws['C3'].font = name_font
138
    ws['C3'] = name
139
140
    ws['D3'].font = name_font
141
    ws['D3'].alignment = b_r_alignment
142
    ws['D3'] = 'Period:'
143
    ws['E3'].border = b_border
144
    ws['E3'].alignment = b_c_alignment
145
    ws['E3'].font = name_font
146
    ws['E3'] = period_type
147
148
    ws['F3'].font = name_font
149
    ws['F3'].alignment = b_r_alignment
150
    ws['F3'] = 'Date:'
151
    ws['G3'].border = b_border
152
    ws['G3'].alignment = b_c_alignment
153
    ws['G3'].font = name_font
154
    ws['G3'] = reporting_start_datetime_local + "__" + reporting_end_datetime_local
155
    ws.merge_cells("G3:H3")
156
157
    if "reporting_period" not in report.keys() or \
158
            "names" not in report['reporting_period'].keys() or len(report['reporting_period']['names']) == 0:
159
        filename = str(uuid.uuid4()) + '.xlsx'
160
        wb.save(filename)
161
162
        return filename
163
    #################################################
164
    # First: 统计分析
165
    # 6: title
166
    # 7: table title
167
    # 8~ca_len table_data
168
    #################################################
169
    reporting_period_data = report['reporting_period']
170
171
    has_energy_data_flag = True
172
173
    if "names" not in reporting_period_data.keys() or \
174
            reporting_period_data['names'] is None or \
175
            len(reporting_period_data['names']) == 0:
176
        has_energy_data_flag = False
177
178
        filename = str(uuid.uuid4()) + '.xlsx'
179
        wb.save(filename)
180
181
        return filename
182
183
    if has_energy_data_flag:
184
        ws['B6'].font = title_font
185
        ws['B6'] = name + ' 统计分析'
186
        # ws['D6'].font = title_font
187
        # ws['D6'] = '面积' +report['space']['area']
188
189
        category = reporting_period_data['names']
190
191
        # table_title
192
        ws['B7'].fill = table_fill
193
        ws['B7'].font = title_font
194
        ws['B7'].alignment = c_c_alignment
195
        ws['B7'] = '报告期'
196
        ws['B7'].border = f_border
197
198
        ws['C7'].font = title_font
199
        ws['C7'].alignment = c_c_alignment
200
        ws['C7'] = '算术平均数'
201
        ws['C7'].border = f_border
202
203
        ws['D7'].font = title_font
204
        ws['D7'].alignment = c_c_alignment
205
        ws['D7'] = '中位数'
206
        ws['D7'].border = f_border
207
208
        ws['E7'].font = title_font
209
        ws['E7'].alignment = c_c_alignment
210
        ws['E7'] = '最小值'
211
        ws['E7'].border = f_border
212
213
        ws['F7'].font = title_font
214
        ws['F7'].alignment = c_c_alignment
215
        ws['F7'] = '最大值'
216
        ws['F7'].border = f_border
217
218
        ws['G7'].font = title_font
219
        ws['G7'].alignment = c_c_alignment
220
        ws['G7'] = '样本标准差'
221
        ws['G7'].border = f_border
222
223
        ws['H7'].font = title_font
224
        ws['H7'].alignment = c_c_alignment
225
        ws['H7'] = '样本方差'
226
        ws['H7'].border = f_border
227
228
        # table_data
229
230
        for i, value in enumerate(category):
231
            row = i*2 + 8
232
            ws['B' + str(row)].font = name_font
233
            ws['B' + str(row)].alignment = c_c_alignment
234
            ws['B' + str(row)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + " )"
235
            ws['B' + str(row)].border = f_border
236
237
            ws['B' + str(row + 1)].font = name_font
238
            ws['B' + str(row + 1)].alignment = c_c_alignment
239
            ws['B' + str(row + 1)] = "环比"
240
            ws['B' + str(row + 1)].border = f_border
241
242
            ws['C' + str(row)].font = name_font
243
            ws['C' + str(row)].alignment = c_c_alignment
244
            ws['C' + str(row)] = round(reporting_period_data['means'][i], 2) \
245
                if reporting_period_data['means'][i] is not None else ''
246
            ws['C' + str(row)].border = f_border
247
            ws['C' + str(row)].number_format = '0.00'
248
249
            ws['C' + str(row + 1)].font = name_font
250
            ws['C' + str(row + 1)].alignment = c_c_alignment
251
            ws['C' + str(row + 1)] = str(round(reporting_period_data['means_increment_rate'][i] * 100, 2)) + "%" \
252
                if reporting_period_data['means_increment_rate'][i] is not None else '0.00%'
253
            ws['C' + str(row + 1)].border = f_border
254
255
            ws['D' + str(row)].font = name_font
256
            ws['D' + str(row)].alignment = c_c_alignment
257
            ws['D' + str(row)] = round(reporting_period_data['medians'][i], 2) \
258
                if reporting_period_data['medians'][i] is not None else ''
259
            ws['D' + str(row)].border = f_border
260
            ws['D' + str(row)].number_format = '0.00'
261
262
            ws['D' + str(row + 1)].font = name_font
263
            ws['D' + str(row + 1)].alignment = c_c_alignment
264
            ws['D' + str(row + 1)] = str(round(reporting_period_data['medians_increment_rate'][i] * 100, 2)) + "%" \
265
                if reporting_period_data['medians_increment_rate'][i] is not None else '0.00%'
266
            ws['D' + str(row + 1)].border = f_border
267
268
            ws['E' + str(row)].font = name_font
269
            ws['E' + str(row)].alignment = c_c_alignment
270
            ws['E' + str(row)] = round(reporting_period_data['minimums'][i], 2) \
271
                if reporting_period_data['minimums'][i] is not None else ''
272
            ws['E' + str(row)].border = f_border
273
            ws['E' + str(row)].number_format = '0.00'
274
275
            ws['E' + str(row + 1)].font = name_font
276
            ws['E' + str(row + 1)].alignment = c_c_alignment
277
            ws['E' + str(row + 1)] = str(round(reporting_period_data['minimums_increment_rate'][i] * 100, 2)) + "%" \
278
                if reporting_period_data['minimums_increment_rate'][i] is not None else '0.00%'
279
            ws['E' + str(row + 1)].border = f_border
280
281
            ws['F' + str(row)].font = name_font
282
            ws['F' + str(row)].alignment = c_c_alignment
283
            ws['F' + str(row)] = round(reporting_period_data['maximums'][i], 2) \
284
                if reporting_period_data['maximums'][i] is not None else ''
285
            ws['F' + str(row)].border = f_border
286
            ws['F' + str(row)].number_format = '0.00'
287
288
            ws['F' + str(row + 1)].font = name_font
289
            ws['F' + str(row + 1)].alignment = c_c_alignment
290
            ws['F' + str(row + 1)] = str(round(reporting_period_data['maximums_increment_rate'][i] * 100, 2)) + "%" \
291
                if reporting_period_data['maximums_increment_rate'][i] is not None else '0.00%'
292
            ws['F' + str(row + 1)].border = f_border
293
294
            ws['G' + str(row)].font = name_font
295
            ws['G' + str(row)].alignment = c_c_alignment
296
            ws['G' + str(row)] = round(reporting_period_data['stdevs'][i], 2) \
297
                if reporting_period_data['stdevs'][i] is not None else ''
298
            ws['G' + str(row)].border = f_border
299
            ws['G' + str(row)].number_format = '0.00'
300
301
            ws['G' + str(row + 1)].font = name_font
302
            ws['G' + str(row + 1)].alignment = c_c_alignment
303
            ws['G' + str(row + 1)] = str(round(reporting_period_data['stdevs_increment_rate'][i] * 100, 2)) + "%" \
304
                if reporting_period_data['stdevs_increment_rate'][i] is not None else '0.00%'
305
            ws['G' + str(row + 1)].border = f_border
306
307
            ws['H' + str(row)].font = name_font
308
            ws['H' + str(row)].alignment = c_c_alignment
309
            ws['H' + str(row)] = round(reporting_period_data['variances'][i], 2) \
310
                if reporting_period_data['variances'][i] is not None else ''
311
            ws['H' + str(row)].border = f_border
312
            ws['H' + str(row)].number_format = '0.00'
313
314
            ws['H' + str(row + 1)].font = name_font
315
            ws['H' + str(row + 1)].alignment = c_c_alignment
316
            ws['H' + str(row + 1)] = str(round(reporting_period_data['variances_increment_rate'][i] * 100, 2)) + "%" \
317
                if reporting_period_data['variances_increment_rate'][i] is not None else '0.00%'
318
            ws['H' + str(row + 1)].border = f_border
319
    #################################################
320
    # Second: 报告期消耗
321
    # 9 + ca_len * 2: title
322
    # 10 + ca_len * 2: table title
323
    # row_title + 2 ~ row_title + 2 + ca_len :  table_data
324
    #################################################
325
326
    if has_energy_data_flag:
327
        names = reporting_period_data['names']
328
        ca_len = len(names)
329
330
        row_title = 9 + ca_len * 2
331
332
        ws['B' + str(row_title)].font = title_font
333
        ws['B' + str(row_title)] = name + ' 单位面积值'
334
        ws['D' + str(row_title)].font = title_font
335
        ws['D' + str(row_title)] = str(report['space']['area']) + 'M²'
336
337
        category = reporting_period_data['names']
338
339
        # table_title
340
        ws['B' + str(row_title + 1)].fill = table_fill
341
        ws['B' + str(row_title + 1)].font = title_font
342
        ws['B' + str(row_title + 1)].alignment = c_c_alignment
343
        ws['B' + str(row_title + 1)] = '报告期'
344
        ws['B' + str(row_title + 1)].border = f_border
345
346
        ws['C' + str(row_title + 1)].font = title_font
347
        ws['C' + str(row_title + 1)].alignment = c_c_alignment
348
        ws['C' + str(row_title + 1)] = '算术平均数'
349
        ws['C' + str(row_title + 1)].border = f_border
350
351
        ws['D' + str(row_title + 1)].font = title_font
352
        ws['D' + str(row_title + 1)].alignment = c_c_alignment
353
        ws['D' + str(row_title + 1)] = '中位数'
354
        ws['D' + str(row_title + 1)].border = f_border
355
356
        ws['E' + str(row_title + 1)].font = title_font
357
        ws['E' + str(row_title + 1)].alignment = c_c_alignment
358
        ws['E' + str(row_title + 1)] = '最小值'
359
        ws['E' + str(row_title + 1)].border = f_border
360
361
        ws['F' + str(row_title + 1)].font = title_font
362
        ws['F' + str(row_title + 1)].alignment = c_c_alignment
363
        ws['F' + str(row_title + 1)] = '最大值'
364
        ws['F' + str(row_title + 1)].border = f_border
365
366
        ws['G' + str(row_title + 1)].font = title_font
367
        ws['G' + str(row_title + 1)].alignment = c_c_alignment
368
        ws['G' + str(row_title + 1)] = '样本标准差'
369
        ws['G' + str(row_title + 1)].border = f_border
370
371
        ws['H' + str(row_title + 1)].font = title_font
372
        ws['H' + str(row_title + 1)].alignment = c_c_alignment
373
        ws['H' + str(row_title + 1)] = '样本方差'
374
        ws['H' + str(row_title + 1)].border = f_border
375
376
        # table_data
377
378
        for i, value in enumerate(category):
379
            row_data = row_title + 2 + i
380
            ws['B' + str(row_data)].font = name_font
381
            ws['B' + str(row_data)].alignment = c_c_alignment
382
            ws['B' + str(row_data)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][
383
                i] + "/M²)"
384
            ws['B' + str(row_data)].border = f_border
385
386
            ws['C' + str(row_data)].font = name_font
387
            ws['C' + str(row_data)].alignment = c_c_alignment
388
            if reporting_period_data['means_per_unit_area'][i] \
389
                    or reporting_period_data['means_per_unit_area'][i] == 0:
390
                ws['C' + str(row_data)] = round(reporting_period_data['means_per_unit_area'][i], 2)
391
            ws['C' + str(row_data)].border = f_border
392
            ws['C' + str(row_data)].number_format = '0.00'
393
394
            ws['D' + str(row_data)].font = name_font
395
            ws['D' + str(row_data)].alignment = c_c_alignment
396
            if reporting_period_data['medians_per_unit_area'][i] \
397
                    or reporting_period_data['medians_per_unit_area'][i] == 0:
398
                ws['D' + str(row_data)] = round(reporting_period_data['medians_per_unit_area'][i], 2)
399
            ws['D' + str(row_data)].border = f_border
400
            ws['D' + str(row_data)].number_format = '0.00'
401
402
            ws['E' + str(row_data)].font = name_font
403
            ws['E' + str(row_data)].alignment = c_c_alignment
404
            if reporting_period_data['minimums_per_unit_area'][i] \
405
                    or reporting_period_data['minimums_per_unit_area'][i] == 0:
406
                ws['E' + str(row_data)] = round(reporting_period_data['minimums_per_unit_area'][i], 2)
407
            ws['E' + str(row_data)].border = f_border
408
            ws['E' + str(row_data)].number_format = '0.00'
409
410
            ws['F' + str(row_data)].font = name_font
411
            ws['F' + str(row_data)].alignment = c_c_alignment
412
            if reporting_period_data['maximums_per_unit_area'][i] \
413
                    or reporting_period_data['maximums_per_unit_area'][i] == 0:
414
                ws['F' + str(row_data)] = round(reporting_period_data['maximums_per_unit_area'][i], 2)
415
            ws['F' + str(row_data)].border = f_border
416
            ws['F' + str(row_data)].number_format = '0.00'
417
418
            ws['G' + str(row_data)].font = name_font
419
            ws['G' + str(row_data)].alignment = c_c_alignment
420
            if (reporting_period_data['stdevs_per_unit_area'][i]) \
421
                    or reporting_period_data['stdevs_per_unit_area'][i] == 0:
422
                ws['G' + str(row_data)] = round(reporting_period_data['stdevs_per_unit_area'][i], 2)
423
            ws['G' + str(row_data)].border = f_border
424
            ws['G' + str(row_data)].number_format = '0.00'
425
426
            ws['H' + str(row_data)].font = name_font
427
            ws['H' + str(row_data)].alignment = c_c_alignment
428
            if reporting_period_data['variances_per_unit_area'][i] \
429
                    or reporting_period_data['variances_per_unit_area'][i] == 0:
430
                ws['H' + str(row_data)] = round(reporting_period_data['variances_per_unit_area'][i], 2)
431
            ws['H' + str(row_data)].border = f_border
432
            ws['H' + str(row_data)].number_format = '0.00'
433
434
    ########################################################
435
    # Third: 详细数据
436
    # row_sat+row_title~ row_sat+row_title+time_len: line
437
    # row_sat+1+row_title: table title
438
    # i + row_sat + 2 + 10 * ca_len~: table_data
439
    ########################################################
440
    has_timestamps_flag = True
441
    if "timestamps" not in reporting_period_data.keys() or \
442
            reporting_period_data['timestamps'] is None or \
443
            len(reporting_period_data['timestamps']) == 0:
444
        has_timestamps_flag = False
445
446
    if has_timestamps_flag:
447
        timestamps = reporting_period_data['timestamps'][0]
448
        values = reporting_period_data['values']
449
        names = reporting_period_data['names']
450
        ca_len = len(names)
451
        time_len = len(timestamps)
452
        # title
453
        row_title = 10 * ca_len
454
        # row_st == row_statistical analysis table
455
        row_sat = 12 + 3 * ca_len
456
457
        ws['B' + str(row_sat+row_title)].font = title_font
458
        ws['B' + str(row_sat+row_title)] = name + ' 详细数据'
459
        # table_title
460
        ws['B' + str(row_sat+1+row_title)].fill = table_fill
461
        ws['B' + str(row_sat+1+row_title)].font = name_font
462
        ws['B' + str(row_sat+1+row_title)].alignment = c_c_alignment
463
        ws['B' + str(row_sat+1+row_title)] = "时间"
464
        ws['B' + str(row_sat+1+row_title)].border = f_border
465
466
        for i in range(0, ca_len):
467
            col = chr(ord('C') + i)
468
469
            ws[col + str(row_sat+1+row_title)].font = name_font
470
            ws[col + str(row_sat+1+row_title)].alignment = c_c_alignment
471
            ws[col + str(row_sat+1+row_title)] = names[i] + " - (" + reporting_period_data['units'][i] + ")"
472
            ws[col + str(row_sat+1+row_title)].border = f_border
473
        # table_date
474
        for i in range(0, time_len):
475
            rows = i + row_sat + 2 + 10 * ca_len
476
477
            ws['B' + str(rows)].font = name_font
478
            ws['B' + str(rows)].alignment = c_c_alignment
479
            ws['B' + str(rows)] = timestamps[i]
480
            ws['B' + str(rows)].border = f_border
481
482
            for index in range(0, ca_len):
483
                col = chr(ord('C') + index)
484
485
                ws[col + str(rows)].font = name_font
486
                ws[col + str(rows)].alignment = c_c_alignment
487
                ws[col + str(rows)] = round(values[index][i], 2)
488
                ws[col + str(rows)].number_format = '0.00'
489
                ws[col + str(rows)].border = f_border
490
491
        # 小计
492
        row_subtotals = row_sat + 2 + time_len + 10 * ca_len
493
        ws['B' + str(row_subtotals)].font = name_font
494
        ws['B' + str(row_subtotals)].alignment = c_c_alignment
495
        ws['B' + str(row_subtotals)] = "小计"
496
        ws['B' + str(row_subtotals)].border = f_border
497
498
        for i in range(0, ca_len):
499
            col = chr(ord('C') + i)
500
501
            ws[col + str(row_subtotals)].font = name_font
502
            ws[col + str(row_subtotals)].alignment = c_c_alignment
503
            ws[col + str(row_subtotals)] = round(reporting_period_data['subtotals'][i], 2)
504
            ws[col + str(row_subtotals)].border = f_border
505
            ws[col + str(row_subtotals)].number_format = '0.00'
506
507
        # LineChart
508
        for i in range(0, ca_len):
509
510
            lc = LineChart()
511
            lc.title = "报告期消耗" + " - " + names[i] + "(" + reporting_period_data['units'][i] + ")"
512
            lc.style = 10
513
            lc.height = 8.40  # cm 1.05*8 1.05cm = 30 pt
514
            lc.width = 31
515
            lc.x_axis.majorTickMark = 'in'
516
            lc.y_axis.majorTickMark = 'in'
517
            times = Reference(ws, min_col=2, min_row=row_sat + 2 + row_title,
518
                              max_row=row_sat + 2 + row_title + time_len)
519
            lc_data = Reference(ws, min_col=3 + i, min_row=row_sat + 1 + row_title,
520
                                max_row=row_sat + 1 + row_title + time_len)
521
            lc.add_data(lc_data, titles_from_data=True)
522
            lc.set_categories(times)
523
            ser = lc.series[0]
524
            ser.marker.symbol = "diamond"
525
            ser.marker.size = 5
526
            ws.add_chart(lc, 'B' + str(row_sat + 10 * i))
527
528
    filename = str(uuid.uuid4()) + '.xlsx'
529
    wb.save(filename)
530
531
    return filename
532

excelexporters/tenantstatistics.py 1 location

@@ 62-531 (lines=470) @@
59
    return base64_message
60
61
62
def generate_excel(report,
63
                   name,
64
                   reporting_start_datetime_local,
65
                   reporting_end_datetime_local,
66
                   period_type):
67
    wb = Workbook()
68
    ws = wb.active
69
70
    # Row height
71
    ws.row_dimensions[1].height = 121
72
73
    for i in range(2, 37 + 1):
74
        ws.row_dimensions[i].height = 30
75
76
    for i in range(38, 90 + 1):
77
        ws.row_dimensions[i].height = 30
78
79
    # Col width
80
    ws.column_dimensions['A'].width = 1.5
81
    ws.column_dimensions['B'].width = 20.0
82
83
    for i in range(ord('C'), ord('I')):
84
        ws.column_dimensions[chr(i)].width = 15.0
85
86
    # Font
87
    name_font = Font(name='Constantia', size=15, bold=True)
88
    title_font = Font(name='宋体', size=15, bold=True)
89
    # data_font = Font(name='Franklin Gothic Book', size=11)
90
91
    table_fill = PatternFill(fill_type='solid', fgColor='1F497D')
92
    f_border = Border(left=Side(border_style='medium', color='00000000'),
93
                      right=Side(border_style='medium', color='00000000'),
94
                      bottom=Side(border_style='medium', color='00000000'),
95
                      top=Side(border_style='medium', color='00000000')
96
                      )
97
    b_border = Border(
98
        bottom=Side(border_style='medium', color='00000000'),
99
    )
100
101
    b_c_alignment = Alignment(vertical='bottom',
102
                              horizontal='center',
103
                              text_rotation=0,
104
                              wrap_text=False,
105
                              shrink_to_fit=False,
106
                              indent=0)
107
    c_c_alignment = Alignment(vertical='center',
108
                              horizontal='center',
109
                              text_rotation=0,
110
                              wrap_text=False,
111
                              shrink_to_fit=False,
112
                              indent=0)
113
    b_r_alignment = Alignment(vertical='bottom',
114
                              horizontal='right',
115
                              text_rotation=0,
116
                              wrap_text=False,
117
                              shrink_to_fit=False,
118
                              indent=0)
119
    # c_r_alignment = Alignment(vertical='bottom',
120
    #                           horizontal='center',
121
    #                           text_rotation=0,
122
    #                           wrap_text=False,
123
    #                           shrink_to_fit=False,
124
    #                           indent=0)
125
126
    # Img
127
    img = Image("excelexporters/myems.png")
128
    # img = Image("myems.png")
129
    ws.add_image(img, 'B1')
130
131
    # Title
132
    ws['B3'].font = name_font
133
    ws['B3'].alignment = b_r_alignment
134
    ws['B3'] = 'Name:'
135
    ws['C3'].border = b_border
136
    ws['C3'].alignment = b_c_alignment
137
    ws['C3'].font = name_font
138
    ws['C3'] = name
139
140
    ws['D3'].font = name_font
141
    ws['D3'].alignment = b_r_alignment
142
    ws['D3'] = 'Period:'
143
    ws['E3'].border = b_border
144
    ws['E3'].alignment = b_c_alignment
145
    ws['E3'].font = name_font
146
    ws['E3'] = period_type
147
148
    ws['F3'].font = name_font
149
    ws['F3'].alignment = b_r_alignment
150
    ws['F3'] = 'Date:'
151
    ws['G3'].border = b_border
152
    ws['G3'].alignment = b_c_alignment
153
    ws['G3'].font = name_font
154
    ws['G3'] = reporting_start_datetime_local + "__" + reporting_end_datetime_local
155
    ws.merge_cells("G3:H3")
156
157
    if "reporting_period" not in report.keys() or \
158
            "names" not in report['reporting_period'].keys() or len(report['reporting_period']['names']) == 0:
159
        filename = str(uuid.uuid4()) + '.xlsx'
160
        wb.save(filename)
161
162
        return filename
163
    #################################################
164
    # First: 统计分析
165
    # 6: title
166
    # 7: table title
167
    # 8~ca_len table_data
168
    #################################################
169
    reporting_period_data = report['reporting_period']
170
171
    has_energy_data_flag = True
172
173
    if "names" not in reporting_period_data.keys() or \
174
            reporting_period_data['names'] is None or \
175
            len(reporting_period_data['names']) == 0:
176
        has_energy_data_flag = False
177
178
        filename = str(uuid.uuid4()) + '.xlsx'
179
        wb.save(filename)
180
181
        return filename
182
183
    if has_energy_data_flag:
184
        ws['B6'].font = title_font
185
        ws['B6'] = name + ' 统计分析'
186
        # ws['D6'].font = title_font
187
        # ws['D6'] = '面积' +report['space']['area']
188
189
        category = reporting_period_data['names']
190
191
        # table_title
192
        ws['B7'].fill = table_fill
193
        ws['B7'].font = title_font
194
        ws['B7'].alignment = c_c_alignment
195
        ws['B7'] = '报告期'
196
        ws['B7'].border = f_border
197
198
        ws['C7'].font = title_font
199
        ws['C7'].alignment = c_c_alignment
200
        ws['C7'] = '算术平均数'
201
        ws['C7'].border = f_border
202
203
        ws['D7'].font = title_font
204
        ws['D7'].alignment = c_c_alignment
205
        ws['D7'] = '中位数'
206
        ws['D7'].border = f_border
207
208
        ws['E7'].font = title_font
209
        ws['E7'].alignment = c_c_alignment
210
        ws['E7'] = '最小值'
211
        ws['E7'].border = f_border
212
213
        ws['F7'].font = title_font
214
        ws['F7'].alignment = c_c_alignment
215
        ws['F7'] = '最大值'
216
        ws['F7'].border = f_border
217
218
        ws['G7'].font = title_font
219
        ws['G7'].alignment = c_c_alignment
220
        ws['G7'] = '样本标准差'
221
        ws['G7'].border = f_border
222
223
        ws['H7'].font = title_font
224
        ws['H7'].alignment = c_c_alignment
225
        ws['H7'] = '样本方差'
226
        ws['H7'].border = f_border
227
228
        # table_data
229
230
        for i, value in enumerate(category):
231
            row = i*2 + 8
232
            ws['B' + str(row)].font = name_font
233
            ws['B' + str(row)].alignment = c_c_alignment
234
            ws['B' + str(row)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + " )"
235
            ws['B' + str(row)].border = f_border
236
237
            ws['B' + str(row + 1)].font = name_font
238
            ws['B' + str(row + 1)].alignment = c_c_alignment
239
            ws['B' + str(row + 1)] = "环比"
240
            ws['B' + str(row + 1)].border = f_border
241
242
            ws['C' + str(row)].font = name_font
243
            ws['C' + str(row)].alignment = c_c_alignment
244
            ws['C' + str(row)] = round(reporting_period_data['means'][i], 2) \
245
                if reporting_period_data['means'][i] is not None else ''
246
            ws['C' + str(row)].border = f_border
247
            ws['C' + str(row)].number_format = '0.00'
248
249
            ws['C' + str(row + 1)].font = name_font
250
            ws['C' + str(row + 1)].alignment = c_c_alignment
251
            ws['C' + str(row + 1)] = str(round(reporting_period_data['means_increment_rate'][i] * 100, 2)) + "%" \
252
                if reporting_period_data['means_increment_rate'][i] is not None else '0.00%'
253
            ws['C' + str(row + 1)].border = f_border
254
255
            ws['D' + str(row)].font = name_font
256
            ws['D' + str(row)].alignment = c_c_alignment
257
            ws['D' + str(row)] = round(reporting_period_data['medians'][i], 2) \
258
                if reporting_period_data['medians'][i] is not None else ''
259
            ws['D' + str(row)].border = f_border
260
            ws['D' + str(row)].number_format = '0.00'
261
262
            ws['D' + str(row + 1)].font = name_font
263
            ws['D' + str(row + 1)].alignment = c_c_alignment
264
            ws['D' + str(row + 1)] = str(round(reporting_period_data['medians_increment_rate'][i] * 100, 2)) + "%" \
265
                if reporting_period_data['medians_increment_rate'][i] is not None else '0.00%'
266
            ws['D' + str(row + 1)].border = f_border
267
268
            ws['E' + str(row)].font = name_font
269
            ws['E' + str(row)].alignment = c_c_alignment
270
            ws['E' + str(row)] = round(reporting_period_data['minimums'][i], 2) \
271
                if reporting_period_data['minimums'][i] is not None else ''
272
            ws['E' + str(row)].border = f_border
273
            ws['E' + str(row)].number_format = '0.00'
274
275
            ws['E' + str(row + 1)].font = name_font
276
            ws['E' + str(row + 1)].alignment = c_c_alignment
277
            ws['E' + str(row + 1)] = str(round(reporting_period_data['minimums_increment_rate'][i] * 100, 2)) + "%" \
278
                if reporting_period_data['minimums_increment_rate'][i] is not None else '0.00%'
279
            ws['E' + str(row + 1)].border = f_border
280
281
            ws['F' + str(row)].font = name_font
282
            ws['F' + str(row)].alignment = c_c_alignment
283
            ws['F' + str(row)] = round(reporting_period_data['maximums'][i], 2) \
284
                if reporting_period_data['maximums'][i] is not None else ''
285
            ws['F' + str(row)].border = f_border
286
            ws['F' + str(row)].number_format = '0.00'
287
288
            ws['F' + str(row + 1)].font = name_font
289
            ws['F' + str(row + 1)].alignment = c_c_alignment
290
            ws['F' + str(row + 1)] = str(round(reporting_period_data['maximums_increment_rate'][i] * 100, 2)) + "%" \
291
                if reporting_period_data['maximums_increment_rate'][i] is not None else '0.00%'
292
            ws['F' + str(row + 1)].border = f_border
293
294
            ws['G' + str(row)].font = name_font
295
            ws['G' + str(row)].alignment = c_c_alignment
296
            ws['G' + str(row)] = round(reporting_period_data['stdevs'][i], 2) \
297
                if reporting_period_data['stdevs'][i] is not None else ''
298
            ws['G' + str(row)].border = f_border
299
            ws['G' + str(row)].number_format = '0.00'
300
301
            ws['G' + str(row + 1)].font = name_font
302
            ws['G' + str(row + 1)].alignment = c_c_alignment
303
            ws['G' + str(row + 1)] = str(round(reporting_period_data['stdevs_increment_rate'][i] * 100, 2)) + "%" \
304
                if reporting_period_data['stdevs_increment_rate'][i] is not None else '0.00%'
305
            ws['G' + str(row + 1)].border = f_border
306
307
            ws['H' + str(row)].font = name_font
308
            ws['H' + str(row)].alignment = c_c_alignment
309
            ws['H' + str(row)] = round(reporting_period_data['variances'][i], 2) \
310
                if reporting_period_data['variances'][i] is not None else ''
311
            ws['H' + str(row)].border = f_border
312
            ws['H' + str(row)].number_format = '0.00'
313
314
            ws['H' + str(row + 1)].font = name_font
315
            ws['H' + str(row + 1)].alignment = c_c_alignment
316
            ws['H' + str(row + 1)] = str(round(reporting_period_data['variances_increment_rate'][i] * 100, 2)) + "%" \
317
                if reporting_period_data['variances_increment_rate'][i] is not None else '0.00%'
318
            ws['H' + str(row + 1)].border = f_border
319
    #################################################
320
    # Second: 报告期消耗
321
    # 9 + ca_len * 2: title
322
    # 10 + ca_len * 2: table title
323
    # row_title + 2 ~ row_title + 2 + ca_len :  table_data
324
    #################################################
325
326
    if has_energy_data_flag:
327
        names = reporting_period_data['names']
328
        ca_len = len(names)
329
330
        row_title = 9 + ca_len * 2
331
332
        ws['B' + str(row_title)].font = title_font
333
        ws['B' + str(row_title)] = name + ' 单位面积值'
334
        ws['D' + str(row_title)].font = title_font
335
        ws['D' + str(row_title)] = str(report['tenant']['area']) + 'M²'
336
337
        category = reporting_period_data['names']
338
339
        # table_title
340
        ws['B' + str(row_title + 1)].fill = table_fill
341
        ws['B' + str(row_title + 1)].font = title_font
342
        ws['B' + str(row_title + 1)].alignment = c_c_alignment
343
        ws['B' + str(row_title + 1)] = '报告期'
344
        ws['B' + str(row_title + 1)].border = f_border
345
346
        ws['C' + str(row_title + 1)].font = title_font
347
        ws['C' + str(row_title + 1)].alignment = c_c_alignment
348
        ws['C' + str(row_title + 1)] = '算术平均数'
349
        ws['C' + str(row_title + 1)].border = f_border
350
351
        ws['D' + str(row_title + 1)].font = title_font
352
        ws['D' + str(row_title + 1)].alignment = c_c_alignment
353
        ws['D' + str(row_title + 1)] = '中位数'
354
        ws['D' + str(row_title + 1)].border = f_border
355
356
        ws['E' + str(row_title + 1)].font = title_font
357
        ws['E' + str(row_title + 1)].alignment = c_c_alignment
358
        ws['E' + str(row_title + 1)] = '最小值'
359
        ws['E' + str(row_title + 1)].border = f_border
360
361
        ws['F' + str(row_title + 1)].font = title_font
362
        ws['F' + str(row_title + 1)].alignment = c_c_alignment
363
        ws['F' + str(row_title + 1)] = '最大值'
364
        ws['F' + str(row_title + 1)].border = f_border
365
366
        ws['G' + str(row_title + 1)].font = title_font
367
        ws['G' + str(row_title + 1)].alignment = c_c_alignment
368
        ws['G' + str(row_title + 1)] = '样本标准差'
369
        ws['G' + str(row_title + 1)].border = f_border
370
371
        ws['H' + str(row_title + 1)].font = title_font
372
        ws['H' + str(row_title + 1)].alignment = c_c_alignment
373
        ws['H' + str(row_title + 1)] = '样本方差'
374
        ws['H' + str(row_title + 1)].border = f_border
375
376
        # table_data
377
378
        for i, value in enumerate(category):
379
            row_data = row_title + 2 + i
380
            ws['B' + str(row_data)].font = name_font
381
            ws['B' + str(row_data)].alignment = c_c_alignment
382
            ws['B' + str(row_data)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][
383
                i] + "/M²)"
384
            ws['B' + str(row_data)].border = f_border
385
386
            ws['C' + str(row_data)].font = name_font
387
            ws['C' + str(row_data)].alignment = c_c_alignment
388
            if reporting_period_data['means_per_unit_area'][i] \
389
                    or reporting_period_data['means_per_unit_area'][i] == 0:
390
                ws['C' + str(row_data)] = round(reporting_period_data['means_per_unit_area'][i], 2)
391
            ws['C' + str(row_data)].border = f_border
392
            ws['C' + str(row_data)].number_format = '0.00'
393
394
            ws['D' + str(row_data)].font = name_font
395
            ws['D' + str(row_data)].alignment = c_c_alignment
396
            if reporting_period_data['medians_per_unit_area'][i] \
397
                    or reporting_period_data['medians_per_unit_area'][i] == 0:
398
                ws['D' + str(row_data)] = round(reporting_period_data['medians_per_unit_area'][i], 2)
399
            ws['D' + str(row_data)].border = f_border
400
            ws['D' + str(row_data)].number_format = '0.00'
401
402
            ws['E' + str(row_data)].font = name_font
403
            ws['E' + str(row_data)].alignment = c_c_alignment
404
            if reporting_period_data['minimums_per_unit_area'][i] \
405
                    or reporting_period_data['minimums_per_unit_area'][i] == 0:
406
                ws['E' + str(row_data)] = round(reporting_period_data['minimums_per_unit_area'][i], 2)
407
            ws['E' + str(row_data)].border = f_border
408
            ws['E' + str(row_data)].number_format = '0.00'
409
410
            ws['F' + str(row_data)].font = name_font
411
            ws['F' + str(row_data)].alignment = c_c_alignment
412
            if reporting_period_data['maximums_per_unit_area'][i] \
413
                    or reporting_period_data['maximums_per_unit_area'][i] == 0:
414
                ws['F' + str(row_data)] = round(reporting_period_data['maximums_per_unit_area'][i], 2)
415
            ws['F' + str(row_data)].border = f_border
416
            ws['F' + str(row_data)].number_format = '0.00'
417
418
            ws['G' + str(row_data)].font = name_font
419
            ws['G' + str(row_data)].alignment = c_c_alignment
420
            if (reporting_period_data['stdevs_per_unit_area'][i]) \
421
                    or reporting_period_data['stdevs_per_unit_area'][i] == 0:
422
                ws['G' + str(row_data)] = round(reporting_period_data['stdevs_per_unit_area'][i], 2)
423
            ws['G' + str(row_data)].border = f_border
424
            ws['G' + str(row_data)].number_format = '0.00'
425
426
            ws['H' + str(row_data)].font = name_font
427
            ws['H' + str(row_data)].alignment = c_c_alignment
428
            if reporting_period_data['variances_per_unit_area'][i] \
429
                    or reporting_period_data['variances_per_unit_area'][i] == 0:
430
                ws['H' + str(row_data)] = round(reporting_period_data['variances_per_unit_area'][i], 2)
431
            ws['H' + str(row_data)].border = f_border
432
            ws['H' + str(row_data)].number_format = '0.00'
433
434
    ########################################################
435
    # Third: 详细数据
436
    # row_sat+row_title~ row_sat+row_title+time_len: line
437
    # row_sat+1+row_title: table title
438
    # i + row_sat + 2 + 10 * ca_len~: table_data
439
    ########################################################
440
    has_timestamps_flag = True
441
    if "timestamps" not in reporting_period_data.keys() or \
442
            reporting_period_data['timestamps'] is None or \
443
            len(reporting_period_data['timestamps']) == 0:
444
        has_timestamps_flag = False
445
446
    if has_timestamps_flag:
447
        timestamps = reporting_period_data['timestamps'][0]
448
        values = reporting_period_data['values']
449
        names = reporting_period_data['names']
450
        ca_len = len(names)
451
        time_len = len(timestamps)
452
        # title
453
        row_title = 10 * ca_len
454
        # row_st == row_statistical analysis table
455
        row_sat = 12 + 3 * ca_len
456
457
        ws['B' + str(row_sat+row_title)].font = title_font
458
        ws['B' + str(row_sat+row_title)] = name + ' 详细数据'
459
        # table_title
460
        ws['B' + str(row_sat+1+row_title)].fill = table_fill
461
        ws['B' + str(row_sat+1+row_title)].font = name_font
462
        ws['B' + str(row_sat+1+row_title)].alignment = c_c_alignment
463
        ws['B' + str(row_sat+1+row_title)] = "时间"
464
        ws['B' + str(row_sat+1+row_title)].border = f_border
465
466
        for i in range(0, ca_len):
467
            col = chr(ord('C') + i)
468
469
            ws[col + str(row_sat+1+row_title)].font = name_font
470
            ws[col + str(row_sat+1+row_title)].alignment = c_c_alignment
471
            ws[col + str(row_sat+1+row_title)] = names[i] + " - (" + reporting_period_data['units'][i] + ")"
472
            ws[col + str(row_sat+1+row_title)].border = f_border
473
        # table_date
474
        for i in range(0, time_len):
475
            rows = i + row_sat + 2 + 10 * ca_len
476
477
            ws['B' + str(rows)].font = name_font
478
            ws['B' + str(rows)].alignment = c_c_alignment
479
            ws['B' + str(rows)] = timestamps[i]
480
            ws['B' + str(rows)].border = f_border
481
482
            for index in range(0, ca_len):
483
                col = chr(ord('C') + index)
484
485
                ws[col + str(rows)].font = name_font
486
                ws[col + str(rows)].alignment = c_c_alignment
487
                ws[col + str(rows)] = round(values[index][i], 2)
488
                ws[col + str(rows)].number_format = '0.00'
489
                ws[col + str(rows)].border = f_border
490
491
        # 小计
492
        row_subtotals = row_sat + 2 + time_len + 10 * ca_len
493
        ws['B' + str(row_subtotals)].font = name_font
494
        ws['B' + str(row_subtotals)].alignment = c_c_alignment
495
        ws['B' + str(row_subtotals)] = "小计"
496
        ws['B' + str(row_subtotals)].border = f_border
497
498
        for i in range(0, ca_len):
499
            col = chr(ord('C') + i)
500
501
            ws[col + str(row_subtotals)].font = name_font
502
            ws[col + str(row_subtotals)].alignment = c_c_alignment
503
            ws[col + str(row_subtotals)] = round(reporting_period_data['subtotals'][i], 2)
504
            ws[col + str(row_subtotals)].border = f_border
505
            ws[col + str(row_subtotals)].number_format = '0.00'
506
507
        # LineChart
508
        for i in range(0, ca_len):
509
510
            lc = LineChart()
511
            lc.title = "报告期消耗" + " - " + names[i] + "(" + reporting_period_data['units'][i] + ")"
512
            lc.style = 10
513
            lc.height = 8.40  # cm 1.05*8 1.05cm = 30 pt
514
            lc.width = 31
515
            lc.x_axis.majorTickMark = 'in'
516
            lc.y_axis.majorTickMark = 'in'
517
            times = Reference(ws, min_col=2, min_row=row_sat + 2 + row_title,
518
                              max_row=row_sat + 2 + row_title + time_len)
519
            lc_data = Reference(ws, min_col=3 + i, min_row=row_sat + 1 + row_title,
520
                                max_row=row_sat + 1 + row_title + time_len)
521
            lc.add_data(lc_data, titles_from_data=True)
522
            lc.set_categories(times)
523
            ser = lc.series[0]
524
            ser.marker.symbol = "diamond"
525
            ser.marker.size = 5
526
            ws.add_chart(lc, 'B' + str(row_sat + 10 * i))
527
528
    filename = str(uuid.uuid4()) + '.xlsx'
529
    wb.save(filename)
530
531
    return filename
532

excelexporters/storestatistics.py 1 location

@@ 63-529 (lines=467) @@
60
    return base64_message
61
62
63
def generate_excel(report,
64
                   name,
65
                   reporting_start_datetime_local,
66
                   reporting_end_datetime_local,
67
                   period_type):
68
    wb = Workbook()
69
    ws = wb.active
70
71
    # Row height
72
    ws.row_dimensions[1].height = 121
73
74
    for i in range(2, 37 + 1):
75
        ws.row_dimensions[i].height = 30
76
77
    for i in range(38, 90 + 1):
78
        ws.row_dimensions[i].height = 30
79
80
    # Col width
81
    ws.column_dimensions['A'].width = 1.5
82
    ws.column_dimensions['B'].width = 20.0
83
84
    for i in range(ord('C'), ord('I')):
85
        ws.column_dimensions[chr(i)].width = 15.0
86
87
    # Font
88
    name_font = Font(name='Constantia', size=15, bold=True)
89
    title_font = Font(name='宋体', size=15, bold=True)
90
    # data_font = Font(name='Franklin Gothic Book', size=11)
91
92
    table_fill = PatternFill(fill_type='solid', fgColor='1F497D')
93
    f_border = Border(left=Side(border_style='medium', color='00000000'),
94
                      right=Side(border_style='medium', color='00000000'),
95
                      bottom=Side(border_style='medium', color='00000000'),
96
                      top=Side(border_style='medium', color='00000000')
97
                      )
98
    b_border = Border(
99
        bottom=Side(border_style='medium', color='00000000'),
100
    )
101
102
    b_c_alignment = Alignment(vertical='bottom',
103
                              horizontal='center',
104
                              text_rotation=0,
105
                              wrap_text=False,
106
                              shrink_to_fit=False,
107
                              indent=0)
108
    c_c_alignment = Alignment(vertical='center',
109
                              horizontal='center',
110
                              text_rotation=0,
111
                              wrap_text=False,
112
                              shrink_to_fit=False,
113
                              indent=0)
114
    b_r_alignment = Alignment(vertical='bottom',
115
                              horizontal='right',
116
                              text_rotation=0,
117
                              wrap_text=False,
118
                              shrink_to_fit=False,
119
                              indent=0)
120
    # c_r_alignment = Alignment(vertical='bottom',
121
    #                           horizontal='center',
122
    #                           text_rotation=0,
123
    #                           wrap_text=False,
124
    #                           shrink_to_fit=False,
125
    #                           indent=0)
126
127
    # Img
128
    img = Image("excelexporters/myems.png")
129
    # img = Image("myems.png")
130
    ws.add_image(img, 'B1')
131
132
    # Title
133
    ws['B3'].font = name_font
134
    ws['B3'].alignment = b_r_alignment
135
    ws['B3'] = 'Name:'
136
    ws['C3'].border = b_border
137
    ws['C3'].alignment = b_c_alignment
138
    ws['C3'].font = name_font
139
    ws['C3'] = name
140
141
    ws['D3'].font = name_font
142
    ws['D3'].alignment = b_r_alignment
143
    ws['D3'] = 'Period:'
144
    ws['E3'].border = b_border
145
    ws['E3'].alignment = b_c_alignment
146
    ws['E3'].font = name_font
147
    ws['E3'] = period_type
148
149
    ws['F3'].font = name_font
150
    ws['F3'].alignment = b_r_alignment
151
    ws['F3'] = 'Date:'
152
    ws['G3'].border = b_border
153
    ws['G3'].alignment = b_c_alignment
154
    ws['G3'].font = name_font
155
    ws['G3'] = reporting_start_datetime_local + "__" + reporting_end_datetime_local
156
    ws.merge_cells("G3:H3")
157
158
    if "reporting_period" not in report.keys() or \
159
            "names" not in report['reporting_period'].keys() or len(report['reporting_period']['names']) == 0:
160
        filename = str(uuid.uuid4()) + '.xlsx'
161
        wb.save(filename)
162
163
        return filename
164
    #################################################
165
    # First: 统计分析
166
    # 6: title
167
    # 7: table title
168
    # 8~ca_len table_data
169
    #################################################
170
    reporting_period_data = report['reporting_period']
171
172
    has_energy_data_flag = True
173
174
    if "names" not in reporting_period_data.keys() or \
175
            reporting_period_data['names'] is None or \
176
            len(reporting_period_data['names']) == 0:
177
        has_energy_data_flag = False
178
179
        filename = str(uuid.uuid4()) + '.xlsx'
180
        wb.save(filename)
181
182
        return filename
183
184
    if has_energy_data_flag:
185
        ws['B6'].font = title_font
186
        ws['B6'] = name + ' 统计分析'
187
188
        category = reporting_period_data['names']
189
190
        # table_title
191
        ws['B7'].fill = table_fill
192
        ws['B7'].font = title_font
193
        ws['B7'].alignment = c_c_alignment
194
        ws['B7'] = '报告期'
195
        ws['B7'].border = f_border
196
197
        ws['C7'].font = title_font
198
        ws['C7'].alignment = c_c_alignment
199
        ws['C7'] = '算术平均数'
200
        ws['C7'].border = f_border
201
202
        ws['D7'].font = title_font
203
        ws['D7'].alignment = c_c_alignment
204
        ws['D7'] = '中位数'
205
        ws['D7'].border = f_border
206
207
        ws['E7'].font = title_font
208
        ws['E7'].alignment = c_c_alignment
209
        ws['E7'] = '最小值'
210
        ws['E7'].border = f_border
211
212
        ws['F7'].font = title_font
213
        ws['F7'].alignment = c_c_alignment
214
        ws['F7'] = '最大值'
215
        ws['F7'].border = f_border
216
217
        ws['G7'].font = title_font
218
        ws['G7'].alignment = c_c_alignment
219
        ws['G7'] = '样本标准差'
220
        ws['G7'].border = f_border
221
222
        ws['H7'].font = title_font
223
        ws['H7'].alignment = c_c_alignment
224
        ws['H7'] = '样本方差'
225
        ws['H7'].border = f_border
226
227
        # table_data
228
229
        for i, value in enumerate(category):
230
            row = i * 2 + 8
231
            ws['B' + str(row)].font = name_font
232
            ws['B' + str(row)].alignment = c_c_alignment
233
            ws['B' + str(row)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + " )"
234
            ws['B' + str(row)].border = f_border
235
236
            ws['B' + str(row + 1)].font = name_font
237
            ws['B' + str(row + 1)].alignment = c_c_alignment
238
            ws['B' + str(row + 1)] = "环比"
239
            ws['B' + str(row + 1)].border = f_border
240
241
            ws['C' + str(row)].font = name_font
242
            ws['C' + str(row)].alignment = c_c_alignment
243
            ws['C' + str(row)] = round(reporting_period_data['means'][i], 2) \
244
                if reporting_period_data['means'][i] is not None else ''
245
            ws['C' + str(row)].border = f_border
246
            ws['C' + str(row)].number_format = '0.00'
247
248
            ws['C' + str(row + 1)].font = name_font
249
            ws['C' + str(row + 1)].alignment = c_c_alignment
250
            ws['C' + str(row + 1)] = str(round(reporting_period_data['means_increment_rate'][i] * 100, 2)) + "%" \
251
                if reporting_period_data['means_increment_rate'][i] is not None else '0.00%'
252
            ws['C' + str(row + 1)].border = f_border
253
254
            ws['D' + str(row)].font = name_font
255
            ws['D' + str(row)].alignment = c_c_alignment
256
            ws['D' + str(row)] = round(reporting_period_data['medians'][i], 2) \
257
                if reporting_period_data['medians'][i] is not None else ''
258
            ws['D' + str(row)].border = f_border
259
            ws['D' + str(row)].number_format = '0.00'
260
261
            ws['D' + str(row + 1)].font = name_font
262
            ws['D' + str(row + 1)].alignment = c_c_alignment
263
            ws['D' + str(row + 1)] = str(round(reporting_period_data['medians_increment_rate'][i] * 100, 2)) + "%" \
264
                if reporting_period_data['medians_increment_rate'][i] is not None else '0.00%'
265
            ws['D' + str(row + 1)].border = f_border
266
267
            ws['E' + str(row)].font = name_font
268
            ws['E' + str(row)].alignment = c_c_alignment
269
            ws['E' + str(row)] = round(reporting_period_data['minimums'][i], 2) \
270
                if reporting_period_data['minimums'][i] is not None else ''
271
            ws['E' + str(row)].border = f_border
272
            ws['E' + str(row)].number_format = '0.00'
273
274
            ws['E' + str(row + 1)].font = name_font
275
            ws['E' + str(row + 1)].alignment = c_c_alignment
276
            ws['E' + str(row + 1)] = str(round(reporting_period_data['minimums_increment_rate'][i] * 100, 2)) + "%" \
277
                if reporting_period_data['minimums_increment_rate'][i] is not None else '0.00%'
278
            ws['E' + str(row + 1)].border = f_border
279
280
            ws['F' + str(row)].font = name_font
281
            ws['F' + str(row)].alignment = c_c_alignment
282
            ws['F' + str(row)] = round(reporting_period_data['maximums'][i], 2) \
283
                if reporting_period_data['maximums'][i] is not None else ''
284
            ws['F' + str(row)].border = f_border
285
            ws['F' + str(row)].number_format = '0.00'
286
287
            ws['F' + str(row + 1)].font = name_font
288
            ws['F' + str(row + 1)].alignment = c_c_alignment
289
            ws['F' + str(row + 1)] = str(round(reporting_period_data['maximums_increment_rate'][i] * 100, 2)) + "%" \
290
                if reporting_period_data['maximums_increment_rate'][i] is not None else '0.00%'
291
            ws['F' + str(row + 1)].border = f_border
292
293
            ws['G' + str(row)].font = name_font
294
            ws['G' + str(row)].alignment = c_c_alignment
295
            ws['G' + str(row)] = round(reporting_period_data['stdevs'][i], 2) \
296
                if reporting_period_data['stdevs'][i] is not None else ''
297
            ws['G' + str(row)].border = f_border
298
            ws['G' + str(row)].number_format = '0.00'
299
300
            ws['G' + str(row + 1)].font = name_font
301
            ws['G' + str(row + 1)].alignment = c_c_alignment
302
            ws['G' + str(row + 1)] = str(round(reporting_period_data['stdevs_increment_rate'][i] * 100, 2)) + "%" \
303
                if reporting_period_data['stdevs_increment_rate'][i] is not None else '0.00%'
304
            ws['G' + str(row + 1)].border = f_border
305
306
            ws['H' + str(row)].font = name_font
307
            ws['H' + str(row)].alignment = c_c_alignment
308
            ws['H' + str(row)] = round(reporting_period_data['variances'][i], 2) \
309
                if reporting_period_data['variances'][i] is not None else ''
310
            ws['H' + str(row)].border = f_border
311
            ws['H' + str(row)].number_format = '0.00'
312
313
            ws['H' + str(row + 1)].font = name_font
314
            ws['H' + str(row + 1)].alignment = c_c_alignment
315
            ws['H' + str(row + 1)] = str(round(reporting_period_data['variances_increment_rate'][i] * 100, 2)) + "%" \
316
                if reporting_period_data['variances_increment_rate'][i] is not None else '0.00%'
317
            ws['H' + str(row + 1)].border = f_border
318
    #################################################
319
    # Second: 报告期消耗
320
    # 9 + ca_len * 2: title
321
    # 10 + ca_len * 2: table title
322
    # row_title + 2 ~ row_title + 2 + ca_len :  table_data
323
    #################################################
324
325
    if has_energy_data_flag:
326
        names = reporting_period_data['names']
327
        ca_len = len(names)
328
329
        row_title = 9 + ca_len * 2
330
331
        ws['B' + str(row_title)].font = title_font
332
        ws['B' + str(row_title)] = name + ' 单位面积值'
333
        ws['D' + str(row_title)].font = title_font
334
        ws['D' + str(row_title)] = str(report['store']['area']) + 'M²'
335
336
        category = reporting_period_data['names']
337
338
        # table_title
339
        ws['B' + str(row_title + 1)].fill = table_fill
340
        ws['B' + str(row_title + 1)].font = title_font
341
        ws['B' + str(row_title + 1)].alignment = c_c_alignment
342
        ws['B' + str(row_title + 1)] = '报告期'
343
        ws['B' + str(row_title + 1)].border = f_border
344
345
        ws['C' + str(row_title + 1)].font = title_font
346
        ws['C' + str(row_title + 1)].alignment = c_c_alignment
347
        ws['C' + str(row_title + 1)] = '算术平均数'
348
        ws['C' + str(row_title + 1)].border = f_border
349
350
        ws['D' + str(row_title + 1)].font = title_font
351
        ws['D' + str(row_title + 1)].alignment = c_c_alignment
352
        ws['D' + str(row_title + 1)] = '中位数'
353
        ws['D' + str(row_title + 1)].border = f_border
354
355
        ws['E' + str(row_title + 1)].font = title_font
356
        ws['E' + str(row_title + 1)].alignment = c_c_alignment
357
        ws['E' + str(row_title + 1)] = '最小值'
358
        ws['E' + str(row_title + 1)].border = f_border
359
360
        ws['F' + str(row_title + 1)].font = title_font
361
        ws['F' + str(row_title + 1)].alignment = c_c_alignment
362
        ws['F' + str(row_title + 1)] = '最大值'
363
        ws['F' + str(row_title + 1)].border = f_border
364
365
        ws['G' + str(row_title + 1)].font = title_font
366
        ws['G' + str(row_title + 1)].alignment = c_c_alignment
367
        ws['G' + str(row_title + 1)] = '样本标准差'
368
        ws['G' + str(row_title + 1)].border = f_border
369
370
        ws['H' + str(row_title + 1)].font = title_font
371
        ws['H' + str(row_title + 1)].alignment = c_c_alignment
372
        ws['H' + str(row_title + 1)] = '样本方差'
373
        ws['H' + str(row_title + 1)].border = f_border
374
375
        # table_data
376
377
        for i, value in enumerate(category):
378
            row_data = row_title + 2 + i
379
            ws['B' + str(row_data)].font = name_font
380
            ws['B' + str(row_data)].alignment = c_c_alignment
381
            ws['B' + str(row_data)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][
382
                i] + "/M²)"
383
            ws['B' + str(row_data)].border = f_border
384
385
            ws['C' + str(row_data)].font = name_font
386
            ws['C' + str(row_data)].alignment = c_c_alignment
387
            if reporting_period_data['means_per_unit_area'][i] \
388
                    or reporting_period_data['means_per_unit_area'][i] == 0:
389
                ws['C' + str(row_data)] = round(reporting_period_data['means_per_unit_area'][i], 2)
390
            ws['C' + str(row_data)].border = f_border
391
            ws['C' + str(row_data)].number_format = '0.00'
392
393
            ws['D' + str(row_data)].font = name_font
394
            ws['D' + str(row_data)].alignment = c_c_alignment
395
            if reporting_period_data['medians_per_unit_area'][i] \
396
                    or reporting_period_data['medians_per_unit_area'][i] == 0:
397
                ws['D' + str(row_data)] = round(reporting_period_data['medians_per_unit_area'][i], 2)
398
            ws['D' + str(row_data)].border = f_border
399
            ws['D' + str(row_data)].number_format = '0.00'
400
401
            ws['E' + str(row_data)].font = name_font
402
            ws['E' + str(row_data)].alignment = c_c_alignment
403
            if reporting_period_data['minimums_per_unit_area'][i] \
404
                    or reporting_period_data['minimums_per_unit_area'][i] == 0:
405
                ws['E' + str(row_data)] = round(reporting_period_data['minimums_per_unit_area'][i], 2)
406
            ws['E' + str(row_data)].border = f_border
407
            ws['E' + str(row_data)].number_format = '0.00'
408
409
            ws['F' + str(row_data)].font = name_font
410
            ws['F' + str(row_data)].alignment = c_c_alignment
411
            if reporting_period_data['maximums_per_unit_area'][i] \
412
                    or reporting_period_data['maximums_per_unit_area'][i] == 0:
413
                ws['F' + str(row_data)] = round(reporting_period_data['maximums_per_unit_area'][i], 2)
414
            ws['F' + str(row_data)].border = f_border
415
            ws['F' + str(row_data)].number_format = '0.00'
416
417
            ws['G' + str(row_data)].font = name_font
418
            ws['G' + str(row_data)].alignment = c_c_alignment
419
            if (reporting_period_data['stdevs_per_unit_area'][i]) \
420
                    or reporting_period_data['stdevs_per_unit_area'][i] == 0:
421
                ws['G' + str(row_data)] = round(reporting_period_data['stdevs_per_unit_area'][i], 2)
422
            ws['G' + str(row_data)].border = f_border
423
            ws['G' + str(row_data)].number_format = '0.00'
424
425
            ws['H' + str(row_data)].font = name_font
426
            ws['H' + str(row_data)].alignment = c_c_alignment
427
            if reporting_period_data['variances_per_unit_area'][i] \
428
                    or reporting_period_data['variances_per_unit_area'][i] == 0:
429
                ws['H' + str(row_data)] = round(reporting_period_data['variances_per_unit_area'][i], 2)
430
            ws['H' + str(row_data)].border = f_border
431
            ws['H' + str(row_data)].number_format = '0.00'
432
433
    ########################################################
434
    # Third: 详细数据
435
    # row_sat+row_title~ row_sat+row_title+time_len: line
436
    # row_sat+1+row_title: table title
437
    # i + row_sat + 2 + 10 * ca_len~: table_data
438
    ########################################################
439
    has_timestamps_flag = True
440
    if "timestamps" not in reporting_period_data.keys() or \
441
            reporting_period_data['timestamps'] is None or \
442
            len(reporting_period_data['timestamps']) == 0:
443
        has_timestamps_flag = False
444
445
    if has_timestamps_flag:
446
        timestamps = reporting_period_data['timestamps'][0]
447
        values = reporting_period_data['values']
448
        names = reporting_period_data['names']
449
        ca_len = len(names)
450
        time_len = len(timestamps)
451
        # title
452
        row_title = 10 * ca_len
453
        # row_st == row_statistical analysis table
454
        row_sat = 12 + 3 * ca_len
455
456
        ws['B' + str(row_sat + row_title)].font = title_font
457
        ws['B' + str(row_sat + row_title)] = name + ' 详细数据'
458
        # table_title
459
        ws['B' + str(row_sat + 1 + row_title)].fill = table_fill
460
        ws['B' + str(row_sat + 1 + row_title)].font = name_font
461
        ws['B' + str(row_sat + 1 + row_title)].alignment = c_c_alignment
462
        ws['B' + str(row_sat + 1 + row_title)] = "时间"
463
        ws['B' + str(row_sat + 1 + row_title)].border = f_border
464
465
        for i in range(0, ca_len):
466
            col = chr(ord('C') + i)
467
468
            ws[col + str(row_sat + 1 + row_title)].font = name_font
469
            ws[col + str(row_sat + 1 + row_title)].alignment = c_c_alignment
470
            ws[col + str(row_sat + 1 + row_title)] = names[i] + " - (" + reporting_period_data['units'][i] + ")"
471
            ws[col + str(row_sat + 1 + row_title)].border = f_border
472
        # table_date
473
        for i in range(0, time_len):
474
            rows = i + row_sat + 2 + 10 * ca_len
475
476
            ws['B' + str(rows)].font = name_font
477
            ws['B' + str(rows)].alignment = c_c_alignment
478
            ws['B' + str(rows)] = timestamps[i]
479
            ws['B' + str(rows)].border = f_border
480
481
            for index in range(0, ca_len):
482
                col = chr(ord('C') + index)
483
484
                ws[col + str(rows)].font = name_font
485
                ws[col + str(rows)].alignment = c_c_alignment
486
                ws[col + str(rows)] = round(values[index][i], 2)
487
                ws[col + str(rows)].number_format = '0.00'
488
                ws[col + str(rows)].border = f_border
489
490
        # 小计
491
        row_subtotals = row_sat + 2 + time_len + 10 * ca_len
492
        ws['B' + str(row_subtotals)].font = name_font
493
        ws['B' + str(row_subtotals)].alignment = c_c_alignment
494
        ws['B' + str(row_subtotals)] = "小计"
495
        ws['B' + str(row_subtotals)].border = f_border
496
497
        for i in range(0, ca_len):
498
            col = chr(ord('C') + i)
499
500
            ws[col + str(row_subtotals)].font = name_font
501
            ws[col + str(row_subtotals)].alignment = c_c_alignment
502
            ws[col + str(row_subtotals)] = round(reporting_period_data['subtotals'][i], 2)
503
            ws[col + str(row_subtotals)].border = f_border
504
            ws[col + str(row_subtotals)].number_format = '0.00'
505
506
        # LineChart
507
        for i in range(0, ca_len):
508
            lc = LineChart()
509
            lc.title = "报告期消耗" + " - " + names[i] + "(" + reporting_period_data['units'][i] + ")"
510
            lc.style = 10
511
            lc.height = 8.40  # cm 1.05*8 1.05cm = 30 pt
512
            lc.width = 31
513
            lc.x_axis.majorTickMark = 'in'
514
            lc.y_axis.majorTickMark = 'in'
515
            times = Reference(ws, min_col=2, min_row=row_sat + 2 + row_title,
516
                              max_row=row_sat + 2 + row_title + time_len)
517
            lc_data = Reference(ws, min_col=3 + i, min_row=row_sat + 1 + row_title,
518
                                max_row=row_sat + 1 + row_title + time_len)
519
            lc.add_data(lc_data, titles_from_data=True)
520
            lc.set_categories(times)
521
            ser = lc.series[0]
522
            ser.marker.symbol = "diamond"
523
            ser.marker.size = 5
524
            ws.add_chart(lc, 'B' + str(row_sat + 10 * i))
525
526
    filename = str(uuid.uuid4()) + '.xlsx'
527
    wb.save(filename)
528
529
    return filename
530