added associated parameters data to excel exporter of meterenergy in API

pull/31/MERGE
13621160019@163.com 2021-04-12 17:35:10 +08:00
parent 98dcc10990
commit e9224ec264
1 changed files with 262 additions and 17 deletions

View File

@ -10,6 +10,7 @@ from openpyxl.styles import PatternFill, Border, Side, Alignment, Protection, Fo
from openpyxl.drawing.image import Image from openpyxl.drawing.image import Image
from openpyxl import Workbook from openpyxl import Workbook
from openpyxl.chart.label import DataLabelList from openpyxl.chart.label import DataLabelList
import openpyxl.utils.cell as format_cell
#################################################################################################################### ####################################################################################################################
@ -55,6 +56,60 @@ def export(result, name, reporting_start_datetime_local, reporting_end_datetime_
return base64_message return base64_message
def timestamps_data_all_equal_0(lists):
for i, value in enumerate(list(lists)):
if len(value) > 0:
return False
return True
def get_parameters_timestamps_lists_max_len(parameters_timestamps_lists):
max_len = 0
for i, value in enumerate(list(parameters_timestamps_lists)):
if len(value) > max_len:
max_len = len(value)
return max_len
def timestamps_data_not_equal_0(lists):
number = 0
for i, value in enumerate(list(lists)):
if len(value) > 0:
number += 1
return number
def decimal_to_column(num=65):
string = ''
num = num - 64
# The column number is not greater than 90
if num <= 26:
return chr(num+64)
# The column number is greater than 90
while num // 26 > 0:
if num % 26 == 0:
string += 'Z'
num = num // 26 - 1
else:
string += chr(num % 26 + 64)
num //= 26
# Avoid conversion errors that might occur between 741 and 766
if num > 0:
string += chr(num + 64)
return string[::-1]
def column_to_decimal(string='A'):
num = 0
for index, key in enumerate(string[::-1]):
num += (ord(key) - 64) * (26 ** index)
return num + 64
def generate_excel(report, name, reporting_start_datetime_local, reporting_end_datetime_local, period_type): def generate_excel(report, name, reporting_start_datetime_local, reporting_end_datetime_local, period_type):
wb = Workbook() wb = Workbook()
@ -278,28 +333,30 @@ def generate_excel(report, name, reporting_start_datetime_local, reporting_end_d
reporting_period_data = report['reporting_period'] reporting_period_data = report['reporting_period']
category = report['meter']['energy_category_name'] category = report['meter']['energy_category_name']
ca_len = len(category) ca_len = len(category)
parameters_names_len = len(report['parameters']['names'])
start_detail_data_row_num = 7 + (parameters_names_len + ca_len) * 6
ws['B11'].font = title_font ws['B11'].font = title_font
ws['B11'] = name + '详细数据' ws['B11'] = name + '详细数据'
ws.row_dimensions[18].height = 60 ws.row_dimensions[start_detail_data_row_num].height = 60
ws['B18'].fill = table_fill ws['B' + str(start_detail_data_row_num)].fill = table_fill
ws['B18'].font = title_font ws['B' + str(start_detail_data_row_num)].font = title_font
ws['B18'].border = f_border ws['B' + str(start_detail_data_row_num)].border = f_border
ws['B18'].alignment = c_c_alignment ws['B' + str(start_detail_data_row_num)].alignment = c_c_alignment
ws['B18'] = '日期时间' ws['B' + str(start_detail_data_row_num)] = '日期时间'
time = times time = times
has_data = False has_data = False
max_row = 0 max_row = 0
if len(time) > 0: if len(time) > 0:
has_data = True has_data = True
max_row = 18 + len(time) max_row = start_detail_data_row_num + len(time)
if has_data: if has_data:
for i in range(0, len(time)): for i in range(0, len(time)):
col = 'B' col = 'B'
row = str(19 + i) row = str(start_detail_data_row_num + 1 + i)
# col = chr(ord('B') + i) # col = chr(ord('B') + i)
ws[col + row].font = title_font ws[col + row].font = title_font
ws[col + row].alignment = c_c_alignment ws[col + row].alignment = c_c_alignment
@ -310,19 +367,19 @@ def generate_excel(report, name, reporting_start_datetime_local, reporting_end_d
# 12 title # 12 title
col = chr(ord('C') + i) col = chr(ord('C') + i)
ws[col + '18'].fill = table_fill ws[col + str(start_detail_data_row_num)].fill = table_fill
ws[col + '18'].font = title_font ws[col + str(start_detail_data_row_num)].font = title_font
ws[col + '18'].alignment = c_c_alignment ws[col + str(start_detail_data_row_num)].alignment = c_c_alignment
ws[col + '18'] = report['meter']['energy_category_name'] + \ ws[col + str(start_detail_data_row_num)] = report['meter']['energy_category_name'] + \
" (" + report['meter']['unit_of_measure'] + ")" " (" + report['meter']['unit_of_measure'] + ")"
ws[col + '18'].border = f_border ws[col + str(start_detail_data_row_num)].border = f_border
# 13 data # 13 data
time = times time = times
time_len = len(time) time_len = len(time)
for j in range(0, time_len): for j in range(0, time_len):
row = str(19 + j) row = str(start_detail_data_row_num + 1 + j)
# col = chr(ord('B') + i) # col = chr(ord('B') + i)
ws[col + row].font = title_font ws[col + row].font = title_font
ws[col + row].alignment = c_c_alignment ws[col + row].alignment = c_c_alignment
@ -333,8 +390,8 @@ def generate_excel(report, name, reporting_start_datetime_local, reporting_end_d
line = LineChart() line = LineChart()
line.title = '报告期消耗 - ' + report['meter']['energy_category_name'] + \ line.title = '报告期消耗 - ' + report['meter']['energy_category_name'] + \
" (" + report['meter']['unit_of_measure'] + ")" " (" + report['meter']['unit_of_measure'] + ")"
labels = Reference(ws, min_col=2, min_row=19, max_row=max_row) labels = Reference(ws, min_col=2, min_row=start_detail_data_row_num + 1, max_row=max_row)
bar_data = Reference(ws, min_col=3, min_row=18, max_row=max_row) bar_data = Reference(ws, min_col=3, min_row=start_detail_data_row_num, max_row=max_row)
line.add_data(bar_data, titles_from_data=True) line.add_data(bar_data, titles_from_data=True)
line.set_categories(labels) line.set_categories(labels)
line_data = line.series[0] line_data = line.series[0]
@ -355,7 +412,7 @@ def generate_excel(report, name, reporting_start_datetime_local, reporting_end_d
ws.add_chart(line, "B12") ws.add_chart(line, "B12")
col = 'B' col = 'B'
row = str(19 + len(time)) row = str(start_detail_data_row_num + 1 + len(time))
ws[col + row].font = title_font ws[col + row].font = title_font
ws[col + row].alignment = c_c_alignment ws[col + row].alignment = c_c_alignment
@ -372,6 +429,194 @@ def generate_excel(report, name, reporting_start_datetime_local, reporting_end_d
else: else:
for i in range(11, 43 + 1): for i in range(11, 43 + 1):
ws.row_dimensions[i].height = 0.0 ws.row_dimensions[i].height = 0.0
##########################################
has_parameters_names_and_timestamps_and_values_data = True
# 12 is the starting line number of the last line chart in the report period
category = report['meter']['energy_category_name']
time_len = len(reporting_period_data['timestamps'])
ca_len = len(category)
current_sheet_parameters_row_number = 12 + ca_len * 6
if 'parameters' not in report.keys() or \
report['parameters'] is None or \
'names' not in report['parameters'].keys() or \
report['parameters']['names'] is None or \
len(report['parameters']['names']) == 0 or \
'timestamps' not in report['parameters'].keys() or \
report['parameters']['timestamps'] is None or \
len(report['parameters']['timestamps']) == 0 or \
'values' not in report['parameters'].keys() or \
report['parameters']['values'] is None or \
len(report['parameters']['values']) == 0 or \
timestamps_data_all_equal_0(report['parameters']['timestamps']):
has_parameters_names_and_timestamps_and_values_data = False
if has_parameters_names_and_timestamps_and_values_data:
###############################
# new worksheet
###############################
parameters_data = report['parameters']
parameters_names_len = len(parameters_data['names'])
parameters_ws = wb.create_sheet('相关参数')
parameters_timestamps_data_max_len = \
get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps']))
# Row height
parameters_ws.row_dimensions[1].height = 102
for i in range(2, 7 + 1):
parameters_ws.row_dimensions[i].height = 42
for i in range(8, parameters_timestamps_data_max_len + 10):
parameters_ws.row_dimensions[i].height = 60
# Col width
parameters_ws.column_dimensions['A'].width = 1.5
parameters_ws.column_dimensions['B'].width = 25.0
for i in range(3, 12 + parameters_names_len * 3):
parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0
# Img
img = Image("excelexporters/myems.png")
img.width = img.width * 0.85
img.height = img.height * 0.85
# img = Image("myems.png")
parameters_ws.add_image(img, 'B1')
# Title
parameters_ws.row_dimensions[3].height = 60
parameters_ws['B3'].font = name_font
parameters_ws['B3'].alignment = b_r_alignment
parameters_ws['B3'] = 'Name:'
parameters_ws['C3'].border = b_border
parameters_ws['C3'].alignment = b_c_alignment
parameters_ws['C3'].font = name_font
parameters_ws['C3'] = name
parameters_ws['D3'].font = name_font
parameters_ws['D3'].alignment = b_r_alignment
parameters_ws['D3'] = 'Period:'
parameters_ws['E3'].border = b_border
parameters_ws['E3'].alignment = b_c_alignment
parameters_ws['E3'].font = name_font
parameters_ws['E3'] = period_type
parameters_ws['F3'].font = name_font
parameters_ws['F3'].alignment = b_r_alignment
parameters_ws['F3'] = 'Date:'
parameters_ws['G3'].border = b_border
parameters_ws['G3'].alignment = b_c_alignment
parameters_ws['G3'].font = name_font
parameters_ws['G3'] = reporting_start_datetime_local + "__" + reporting_end_datetime_local
parameters_ws.merge_cells("G3:H3")
parameters_ws_current_row_number = 6
parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font
parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' 相关参数'
parameters_ws_current_row_number += 1
parameters_table_start_row_number = parameters_ws_current_row_number
parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80
parameters_ws_current_row_number += 1
table_current_col_number = 'B'
for i in range(0, parameters_names_len):
if len(parameters_data['timestamps'][i]) == 0:
continue
parameters_ws[table_current_col_number + str(parameters_ws_current_row_number - 1)].fill = table_fill
parameters_ws[table_current_col_number + str(parameters_ws_current_row_number - 1)].border = f_border
col = decimal_to_column(column_to_decimal(table_current_col_number) + 1)
parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
parameters_ws[col + str(parameters_ws_current_row_number - 1)].font = name_font
parameters_ws[col + str(parameters_ws_current_row_number - 1)].alignment = c_c_alignment
parameters_ws[col + str(parameters_ws_current_row_number - 1)] = parameters_data['names'][i]
table_current_row_number = parameters_ws_current_row_number
for j, value in enumerate(list(parameters_data['timestamps'][i])):
col = table_current_col_number
parameters_ws[col + str(table_current_row_number)].border = f_border
parameters_ws[col + str(table_current_row_number)].font = title_font
parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
parameters_ws[col + str(table_current_row_number)] = value
col = decimal_to_column(column_to_decimal(col) + 1)
parameters_ws[col + str(table_current_row_number)].border = f_border
parameters_ws[col + str(table_current_row_number)].font = title_font
parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
parameters_ws[col + str(table_current_row_number)] = round(parameters_data['values'][i][j], 2)
table_current_row_number += 1
table_current_col_number = decimal_to_column(column_to_decimal(table_current_col_number) + 3)
########################################################
# parameters chart and parameters table
########################################################
ws['B' + str(current_sheet_parameters_row_number)].font = title_font
ws['B' + str(current_sheet_parameters_row_number)] = name + ' 相关参数'
current_sheet_parameters_row_number += 1
chart_start_row_number = current_sheet_parameters_row_number
col_index = 0
for i in range(0, parameters_names_len):
if len(parameters_data['timestamps'][i]) == 0:
continue
line = LineChart()
data_col = 3 + col_index * 3
labels_col = 2 + col_index * 3
col_index += 1
line.title = '相关参数 - ' + \
parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value
labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1,
max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number,
max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
line.add_data(line_data, titles_from_data=True)
line.set_categories(labels)
line_data = line.series[0]
line_data.marker.symbol = "circle"
line_data.smooth = True
line.x_axis.crosses = 'min'
line.height = 8.25
line.width = 24
line.dLbls = DataLabelList()
line.dLbls.dLblPos = 't'
line.dLbls.showVal = False
line.dLbls.showPercent = False
chart_col = 'B'
chart_cell = chart_col + str(chart_start_row_number)
chart_start_row_number += 6
ws.add_chart(line, chart_cell)
current_sheet_parameters_row_number = chart_start_row_number
current_sheet_parameters_row_number += 1
filename = str(uuid.uuid4()) + '.xlsx' filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename) wb.save(filename)