added excel exporter of combinedequipmentstatistics report

pull/16/head^2
13621160019@163.com 2021-03-11 15:26:18 +08:00
parent fd41af641b
commit f3b62c91a7
7 changed files with 756 additions and 348 deletions

View File

@ -113,12 +113,6 @@ def generate_excel(report,
wrap_text=False, wrap_text=False,
shrink_to_fit=False, shrink_to_fit=False,
indent=0) indent=0)
# c_r_alignment = Alignment(vertical='bottom',
# horizontal='center',
# text_rotation=0,
# wrap_text=False,
# shrink_to_fit=False,
# indent=0)
# Img # Img
img = Image("excelexporters/myems.png") img = Image("excelexporters/myems.png")
@ -262,9 +256,9 @@ def generate_excel(report,
######################################################## ########################################################
# Third: 详细数据 # Third: 详细数据
# row_sat~ row_sat + 6*cal_len: line # analysis_end_row_number~ analysis_end_row_number + 6*cal_len: line
# row_da: table title # detailed_start_row_number: table title
# row_da + 1~: table_data # detailed_start_row_number + 1~: table_data
######################################################## ########################################################
has_timestamps_flag = True has_timestamps_flag = True
if "timestamps" not in reporting_period_data.keys() or \ if "timestamps" not in reporting_period_data.keys() or \
@ -277,40 +271,37 @@ def generate_excel(report,
names = reporting_period_data['names'] names = reporting_period_data['names']
ca_len = len(names) ca_len = len(names)
time_len = len(timestamps) time_len = len(timestamps)
# row_lines == the number of rows of lines line_charts_row_number = 6 * ca_len
row_lines = 6 * ca_len analysis_end_row_number = 9 + 2 * ca_len
# row_sat == the number of rows of statistical analysis table detailed_start_row_number = analysis_end_row_number + line_charts_row_number + 1
row_sat = 9 + 2 * ca_len
# row_da == the number of rows of Detailed data
row_da = row_sat + row_lines + 1
ws['B' + str(row_da)].font = title_font ws['B' + str(detailed_start_row_number)].font = title_font
ws['B' + str(row_da)] = name + ' 详细数据' ws['B' + str(detailed_start_row_number)] = name + ' 详细数据'
# table_title # table_title
ws['B' + str(row_da + 1)].fill = table_fill ws['B' + str(detailed_start_row_number + 1)].fill = table_fill
ws['B' + str(row_da + 1)].font = name_font ws['B' + str(detailed_start_row_number + 1)].font = name_font
ws['B' + str(row_da + 1)].alignment = c_c_alignment ws['B' + str(detailed_start_row_number + 1)].alignment = c_c_alignment
ws['B' + str(row_da + 1)] = "日期时间" ws['B' + str(detailed_start_row_number + 1)] = "日期时间"
ws['B' + str(row_da + 1)].border = f_border ws['B' + str(detailed_start_row_number + 1)].border = f_border
for i in range(0, ca_len): for i in range(0, ca_len):
col_average = chr(ord('C') + 2 * i) col_average = chr(ord('C') + 2 * i)
col_maximum = chr(ord('D') + 2 * i) col_maximum = chr(ord('D') + 2 * i)
ws[col_average + str(row_da + 1)].font = name_font ws[col_average + str(detailed_start_row_number + 1)].font = name_font
ws[col_average + str(row_da + 1)].alignment = c_c_alignment ws[col_average + str(detailed_start_row_number + 1)].alignment = c_c_alignment
ws[col_average + str(row_da + 1)] = names[i] + " 平均负荷(" + reporting_period_data['units'][ ws[col_average + str(detailed_start_row_number + 1)] = names[i] + " 平均负荷(" + reporting_period_data['units'][
i] + "/H)" i] + "/H)"
ws[col_average + str(row_da + 1)].border = f_border ws[col_average + str(detailed_start_row_number + 1)].border = f_border
ws[col_maximum + str(row_da + 1)].font = name_font ws[col_maximum + str(detailed_start_row_number + 1)].font = name_font
ws[col_maximum + str(row_da + 1)].alignment = c_c_alignment ws[col_maximum + str(detailed_start_row_number + 1)].alignment = c_c_alignment
ws[col_maximum + str(row_da + 1)] = names[i] + " 最大负荷(" + reporting_period_data['units'][ ws[col_maximum + str(detailed_start_row_number + 1)] = names[i] + " 最大负荷(" + reporting_period_data['units'][
i] + "/H)" i] + "/H)"
ws[col_maximum + str(row_da + 1)].border = f_border ws[col_maximum + str(detailed_start_row_number + 1)].border = f_border
# table_date # table_date
for i in range(0, time_len): for i in range(0, time_len):
rows = i + row_da + 2 rows = i + detailed_start_row_number + 2
ws['B' + str(rows)].font = name_font ws['B' + str(rows)].font = name_font
ws['B' + str(rows)].alignment = c_c_alignment ws['B' + str(rows)].alignment = c_c_alignment
@ -335,32 +326,36 @@ def generate_excel(report,
ws[col_maximum + str(rows)].number_format = '0.00' ws[col_maximum + str(rows)].number_format = '0.00'
ws[col_maximum + str(rows)].border = f_border ws[col_maximum + str(rows)].border = f_border
# LineChart ########################################################
# third: LineChart
# LineChart requires data from the detailed data table in the Excel file
# so print the detailed data table first and then print LineChart
########################################################
for i in range(0, ca_len): for i in range(0, ca_len):
lc = LineChart() line = LineChart()
lc.title = "报告期 最大负荷" line.title = "报告期 最大负荷 - " + names[i] + "(" + reporting_period_data['units'][i] + ")"
lc.style = 10 line.style = 10
lc.x_axis.majorTickMark = 'in' line.x_axis.majorTickMark = 'in'
lc.y_axis.majorTickMark = 'in' line.y_axis.majorTickMark = 'in'
lc.smooth = True line.smooth = True
lc.x_axis.crosses = 'min' line.x_axis.crosses = 'min'
lc.height = 8.25 line.height = 8.25
lc.width = 24 line.width = 24
lc.dLbls = DataLabelList() line.dLbls = DataLabelList()
lc.dLbls.dLblPos = 't' line.dLbls.dLblPos = 't'
lc.dLbls.showVal = True line.dLbls.showVal = True
times = Reference(ws, min_col=2, min_row=row_da + 2, times = Reference(ws, min_col=2, min_row=detailed_start_row_number + 2,
max_row=row_da + 2 + time_len) max_row=detailed_start_row_number + 2 + time_len)
lc_data = Reference(ws, min_col=2 + 2 * (i+1), min_row=row_da + 1, line_data = Reference(ws, min_col=2 + 2 * (i + 1), min_row=detailed_start_row_number + 1,
max_row=row_da + 1 + time_len) max_row=detailed_start_row_number + 1 + time_len)
lc.add_data(lc_data, titles_from_data=True) line.add_data(line_data, titles_from_data=True)
lc.set_categories(times) line.set_categories(times)
ser = lc.series[0] ser = line.series[0]
ser.marker.symbol = "diamond" ser.marker.symbol = "diamond"
ser.marker.size = 5 ser.marker.size = 5
chart_col = 'B' chart_col = 'B'
chart_cell = str(row_sat + 6 * i) chart_cell = str(analysis_end_row_number + 6 * i)
ws.add_chart(lc, chart_col + chart_cell) ws.add_chart(line, chart_col + chart_cell)
filename = str(uuid.uuid4()) + '.xlsx' filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename) wb.save(filename)

View File

@ -0,0 +1,414 @@
import base64
import uuid
import os
from openpyxl.chart import (
LineChart,
Reference,
)
from openpyxl.chart.label import DataLabelList
from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
from openpyxl.drawing.image import Image
from openpyxl import Workbook
####################################################################################################################
# PROCEDURES
# Step 1: Validate the report data
# Step 2: Generate excel file
# Step 3: Encode the excel file bytes to Base64
####################################################################################################################
def export(report,
name,
reporting_start_datetime_local,
reporting_end_datetime_local,
period_type):
####################################################################################################################
# Step 1: Validate the report data
####################################################################################################################
if report is None:
return None
print(report)
####################################################################################################################
# Step 2: Generate excel file from the report data
####################################################################################################################
filename = generate_excel(report,
name,
reporting_start_datetime_local,
reporting_end_datetime_local,
period_type)
####################################################################################################################
# Step 3: Encode the excel file to Base64
####################################################################################################################
try:
with open(filename, 'rb') as binary_file:
binary_file_data = binary_file.read()
except IOError as ex:
pass
# Base64 encode the bytes
base64_encoded_data = base64.b64encode(binary_file_data)
# get the Base64 encoded data using human-readable characters.
base64_message = base64_encoded_data.decode('utf-8')
# delete the file from server
try:
os.remove(filename)
except NotImplementedError as ex:
pass
return base64_message
def generate_excel(report,
name,
reporting_start_datetime_local,
reporting_end_datetime_local,
period_type):
wb = Workbook()
ws = wb.active
# Row height
ws.row_dimensions[1].height = 102
for i in range(2, 2000 + 1):
ws.row_dimensions[i].height = 42
# Col width
ws.column_dimensions['A'].width = 1.5
ws.column_dimensions['B'].width = 25.0
for i in range(ord('C'), ord('L')):
ws.column_dimensions[chr(i)].width = 15.0
# Font
name_font = Font(name='Constantia', size=15, bold=True)
title_font = Font(name='宋体', size=15, bold=True)
# data_font = Font(name='Franklin Gothic Book', size=11)
table_fill = PatternFill(fill_type='solid', fgColor='1F497D')
f_border = Border(left=Side(border_style='medium', color='00000000'),
right=Side(border_style='medium', color='00000000'),
bottom=Side(border_style='medium', color='00000000'),
top=Side(border_style='medium', color='00000000')
)
b_border = Border(
bottom=Side(border_style='medium', color='00000000'),
)
b_c_alignment = Alignment(vertical='bottom',
horizontal='center',
text_rotation=0,
wrap_text=False,
shrink_to_fit=False,
indent=0)
c_c_alignment = Alignment(vertical='center',
horizontal='center',
text_rotation=0,
wrap_text=False,
shrink_to_fit=False,
indent=0)
b_r_alignment = Alignment(vertical='bottom',
horizontal='right',
text_rotation=0,
wrap_text=False,
shrink_to_fit=False,
indent=0)
# Img
img = Image("excelexporters/myems.png")
# img = Image("myems.png")
img.width = img.width * 0.85
img.height = img.height * 0.85
ws.add_image(img, 'B1')
# Title
ws['B3'].font = name_font
ws['B3'].alignment = b_r_alignment
ws['B3'] = 'Name:'
ws['C3'].border = b_border
ws['C3'].alignment = b_c_alignment
ws['C3'].font = name_font
ws['C3'] = name
ws['D3'].font = name_font
ws['D3'].alignment = b_r_alignment
ws['D3'] = 'Period:'
ws['E3'].border = b_border
ws['E3'].alignment = b_c_alignment
ws['E3'].font = name_font
ws['E3'] = period_type
ws['F3'].font = name_font
ws['F3'].alignment = b_r_alignment
ws['F3'] = 'Date:'
ws['G3'].border = b_border
ws['G3'].alignment = b_c_alignment
ws['G3'].font = name_font
ws['G3'] = reporting_start_datetime_local + "__" + reporting_end_datetime_local
ws.merge_cells("G3:H3")
if "reporting_period" not in report.keys() or \
"names" not in report['reporting_period'].keys() or len(report['reporting_period']['names']) == 0:
filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename)
return filename
#################################################
# First: 统计分析
# 6: title
# 7: table title
# 8~ca_len table_data
#################################################
reporting_period_data = report['reporting_period']
has_energy_data_flag = True
if "names" not in reporting_period_data.keys() or \
reporting_period_data['names'] is None or \
len(reporting_period_data['names']) == 0:
has_energy_data_flag = False
filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename)
return filename
if has_energy_data_flag:
ws['B6'].font = title_font
ws['B6'] = name + ' 统计分析'
category = reporting_period_data['names']
# table_title
ws['B7'].fill = table_fill
ws['B7'].font = title_font
ws['B7'].alignment = c_c_alignment
ws['B7'] = '报告期'
ws['B7'].border = f_border
ws['C7'].font = title_font
ws['C7'].alignment = c_c_alignment
ws['C7'] = '算术平均数'
ws['C7'].border = f_border
ws['D7'].font = title_font
ws['D7'].alignment = c_c_alignment
ws['D7'] = '中位数'
ws['D7'].border = f_border
ws['E7'].font = title_font
ws['E7'].alignment = c_c_alignment
ws['E7'] = '最小值'
ws['E7'].border = f_border
ws['F7'].font = title_font
ws['F7'].alignment = c_c_alignment
ws['F7'] = '最大值'
ws['F7'].border = f_border
ws['G7'].font = title_font
ws['G7'].alignment = c_c_alignment
ws['G7'] = '样本标准差'
ws['G7'].border = f_border
ws['H7'].font = title_font
ws['H7'].alignment = c_c_alignment
ws['H7'] = '样本方差'
ws['H7'].border = f_border
# table_data
for i, value in enumerate(category):
row = i * 2 + 8
ws['B' + str(row)].font = name_font
ws['B' + str(row)].alignment = c_c_alignment
ws['B' + str(row)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + " )"
ws['B' + str(row)].border = f_border
ws['B' + str(row + 1)].font = name_font
ws['B' + str(row + 1)].alignment = c_c_alignment
ws['B' + str(row + 1)] = "环比"
ws['B' + str(row + 1)].border = f_border
ws['C' + str(row)].font = name_font
ws['C' + str(row)].alignment = c_c_alignment
ws['C' + str(row)] = reporting_period_data['means'][i] \
if reporting_period_data['means'][i] is not None else ''
ws['C' + str(row)].border = f_border
ws['C' + str(row)].number_format = '0.00'
ws['C' + str(row + 1)].font = name_font
ws['C' + str(row + 1)].alignment = c_c_alignment
ws['C' + str(row + 1)] = str(round(reporting_period_data['means_increment_rate'][i] * 100, 2)) + "%" \
if reporting_period_data['means_increment_rate'][i] is not None else '0.00%'
ws['C' + str(row + 1)].border = f_border
ws['D' + str(row)].font = name_font
ws['D' + str(row)].alignment = c_c_alignment
ws['D' + str(row)] = reporting_period_data['medians'][i] \
if reporting_period_data['medians'][i] is not None else ''
ws['D' + str(row)].border = f_border
ws['D' + str(row)].number_format = '0.00'
ws['D' + str(row + 1)].font = name_font
ws['D' + str(row + 1)].alignment = c_c_alignment
ws['D' + str(row + 1)] = str(round(reporting_period_data['medians_increment_rate'][i] * 100, 2)) + "%" \
if reporting_period_data['medians_increment_rate'][i] is not None else '0.00%'
ws['D' + str(row + 1)].border = f_border
ws['E' + str(row)].font = name_font
ws['E' + str(row)].alignment = c_c_alignment
ws['E' + str(row)] = reporting_period_data['minimums'][i] \
if reporting_period_data['minimums'][i] is not None else ''
ws['E' + str(row)].border = f_border
ws['E' + str(row)].number_format = '0.00'
ws['E' + str(row + 1)].font = name_font
ws['E' + str(row + 1)].alignment = c_c_alignment
ws['E' + str(row + 1)] = str(round(reporting_period_data['minimums_increment_rate'][i] * 100, 2)) + "%" \
if reporting_period_data['minimums_increment_rate'][i] is not None else '0.00%'
ws['E' + str(row + 1)].border = f_border
ws['F' + str(row)].font = name_font
ws['F' + str(row)].alignment = c_c_alignment
ws['F' + str(row)] = reporting_period_data['maximums'][i] \
if reporting_period_data['maximums'][i] is not None else ''
ws['F' + str(row)].border = f_border
ws['F' + str(row)].number_format = '0.00'
ws['F' + str(row + 1)].font = name_font
ws['F' + str(row + 1)].alignment = c_c_alignment
ws['F' + str(row + 1)] = str(round(reporting_period_data['maximums_increment_rate'][i] * 100, 2)) + "%" \
if reporting_period_data['maximums_increment_rate'][i] is not None else '0.00%'
ws['F' + str(row + 1)].border = f_border
ws['G' + str(row)].font = name_font
ws['G' + str(row)].alignment = c_c_alignment
ws['G' + str(row)] = reporting_period_data['stdevs'][i] \
if reporting_period_data['stdevs'][i] is not None else ''
ws['G' + str(row)].border = f_border
ws['G' + str(row)].number_format = '0.00'
ws['G' + str(row + 1)].font = name_font
ws['G' + str(row + 1)].alignment = c_c_alignment
ws['G' + str(row + 1)] = str(round(reporting_period_data['stdevs_increment_rate'][i] * 100, 2)) + "%" \
if reporting_period_data['stdevs_increment_rate'][i] is not None else '0.00%'
ws['G' + str(row + 1)].border = f_border
ws['H' + str(row)].font = name_font
ws['H' + str(row)].alignment = c_c_alignment
ws['H' + str(row)] = reporting_period_data['variances'][i] \
if reporting_period_data['variances'][i] is not None else ''
ws['H' + str(row)].border = f_border
ws['H' + str(row)].number_format = '0.00'
ws['H' + str(row + 1)].font = name_font
ws['H' + str(row + 1)].alignment = c_c_alignment
ws['H' + str(row + 1)] = str(round(reporting_period_data['variances_increment_rate'][i] * 100, 2)) + "%" \
if reporting_period_data['variances_increment_rate'][i] is not None else '0.00%'
ws['H' + str(row + 1)].border = f_border
########################################################
# Second: 详细数据
# analysis_end_row_number+1~ analysis_end_row_number+1+line_charts_row_number+: line
# detailed_start_row_number~ : the detailed data table
########################################################
has_timestamps_flag = True
if "timestamps" not in reporting_period_data.keys() or \
reporting_period_data['timestamps'] is None or \
len(reporting_period_data['timestamps']) == 0:
has_timestamps_flag = False
if has_timestamps_flag:
timestamps = reporting_period_data['timestamps'][0]
values = reporting_period_data['values']
names = reporting_period_data['names']
ca_len = len(names)
time_len = len(timestamps)
# the detailed title
line_charts_row_number = 6 * ca_len + 1
analysis_end_row_number = 9 + 2 * ca_len
detailed_start_row_number = analysis_end_row_number + line_charts_row_number
ws['B' + str(detailed_start_row_number)].font = title_font
ws['B' + str(detailed_start_row_number)] = name + ' 详细数据'
# the detailed table_title
ws['B' + str(detailed_start_row_number + 1)].fill = table_fill
ws['B' + str(detailed_start_row_number + 1)].font = name_font
ws['B' + str(detailed_start_row_number + 1)].alignment = c_c_alignment
ws['B' + str(detailed_start_row_number + 1)] = "时间"
ws['B' + str(detailed_start_row_number + 1)].border = f_border
for i in range(0, ca_len):
col = chr(ord('C') + i)
ws[col + str(detailed_start_row_number + 1)].font = name_font
ws[col + str(detailed_start_row_number + 1)].alignment = c_c_alignment
ws[col + str(detailed_start_row_number + 1)] = names[i] + " - (" + reporting_period_data['units'][i] + ")"
ws[col + str(detailed_start_row_number + 1)].border = f_border
# the detailed table_date
for i in range(0, time_len):
rows = i + detailed_start_row_number + 2
ws['B' + str(rows)].font = name_font
ws['B' + str(rows)].alignment = c_c_alignment
ws['B' + str(rows)] = timestamps[i]
ws['B' + str(rows)].border = f_border
for index in range(0, ca_len):
col = chr(ord('C') + index)
ws[col + str(rows)].font = name_font
ws[col + str(rows)].alignment = c_c_alignment
ws[col + str(rows)] = values[index][i]
ws[col + str(rows)].number_format = '0.00'
ws[col + str(rows)].border = f_border
# 小计
row_subtotals = detailed_start_row_number + 2 + time_len
ws['B' + str(row_subtotals)].font = name_font
ws['B' + str(row_subtotals)].alignment = c_c_alignment
ws['B' + str(row_subtotals)] = "小计"
ws['B' + str(row_subtotals)].border = f_border
for i in range(0, ca_len):
col = chr(ord('C') + i)
ws[col + str(row_subtotals)].font = name_font
ws[col + str(row_subtotals)].alignment = c_c_alignment
ws[col + str(row_subtotals)] = reporting_period_data['subtotals'][i]
ws[col + str(row_subtotals)].border = f_border
ws[col + str(row_subtotals)].number_format = '0.00'
########################################################
# third: LineChart
# LineChart requires data from the detailed data table in the Excel file
# so print the detailed data table first and then print LineChart
########################################################
for i in range(0, ca_len):
line = LineChart()
line.title = "报告期消耗" + " - " + names[i] + "(" + reporting_period_data['units'][i] + ")"
line.style = 10
line.height = 8.40 # cm 1.05*8 1.05cm = 30 pt
line.width = 24
line.x_axis.majorTickMark = 'in'
line.y_axis.majorTickMark = 'in'
line.dLbls = DataLabelList()
line.dLbls.dLblPos = 't'
line.dLbls.showVal = True
times = Reference(ws, min_col=2, min_row=detailed_start_row_number + 2,
max_row=detailed_start_row_number + 2 + time_len)
line_data = Reference(ws, min_col=3 + i, min_row=detailed_start_row_number + 1,
max_row=detailed_start_row_number + 1 + time_len)
line.add_data(line_data, titles_from_data=True)
line.set_categories(times)
ser = line.series[0]
ser.marker.symbol = "diamond"
ser.marker.size = 5
ws.add_chart(line, 'B' + str(analysis_end_row_number + 6 * i))
filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename)
return filename

View File

@ -5,6 +5,7 @@ from openpyxl.chart import (
LineChart, LineChart,
Reference, Reference,
) )
from openpyxl.chart.label import DataLabelList
from openpyxl.styles import PatternFill, Border, Side, Alignment, Font from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
from openpyxl.drawing.image import Image from openpyxl.drawing.image import Image
from openpyxl import Workbook from openpyxl import Workbook
@ -68,19 +69,16 @@ def generate_excel(report,
ws = wb.active ws = wb.active
# Row height # Row height
ws.row_dimensions[1].height = 121 ws.row_dimensions[1].height = 102
for i in range(2, 37 + 1): for i in range(2, 2000 + 1):
ws.row_dimensions[i].height = 30 ws.row_dimensions[i].height = 42
for i in range(38, 90 + 1):
ws.row_dimensions[i].height = 30
# Col width # Col width
ws.column_dimensions['A'].width = 1.5 ws.column_dimensions['A'].width = 1.5
ws.column_dimensions['B'].width = 20.0 ws.column_dimensions['B'].width = 25.0
for i in range(ord('C'), ord('I')): for i in range(ord('C'), ord('L')):
ws.column_dimensions[chr(i)].width = 15.0 ws.column_dimensions[chr(i)].width = 15.0
# Font # Font
@ -116,12 +114,6 @@ def generate_excel(report,
wrap_text=False, wrap_text=False,
shrink_to_fit=False, shrink_to_fit=False,
indent=0) indent=0)
# c_r_alignment = Alignment(vertical='bottom',
# horizontal='center',
# text_rotation=0,
# wrap_text=False,
# shrink_to_fit=False,
# indent=0)
# Img # Img
img = Image("excelexporters/myems.png") img = Image("excelexporters/myems.png")
@ -317,11 +309,8 @@ def generate_excel(report,
######################################################## ########################################################
# Second: 详细数据 # Second: 详细数据
# row_sat+1~ row_sat+1+row_lines+: line # a+1~ analysis_end_row_number+1+line_charts_row_number+: line
# row_ddt~ : the detailed data table # detailed_start_row_number~ : the detailed data table
# row_sat : the number of rows of the analysis table
# row_lines : the number of rows of all line charts
# row_ddt : The number of rows in which the detailed data table header resides
######################################################## ########################################################
has_timestamps_flag = True has_timestamps_flag = True
if "timestamps" not in reporting_period_data.keys() or \ if "timestamps" not in reporting_period_data.keys() or \
@ -336,29 +325,29 @@ def generate_excel(report,
ca_len = len(names) ca_len = len(names)
time_len = len(timestamps) time_len = len(timestamps)
# the detailed title # the detailed title
row_lines = 9 * ca_len line_charts_row_number = 6 * ca_len + 1
row_sat = 7 + 2 * ca_len analysis_end_row_number = 7 + 2 * ca_len
row_ddt = row_sat + row_lines + 2 detailed_start_row_number = analysis_end_row_number + line_charts_row_number + 2
ws['B' + str(row_ddt)].font = title_font ws['B' + str(detailed_start_row_number)].font = title_font
ws['B' + str(row_ddt)] = name + ' 详细数据' ws['B' + str(detailed_start_row_number)] = name + ' 详细数据'
# the detailed table_title # the detailed table_title
ws['B' + str(row_ddt+1)].fill = table_fill ws['B' + str(detailed_start_row_number + 1)].fill = table_fill
ws['B' + str(row_ddt+1)].font = name_font ws['B' + str(detailed_start_row_number + 1)].font = name_font
ws['B' + str(row_ddt+1)].alignment = c_c_alignment ws['B' + str(detailed_start_row_number + 1)].alignment = c_c_alignment
ws['B' + str(row_ddt+1)] = "时间" ws['B' + str(detailed_start_row_number + 1)] = "时间"
ws['B' + str(row_ddt+1)].border = f_border ws['B' + str(detailed_start_row_number + 1)].border = f_border
for i in range(0, ca_len): for i in range(0, ca_len):
col = chr(ord('C') + i) col = chr(ord('C') + i)
ws[col + str(row_ddt+1)].font = name_font ws[col + str(detailed_start_row_number + 1)].font = name_font
ws[col + str(row_ddt+1)].alignment = c_c_alignment ws[col + str(detailed_start_row_number + 1)].alignment = c_c_alignment
ws[col + str(row_ddt+1)] = names[i] + " - (" + reporting_period_data['units'][i] + ")" ws[col + str(detailed_start_row_number + 1)] = names[i] + " - (" + reporting_period_data['units'][i] + ")"
ws[col + str(row_ddt+1)].border = f_border ws[col + str(detailed_start_row_number + 1)].border = f_border
# the detailed table_date # the detailed table_date
for i in range(0, time_len): for i in range(0, time_len):
rows = i + row_ddt + 2 rows = i + detailed_start_row_number + 2
ws['B' + str(rows)].font = name_font ws['B' + str(rows)].font = name_font
ws['B' + str(rows)].alignment = c_c_alignment ws['B' + str(rows)].alignment = c_c_alignment
@ -375,7 +364,7 @@ def generate_excel(report,
ws[col + str(rows)].border = f_border ws[col + str(rows)].border = f_border
# 小计 # 小计
row_subtotals = row_ddt + 2 + time_len row_subtotals = detailed_start_row_number + 2 + time_len
ws['B' + str(row_subtotals)].font = name_font ws['B' + str(row_subtotals)].font = name_font
ws['B' + str(row_subtotals)].alignment = c_c_alignment ws['B' + str(row_subtotals)].alignment = c_c_alignment
ws['B' + str(row_subtotals)] = "小计" ws['B' + str(row_subtotals)] = "小计"
@ -390,26 +379,32 @@ def generate_excel(report,
ws[col + str(row_subtotals)].border = f_border ws[col + str(row_subtotals)].border = f_border
ws[col + str(row_subtotals)].number_format = '0.00' ws[col + str(row_subtotals)].number_format = '0.00'
# LineChart ########################################################
# third: LineChart
# LineChart requires data from the detailed data table in the Excel file
# so print the detailed data table first and then print LineChart
########################################################
for i in range(0, ca_len): for i in range(0, ca_len):
line = LineChart()
lc = LineChart() line.title = "报告期消耗" + " - " + names[i] + "(" + reporting_period_data['units'][i] + ")"
lc.title = "报告期消耗" + " - " + names[i] + "(" + reporting_period_data['units'][i] + ")" line.style = 10
lc.style = 10 line.height = 8.40 # cm 1.05*8 1.05cm = 30 pt
lc.height = 8.40 # cm 1.05*8 1.05cm = 30 pt line.width = 24
lc.width = 23.28 line.x_axis.majorTickMark = 'in'
lc.x_axis.majorTickMark = 'in' line.y_axis.majorTickMark = 'in'
lc.y_axis.majorTickMark = 'in' line.dLbls = DataLabelList()
times = Reference(ws, min_col=2, min_row=row_ddt + 2, line.dLbls.dLblPos = 't'
max_row=row_ddt + 2 + time_len) line.dLbls.showVal = True
lc_data = Reference(ws, min_col=3 + i, min_row=row_ddt + 1, times = Reference(ws, min_col=2, min_row=detailed_start_row_number + 2,
max_row=row_ddt + 1 + time_len) max_row=detailed_start_row_number + 2 + time_len)
lc.add_data(lc_data, titles_from_data=True) line_data = Reference(ws, min_col=3 + i, min_row=detailed_start_row_number + 1,
lc.set_categories(times) max_row=detailed_start_row_number + 1 + time_len)
ser = lc.series[0] line.add_data(line_data, titles_from_data=True)
line.set_categories(times)
ser = line.series[0]
ser.marker.symbol = "diamond" ser.marker.symbol = "diamond"
ser.marker.size = 5 ser.marker.size = 5
ws.add_chart(lc, 'B' + str(row_sat + 2 + 9 * i)) ws.add_chart(line, 'B' + str(analysis_end_row_number + 2 + 6 * i))
filename = str(uuid.uuid4()) + '.xlsx' filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename) wb.save(filename)

View File

@ -113,12 +113,6 @@ def generate_excel(report,
wrap_text=False, wrap_text=False,
shrink_to_fit=False, shrink_to_fit=False,
indent=0) indent=0)
# c_r_alignment = Alignment(vertical='bottom',
# horizontal='center',
# text_rotation=0,
# wrap_text=False,
# shrink_to_fit=False,
# indent=0)
# Img # Img
img = Image("excelexporters/myems.png") img = Image("excelexporters/myems.png")
@ -264,40 +258,40 @@ def generate_excel(report,
# Second: 报告期单位面积消耗 # Second: 报告期单位面积消耗
# 9 + ca_len * 2: title # 9 + ca_len * 2: title
# 10 + ca_len * 2: table title # 10 + ca_len * 2: table title
# row_title + 2 ~ row_title + 2 + ca_len : table_data # per_unit_area_start_row_number + 2 ~ per_unit_area_start_row_number + 2 + ca_len : table_data
################################################# #################################################
if has_energy_data_flag: if has_energy_data_flag:
names = reporting_period_data['names'] names = reporting_period_data['names']
ca_len = len(names) ca_len = len(names)
row_title = 9 + ca_len * 2 per_unit_area_start_row_number = 9 + ca_len * 2
ws['B' + str(row_title)].font = title_font ws['B' + str(per_unit_area_start_row_number)].font = title_font
ws['B' + str(row_title)] = name + ' 单位面积值' + str(report['shopfloor']['area']) + '' ws['B' + str(per_unit_area_start_row_number)] = name + ' 单位面积值' + str(report['shopfloor']['area']) + ''
category = reporting_period_data['names'] category = reporting_period_data['names']
# table_title # table_title
ws['B' + str(row_title + 1)].fill = table_fill ws['B' + str(per_unit_area_start_row_number + 1)].fill = table_fill
ws['B' + str(row_title + 1)].font = title_font ws['B' + str(per_unit_area_start_row_number + 1)].font = title_font
ws['B' + str(row_title + 1)].alignment = c_c_alignment ws['B' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
ws['B' + str(row_title + 1)] = '报告期' ws['B' + str(per_unit_area_start_row_number + 1)] = '报告期'
ws['B' + str(row_title + 1)].border = f_border ws['B' + str(per_unit_area_start_row_number + 1)].border = f_border
ws['C' + str(row_title + 1)].font = title_font ws['C' + str(per_unit_area_start_row_number + 1)].font = title_font
ws['C' + str(row_title + 1)].alignment = c_c_alignment ws['C' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
ws['C' + str(row_title + 1)] = '平均负荷' ws['C' + str(per_unit_area_start_row_number + 1)] = '平均负荷'
ws['C' + str(row_title + 1)].border = f_border ws['C' + str(per_unit_area_start_row_number + 1)].border = f_border
ws['D' + str(row_title + 1)].font = title_font ws['D' + str(per_unit_area_start_row_number + 1)].font = title_font
ws['D' + str(row_title + 1)].alignment = c_c_alignment ws['D' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
ws['D' + str(row_title + 1)] = '最大负荷' ws['D' + str(per_unit_area_start_row_number + 1)] = '最大负荷'
ws['D' + str(row_title + 1)].border = f_border ws['D' + str(per_unit_area_start_row_number + 1)].border = f_border
# table_data # table_data
for i, value in enumerate(category): for i, value in enumerate(category):
row_data = row_title + 2 + i row_data = per_unit_area_start_row_number + 2 + i
ws['B' + str(row_data)].font = name_font ws['B' + str(row_data)].font = name_font
ws['B' + str(row_data)].alignment = c_c_alignment ws['B' + str(row_data)].alignment = c_c_alignment
ws['B' + str(row_data)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][ ws['B' + str(row_data)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][
@ -322,9 +316,9 @@ def generate_excel(report,
######################################################## ########################################################
# Third: 详细数据 # Third: 详细数据
# row_sat~ row_sat + 6*cal_len: line # analysis_end_row_number~ analysis_end_row_number + 6*cal_len: line
# row_da: table title # detailed_start_row_number: table title
# row_da + 1~: table_data # detailed_start_row_number + 1~: table_data
######################################################## ########################################################
has_timestamps_flag = True has_timestamps_flag = True
if "timestamps" not in reporting_period_data.keys() or \ if "timestamps" not in reporting_period_data.keys() or \
@ -337,40 +331,37 @@ def generate_excel(report,
names = reporting_period_data['names'] names = reporting_period_data['names']
ca_len = len(names) ca_len = len(names)
time_len = len(timestamps) time_len = len(timestamps)
# row_lines == the number of rows of lines line_charts_row_number = 6 * ca_len
row_lines = 6 * ca_len analysis_end_row_number = 12 + 3 * ca_len
# row_sat == the number of rows of statistical analysis table detailed_start_row_number = analysis_end_row_number + line_charts_row_number + 1
row_sat = 12 + 3 * ca_len
# row_da == the number of rows of Detailed data
row_da = row_sat + row_lines + 1
ws['B' + str(row_da)].font = title_font ws['B' + str(detailed_start_row_number)].font = title_font
ws['B' + str(row_da)] = name + ' 详细数据' ws['B' + str(detailed_start_row_number)] = name + ' 详细数据'
# table_title # table_title
ws['B' + str(row_da + 1)].fill = table_fill ws['B' + str(detailed_start_row_number + 1)].fill = table_fill
ws['B' + str(row_da + 1)].font = name_font ws['B' + str(detailed_start_row_number + 1)].font = name_font
ws['B' + str(row_da + 1)].alignment = c_c_alignment ws['B' + str(detailed_start_row_number + 1)].alignment = c_c_alignment
ws['B' + str(row_da + 1)] = "日期时间" ws['B' + str(detailed_start_row_number + 1)] = "日期时间"
ws['B' + str(row_da + 1)].border = f_border ws['B' + str(detailed_start_row_number + 1)].border = f_border
for i in range(0, ca_len): for i in range(0, ca_len):
col_average = chr(ord('C') + 2 * i) col_average = chr(ord('C') + 2 * i)
col_maximum = chr(ord('D') + 2 * i) col_maximum = chr(ord('D') + 2 * i)
ws[col_average + str(row_da + 1)].font = name_font ws[col_average + str(detailed_start_row_number + 1)].font = name_font
ws[col_average + str(row_da + 1)].alignment = c_c_alignment ws[col_average + str(detailed_start_row_number + 1)].alignment = c_c_alignment
ws[col_average + str(row_da + 1)] = names[i] + " 平均负荷(" + reporting_period_data['units'][ ws[col_average + str(detailed_start_row_number + 1)] = names[i] + " 平均负荷(" + reporting_period_data['units'][
i] + "/H)" i] + "/H)"
ws[col_average + str(row_da + 1)].border = f_border ws[col_average + str(detailed_start_row_number + 1)].border = f_border
ws[col_maximum + str(row_da + 1)].font = name_font ws[col_maximum + str(detailed_start_row_number + 1)].font = name_font
ws[col_maximum + str(row_da + 1)].alignment = c_c_alignment ws[col_maximum + str(detailed_start_row_number + 1)].alignment = c_c_alignment
ws[col_maximum + str(row_da + 1)] = names[i] + " 最大负荷(" + reporting_period_data['units'][ ws[col_maximum + str(detailed_start_row_number + 1)] = names[i] + " 最大负荷(" + reporting_period_data['units'][
i] + "/H)" i] + "/H)"
ws[col_maximum + str(row_da + 1)].border = f_border ws[col_maximum + str(detailed_start_row_number + 1)].border = f_border
# table_date # table_date
for i in range(0, time_len): for i in range(0, time_len):
rows = i + row_da + 2 rows = i + detailed_start_row_number + 2
ws['B' + str(rows)].font = name_font ws['B' + str(rows)].font = name_font
ws['B' + str(rows)].alignment = c_c_alignment ws['B' + str(rows)].alignment = c_c_alignment
@ -395,32 +386,36 @@ def generate_excel(report,
ws[col_maximum + str(rows)].number_format = '0.00' ws[col_maximum + str(rows)].number_format = '0.00'
ws[col_maximum + str(rows)].border = f_border ws[col_maximum + str(rows)].border = f_border
# LineChart ########################################################
# third: LineChart
# LineChart requires data from the detailed data table in the Excel file
# so print the detailed data table first and then print LineChart
########################################################
for i in range(0, ca_len): for i in range(0, ca_len):
lc = LineChart() line = LineChart()
lc.title = "报告期 最大负荷" line.title = "报告期 最大负荷 - " + names[i] + "(" + reporting_period_data['units'][i] + ")"
lc.style = 10 line.style = 10
lc.x_axis.majorTickMark = 'in' line.x_axis.majorTickMark = 'in'
lc.y_axis.majorTickMark = 'in' line.y_axis.majorTickMark = 'in'
lc.smooth = True line.smooth = True
lc.x_axis.crosses = 'min' line.x_axis.crosses = 'min'
lc.height = 8.25 line.height = 8.25
lc.width = 24 line.width = 24
lc.dLbls = DataLabelList() line.dLbls = DataLabelList()
lc.dLbls.dLblPos = 't' line.dLbls.dLblPos = 't'
lc.dLbls.showVal = True line.dLbls.showVal = True
times = Reference(ws, min_col=2, min_row=row_da + 2, times = Reference(ws, min_col=2, min_row=detailed_start_row_number + 2,
max_row=row_da + 2 + time_len) max_row=detailed_start_row_number + 2 + time_len)
lc_data = Reference(ws, min_col=2 + 2 * (i+1), min_row=row_da + 1, line_data = Reference(ws, min_col=2 + 2 * (i + 1), min_row=detailed_start_row_number + 1,
max_row=row_da + 1 + time_len) max_row=detailed_start_row_number + 1 + time_len)
lc.add_data(lc_data, titles_from_data=True) line.add_data(line_data, titles_from_data=True)
lc.set_categories(times) line.set_categories(times)
ser = lc.series[0] ser = line.series[0]
ser.marker.symbol = "diamond" ser.marker.symbol = "diamond"
ser.marker.size = 5 ser.marker.size = 5
chart_col = 'B' chart_col = 'B'
chart_cell = str(row_sat + 6 * i) chart_cell = str(analysis_end_row_number + 6 * i)
ws.add_chart(lc, chart_col + chart_cell) ws.add_chart(line, chart_col + chart_cell)
filename = str(uuid.uuid4()) + '.xlsx' filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename) wb.save(filename)

View File

@ -5,6 +5,7 @@ from openpyxl.chart import (
LineChart, LineChart,
Reference, Reference,
) )
from openpyxl.chart.label import DataLabelList
from openpyxl.styles import PatternFill, Border, Side, Alignment, Font from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
from openpyxl.drawing.image import Image from openpyxl.drawing.image import Image
from openpyxl import Workbook from openpyxl import Workbook
@ -68,19 +69,16 @@ def generate_excel(report,
ws = wb.active ws = wb.active
# Row height # Row height
ws.row_dimensions[1].height = 121 ws.row_dimensions[1].height = 102
for i in range(2, 37 + 1): for i in range(2, 2000 + 1):
ws.row_dimensions[i].height = 30 ws.row_dimensions[i].height = 42
for i in range(38, 90 + 1):
ws.row_dimensions[i].height = 30
# Col width # Col width
ws.column_dimensions['A'].width = 1.5 ws.column_dimensions['A'].width = 1.5
ws.column_dimensions['B'].width = 20.0 ws.column_dimensions['B'].width = 25.0
for i in range(ord('C'), ord('I')): for i in range(ord('C'), ord('L')):
ws.column_dimensions[chr(i)].width = 15.0 ws.column_dimensions[chr(i)].width = 15.0
# Font # Font
@ -116,12 +114,6 @@ def generate_excel(report,
wrap_text=False, wrap_text=False,
shrink_to_fit=False, shrink_to_fit=False,
indent=0) indent=0)
# c_r_alignment = Alignment(vertical='bottom',
# horizontal='center',
# text_rotation=0,
# wrap_text=False,
# shrink_to_fit=False,
# indent=0)
# Img # Img
img = Image("excelexporters/myems.png") img = Image("excelexporters/myems.png")
@ -318,63 +310,61 @@ def generate_excel(report,
# Second: 报告期消耗 # Second: 报告期消耗
# 9 + ca_len * 2: title # 9 + ca_len * 2: title
# 10 + ca_len * 2: table title # 10 + ca_len * 2: table title
# row_title + 2 ~ row_title + 2 + ca_len : table_data # per_unit_area_start_row_number + 2 ~ per_unit_area_start_row_number + 2 + ca_len : table_data
################################################# #################################################
if has_energy_data_flag: if has_energy_data_flag:
names = reporting_period_data['names'] names = reporting_period_data['names']
ca_len = len(names) ca_len = len(names)
row_title = 9 + ca_len * 2 per_unit_area_start_row_number = 9 + ca_len * 2
ws['B' + str(row_title)].font = title_font ws['B' + str(per_unit_area_start_row_number)].font = title_font
ws['B' + str(row_title)] = name + ' 单位面积值' ws['B' + str(per_unit_area_start_row_number)] = name + ' 单位面积值' + str(report['shopfloor']['area']) + ''
ws['D' + str(row_title)].font = title_font
ws['D' + str(row_title)] = str(report['shopfloor']['area']) + ''
category = reporting_period_data['names'] category = reporting_period_data['names']
# table_title # table_title
ws['B' + str(row_title + 1)].fill = table_fill ws['B' + str(per_unit_area_start_row_number + 1)].fill = table_fill
ws['B' + str(row_title + 1)].font = title_font ws['B' + str(per_unit_area_start_row_number + 1)].font = title_font
ws['B' + str(row_title + 1)].alignment = c_c_alignment ws['B' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
ws['B' + str(row_title + 1)] = '报告期' ws['B' + str(per_unit_area_start_row_number + 1)] = '报告期'
ws['B' + str(row_title + 1)].border = f_border ws['B' + str(per_unit_area_start_row_number + 1)].border = f_border
ws['C' + str(row_title + 1)].font = title_font ws['C' + str(per_unit_area_start_row_number + 1)].font = title_font
ws['C' + str(row_title + 1)].alignment = c_c_alignment ws['C' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
ws['C' + str(row_title + 1)] = '算术平均数' ws['C' + str(per_unit_area_start_row_number + 1)] = '算术平均数'
ws['C' + str(row_title + 1)].border = f_border ws['C' + str(per_unit_area_start_row_number + 1)].border = f_border
ws['D' + str(row_title + 1)].font = title_font ws['D' + str(per_unit_area_start_row_number + 1)].font = title_font
ws['D' + str(row_title + 1)].alignment = c_c_alignment ws['D' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
ws['D' + str(row_title + 1)] = '中位数' ws['D' + str(per_unit_area_start_row_number + 1)] = '中位数'
ws['D' + str(row_title + 1)].border = f_border ws['D' + str(per_unit_area_start_row_number + 1)].border = f_border
ws['E' + str(row_title + 1)].font = title_font ws['E' + str(per_unit_area_start_row_number + 1)].font = title_font
ws['E' + str(row_title + 1)].alignment = c_c_alignment ws['E' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
ws['E' + str(row_title + 1)] = '最小值' ws['E' + str(per_unit_area_start_row_number + 1)] = '最小值'
ws['E' + str(row_title + 1)].border = f_border ws['E' + str(per_unit_area_start_row_number + 1)].border = f_border
ws['F' + str(row_title + 1)].font = title_font ws['F' + str(per_unit_area_start_row_number + 1)].font = title_font
ws['F' + str(row_title + 1)].alignment = c_c_alignment ws['F' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
ws['F' + str(row_title + 1)] = '最大值' ws['F' + str(per_unit_area_start_row_number + 1)] = '最大值'
ws['F' + str(row_title + 1)].border = f_border ws['F' + str(per_unit_area_start_row_number + 1)].border = f_border
ws['G' + str(row_title + 1)].font = title_font ws['G' + str(per_unit_area_start_row_number + 1)].font = title_font
ws['G' + str(row_title + 1)].alignment = c_c_alignment ws['G' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
ws['G' + str(row_title + 1)] = '样本标准差' ws['G' + str(per_unit_area_start_row_number + 1)] = '样本标准差'
ws['G' + str(row_title + 1)].border = f_border ws['G' + str(per_unit_area_start_row_number + 1)].border = f_border
ws['H' + str(row_title + 1)].font = title_font ws['H' + str(per_unit_area_start_row_number + 1)].font = title_font
ws['H' + str(row_title + 1)].alignment = c_c_alignment ws['H' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
ws['H' + str(row_title + 1)] = '样本方差' ws['H' + str(per_unit_area_start_row_number + 1)] = '样本方差'
ws['H' + str(row_title + 1)].border = f_border ws['H' + str(per_unit_area_start_row_number + 1)].border = f_border
# table_data # table_data
for i, value in enumerate(category): for i, value in enumerate(category):
row_data = row_title + 2 + i row_data = per_unit_area_start_row_number + 2 + i
ws['B' + str(row_data)].font = name_font ws['B' + str(row_data)].font = name_font
ws['B' + str(row_data)].alignment = c_c_alignment ws['B' + str(row_data)].alignment = c_c_alignment
ws['B' + str(row_data)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][ ws['B' + str(row_data)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][
@ -431,9 +421,9 @@ def generate_excel(report,
######################################################## ########################################################
# Third: 详细数据 # Third: 详细数据
# row_sat+row_title~ row_sat+row_title+time_len: line # detailed_start_row_number~ detailed_start_row_number+time_len: line
# row_sat+1+row_title: table title # detailed_start_row_number+1: table title
# i + row_sat + 2 + 9 * ca_len~: table_data # i + analysis_end_row_number + 2 + 6 * ca_len~: table_data
######################################################## ########################################################
has_timestamps_flag = True has_timestamps_flag = True
if "timestamps" not in reporting_period_data.keys() or \ if "timestamps" not in reporting_period_data.keys() or \
@ -448,29 +438,29 @@ def generate_excel(report,
ca_len = len(names) ca_len = len(names)
time_len = len(timestamps) time_len = len(timestamps)
# title # title
row_title = 9 * ca_len line_charts_row_number = 6 * ca_len
# row_st == row_statistical analysis table analysis_end_row_number = 12 + 3 * ca_len
row_sat = 12 + 3 * ca_len detailed_start_row_number = analysis_end_row_number + line_charts_row_number + 1
ws['B' + str(row_sat+row_title)].font = title_font ws['B' + str(detailed_start_row_number)].font = title_font
ws['B' + str(row_sat+row_title)] = name + ' 详细数据' ws['B' + str(detailed_start_row_number)] = name + ' 详细数据'
# table_title # table_title
ws['B' + str(row_sat+1+row_title)].fill = table_fill ws['B' + str(detailed_start_row_number+1)].fill = table_fill
ws['B' + str(row_sat+1+row_title)].font = name_font ws['B' + str(detailed_start_row_number+1)].font = name_font
ws['B' + str(row_sat+1+row_title)].alignment = c_c_alignment ws['B' + str(detailed_start_row_number+1)].alignment = c_c_alignment
ws['B' + str(row_sat+1+row_title)] = "时间" ws['B' + str(detailed_start_row_number+1)] = "时间"
ws['B' + str(row_sat+1+row_title)].border = f_border ws['B' + str(detailed_start_row_number+1)].border = f_border
for i in range(0, ca_len): for i in range(0, ca_len):
col = chr(ord('C') + i) col = chr(ord('C') + i)
ws[col + str(row_sat+1+row_title)].font = name_font ws[col + str(detailed_start_row_number+1)].font = name_font
ws[col + str(row_sat+1+row_title)].alignment = c_c_alignment ws[col + str(detailed_start_row_number+1)].alignment = c_c_alignment
ws[col + str(row_sat+1+row_title)] = names[i] + " - (" + reporting_period_data['units'][i] + ")" ws[col + str(detailed_start_row_number+1)] = names[i] + " - (" + reporting_period_data['units'][i] + ")"
ws[col + str(row_sat+1+row_title)].border = f_border ws[col + str(detailed_start_row_number+1)].border = f_border
# table_date # table_date
for i in range(0, time_len): for i in range(0, time_len):
rows = i + row_sat + 2 + 9 * ca_len rows = i + detailed_start_row_number + 2
ws['B' + str(rows)].font = name_font ws['B' + str(rows)].font = name_font
ws['B' + str(rows)].alignment = c_c_alignment ws['B' + str(rows)].alignment = c_c_alignment
@ -487,7 +477,7 @@ def generate_excel(report,
ws[col + str(rows)].border = f_border ws[col + str(rows)].border = f_border
# 小计 # 小计
row_subtotals = row_sat + 2 + time_len + 9 * ca_len row_subtotals = detailed_start_row_number + 2 + time_len
ws['B' + str(row_subtotals)].font = name_font ws['B' + str(row_subtotals)].font = name_font
ws['B' + str(row_subtotals)].alignment = c_c_alignment ws['B' + str(row_subtotals)].alignment = c_c_alignment
ws['B' + str(row_subtotals)] = "小计" ws['B' + str(row_subtotals)] = "小计"
@ -502,26 +492,36 @@ def generate_excel(report,
ws[col + str(row_subtotals)].border = f_border ws[col + str(row_subtotals)].border = f_border
ws[col + str(row_subtotals)].number_format = '0.00' ws[col + str(row_subtotals)].number_format = '0.00'
# LineChart ########################################################
# third: LineChart
# LineChart requires data from the detailed data table in the Excel file
# so print the detailed data table first and then print LineChart
########################################################
for i in range(0, ca_len): for i in range(0, ca_len):
lc = LineChart() line = LineChart()
lc.title = "报告期消耗" + " - " + names[i] + "(" + reporting_period_data['units'][i] + ")" line.title = "报告期消耗" + " - " + names[i] + "(" + reporting_period_data['units'][i] + ")"
lc.style = 10 line.style = 10
lc.height = 8.40 # cm 1.05*8 1.05cm = 30 pt line.x_axis.majorTickMark = 'in'
lc.width = 31 line.y_axis.majorTickMark = 'in'
lc.x_axis.majorTickMark = 'in' line.smooth = True
lc.y_axis.majorTickMark = 'in' line.x_axis.crosses = 'min'
times = Reference(ws, min_col=2, min_row=row_sat + 2 + row_title, line.height = 8.25
max_row=row_sat + 2 + row_title + time_len) line.width = 24
lc_data = Reference(ws, min_col=3 + i, min_row=row_sat + 1 + row_title, line.dLbls = DataLabelList()
max_row=row_sat + 1 + row_title + time_len) line.dLbls.dLblPos = 't'
lc.add_data(lc_data, titles_from_data=True) line.dLbls.showVal = True
lc.set_categories(times) times = Reference(ws, min_col=2, min_row=detailed_start_row_number + 2,
ser = lc.series[0] max_row=detailed_start_row_number + 2 + time_len)
line_data = Reference(ws, min_col=3 + i, min_row=detailed_start_row_number + 1,
max_row=detailed_start_row_number + 1 + time_len)
line.add_data(line_data, titles_from_data=True)
line.set_categories(times)
ser = line.series[0]
ser.marker.symbol = "diamond" ser.marker.symbol = "diamond"
ser.marker.size = 5 chart_col = 'B'
ws.add_chart(lc, 'B' + str(row_sat + 9 * i)) chart_cell = str(analysis_end_row_number + 6 * i)
ws.add_chart(line, chart_col + chart_cell)
filename = str(uuid.uuid4()) + '.xlsx' filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename) wb.save(filename)

View File

@ -5,6 +5,7 @@ from openpyxl.chart import (
LineChart, LineChart,
Reference, Reference,
) )
from openpyxl.chart.label import DataLabelList
from openpyxl.styles import PatternFill, Border, Side, Alignment, Font from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
from openpyxl.drawing.image import Image from openpyxl.drawing.image import Image
from openpyxl import Workbook from openpyxl import Workbook
@ -68,19 +69,16 @@ def generate_excel(report,
ws = wb.active ws = wb.active
# Row height # Row height
ws.row_dimensions[1].height = 121 ws.row_dimensions[1].height = 102
for i in range(2, 37 + 1): for i in range(2, 2000 + 1):
ws.row_dimensions[i].height = 30 ws.row_dimensions[i].height = 42
for i in range(38, 90 + 1):
ws.row_dimensions[i].height = 30
# Col width # Col width
ws.column_dimensions['A'].width = 1.5 ws.column_dimensions['A'].width = 1.5
ws.column_dimensions['B'].width = 20.0 ws.column_dimensions['B'].width = 25.0
for i in range(ord('C'), ord('I')): for i in range(ord('C'), ord('L')):
ws.column_dimensions[chr(i)].width = 15.0 ws.column_dimensions[chr(i)].width = 15.0
# Font # Font
@ -116,12 +114,6 @@ def generate_excel(report,
wrap_text=False, wrap_text=False,
shrink_to_fit=False, shrink_to_fit=False,
indent=0) indent=0)
# c_r_alignment = Alignment(vertical='bottom',
# horizontal='center',
# text_rotation=0,
# wrap_text=False,
# shrink_to_fit=False,
# indent=0)
# Img # Img
img = Image("excelexporters/myems.png") img = Image("excelexporters/myems.png")
@ -320,63 +312,63 @@ def generate_excel(report,
# Second: 报告期消耗 # Second: 报告期消耗
# 9 + ca_len * 2: title # 9 + ca_len * 2: title
# 10 + ca_len * 2: table title # 10 + ca_len * 2: table title
# row_title + 2 ~ row_title + 2 + ca_len : table_data # per_unit_area_start_row_number + 2 ~ per_unit_area_start_row_number + 2 + ca_len : table_data
################################################# #################################################
if has_energy_data_flag: if has_energy_data_flag:
names = reporting_period_data['names'] names = reporting_period_data['names']
ca_len = len(names) ca_len = len(names)
row_title = 9 + ca_len * 2 per_unit_area_start_row_number = 9 + ca_len * 2
ws['B' + str(row_title)].font = title_font ws['B' + str(per_unit_area_start_row_number)].font = title_font
ws['B' + str(row_title)] = name + ' 单位面积值' ws['B' + str(per_unit_area_start_row_number)] = name + ' 单位面积值'
ws['D' + str(row_title)].font = title_font ws['D' + str(per_unit_area_start_row_number)].font = title_font
ws['D' + str(row_title)] = str(report['space']['area']) + '' ws['D' + str(per_unit_area_start_row_number)] = str(report['space']['area']) + ''
category = reporting_period_data['names'] category = reporting_period_data['names']
# table_title # table_title
ws['B' + str(row_title + 1)].fill = table_fill ws['B' + str(per_unit_area_start_row_number + 1)].fill = table_fill
ws['B' + str(row_title + 1)].font = title_font ws['B' + str(per_unit_area_start_row_number + 1)].font = title_font
ws['B' + str(row_title + 1)].alignment = c_c_alignment ws['B' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
ws['B' + str(row_title + 1)] = '报告期' ws['B' + str(per_unit_area_start_row_number + 1)] = '报告期'
ws['B' + str(row_title + 1)].border = f_border ws['B' + str(per_unit_area_start_row_number + 1)].border = f_border
ws['C' + str(row_title + 1)].font = title_font ws['C' + str(per_unit_area_start_row_number + 1)].font = title_font
ws['C' + str(row_title + 1)].alignment = c_c_alignment ws['C' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
ws['C' + str(row_title + 1)] = '算术平均数' ws['C' + str(per_unit_area_start_row_number + 1)] = '算术平均数'
ws['C' + str(row_title + 1)].border = f_border ws['C' + str(per_unit_area_start_row_number + 1)].border = f_border
ws['D' + str(row_title + 1)].font = title_font ws['D' + str(per_unit_area_start_row_number + 1)].font = title_font
ws['D' + str(row_title + 1)].alignment = c_c_alignment ws['D' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
ws['D' + str(row_title + 1)] = '中位数' ws['D' + str(per_unit_area_start_row_number + 1)] = '中位数'
ws['D' + str(row_title + 1)].border = f_border ws['D' + str(per_unit_area_start_row_number + 1)].border = f_border
ws['E' + str(row_title + 1)].font = title_font ws['E' + str(per_unit_area_start_row_number + 1)].font = title_font
ws['E' + str(row_title + 1)].alignment = c_c_alignment ws['E' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
ws['E' + str(row_title + 1)] = '最小值' ws['E' + str(per_unit_area_start_row_number + 1)] = '最小值'
ws['E' + str(row_title + 1)].border = f_border ws['E' + str(per_unit_area_start_row_number + 1)].border = f_border
ws['F' + str(row_title + 1)].font = title_font ws['F' + str(per_unit_area_start_row_number + 1)].font = title_font
ws['F' + str(row_title + 1)].alignment = c_c_alignment ws['F' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
ws['F' + str(row_title + 1)] = '最大值' ws['F' + str(per_unit_area_start_row_number + 1)] = '最大值'
ws['F' + str(row_title + 1)].border = f_border ws['F' + str(per_unit_area_start_row_number + 1)].border = f_border
ws['G' + str(row_title + 1)].font = title_font ws['G' + str(per_unit_area_start_row_number + 1)].font = title_font
ws['G' + str(row_title + 1)].alignment = c_c_alignment ws['G' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
ws['G' + str(row_title + 1)] = '样本标准差' ws['G' + str(per_unit_area_start_row_number + 1)] = '样本标准差'
ws['G' + str(row_title + 1)].border = f_border ws['G' + str(per_unit_area_start_row_number + 1)].border = f_border
ws['H' + str(row_title + 1)].font = title_font ws['H' + str(per_unit_area_start_row_number + 1)].font = title_font
ws['H' + str(row_title + 1)].alignment = c_c_alignment ws['H' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment
ws['H' + str(row_title + 1)] = '样本方差' ws['H' + str(per_unit_area_start_row_number + 1)] = '样本方差'
ws['H' + str(row_title + 1)].border = f_border ws['H' + str(per_unit_area_start_row_number + 1)].border = f_border
# table_data # table_data
for i, value in enumerate(category): for i, value in enumerate(category):
row_data = row_title + 2 + i row_data = per_unit_area_start_row_number + 2 + i
ws['B' + str(row_data)].font = name_font ws['B' + str(row_data)].font = name_font
ws['B' + str(row_data)].alignment = c_c_alignment ws['B' + str(row_data)].alignment = c_c_alignment
ws['B' + str(row_data)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][ ws['B' + str(row_data)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][
@ -433,9 +425,9 @@ def generate_excel(report,
######################################################## ########################################################
# Third: 详细数据 # Third: 详细数据
# row_sat+row_title~ row_sat+row_title+time_len: line # analysis_end_row_number~ analysis_end_row_number+time_len: line
# row_sat+1+row_title: table title # analysis_end_row_number+1+line_charts_row_number: table title
# i + row_sat + 2 + 10 * ca_len~: table_data # i + analysis_end_row_number + 2 + 10 * ca_len~: table_data
######################################################## ########################################################
has_timestamps_flag = True has_timestamps_flag = True
if "timestamps" not in reporting_period_data.keys() or \ if "timestamps" not in reporting_period_data.keys() or \
@ -450,29 +442,29 @@ def generate_excel(report,
ca_len = len(names) ca_len = len(names)
time_len = len(timestamps) time_len = len(timestamps)
# title # title
row_title = 10 * ca_len line_charts_row_number = 6 * ca_len
# row_st == row_statistical analysis table analysis_end_row_number = 12 + 3 * ca_len
row_sat = 12 + 3 * ca_len detailed_start_row_number = analysis_end_row_number + line_charts_row_number + 1
ws['B' + str(row_sat+row_title)].font = title_font ws['B' + str(detailed_start_row_number)].font = title_font
ws['B' + str(row_sat+row_title)] = name + ' 详细数据' ws['B' + str(detailed_start_row_number)] = name + ' 详细数据'
# table_title # table_title
ws['B' + str(row_sat+1+row_title)].fill = table_fill ws['B' + str(detailed_start_row_number + 1)].fill = table_fill
ws['B' + str(row_sat+1+row_title)].font = name_font ws['B' + str(detailed_start_row_number + 1)].font = name_font
ws['B' + str(row_sat+1+row_title)].alignment = c_c_alignment ws['B' + str(detailed_start_row_number + 1)].alignment = c_c_alignment
ws['B' + str(row_sat+1+row_title)] = "时间" ws['B' + str(detailed_start_row_number + 1)] = "时间"
ws['B' + str(row_sat+1+row_title)].border = f_border ws['B' + str(detailed_start_row_number + 1)].border = f_border
for i in range(0, ca_len): for i in range(0, ca_len):
col = chr(ord('C') + i) col = chr(ord('C') + i)
ws[col + str(row_sat+1+row_title)].font = name_font ws[col + str(detailed_start_row_number + 1)].font = name_font
ws[col + str(row_sat+1+row_title)].alignment = c_c_alignment ws[col + str(detailed_start_row_number + 1)].alignment = c_c_alignment
ws[col + str(row_sat+1+row_title)] = names[i] + " - (" + reporting_period_data['units'][i] + ")" ws[col + str(detailed_start_row_number + 1)] = names[i] + " - (" + reporting_period_data['units'][i] + ")"
ws[col + str(row_sat+1+row_title)].border = f_border ws[col + str(detailed_start_row_number + 1)].border = f_border
# table_date # table_date
for i in range(0, time_len): for i in range(0, time_len):
rows = i + row_sat + 2 + 10 * ca_len rows = i + detailed_start_row_number + 2
ws['B' + str(rows)].font = name_font ws['B' + str(rows)].font = name_font
ws['B' + str(rows)].alignment = c_c_alignment ws['B' + str(rows)].alignment = c_c_alignment
@ -489,7 +481,7 @@ def generate_excel(report,
ws[col + str(rows)].border = f_border ws[col + str(rows)].border = f_border
# 小计 # 小计
row_subtotals = row_sat + 2 + time_len + 10 * ca_len row_subtotals = detailed_start_row_number + 2 + time_len
ws['B' + str(row_subtotals)].font = name_font ws['B' + str(row_subtotals)].font = name_font
ws['B' + str(row_subtotals)].alignment = c_c_alignment ws['B' + str(row_subtotals)].alignment = c_c_alignment
ws['B' + str(row_subtotals)] = "小计" ws['B' + str(row_subtotals)] = "小计"
@ -504,26 +496,35 @@ def generate_excel(report,
ws[col + str(row_subtotals)].border = f_border ws[col + str(row_subtotals)].border = f_border
ws[col + str(row_subtotals)].number_format = '0.00' ws[col + str(row_subtotals)].number_format = '0.00'
# LineChart ########################################################
# third: LineChart
# LineChart requires data from the detailed data table in the Excel file
# so print the detailed data table first and then print LineChart
########################################################
for i in range(0, ca_len): for i in range(0, ca_len):
lc = LineChart() line = LineChart()
lc.title = "报告期消耗" + " - " + names[i] + "(" + reporting_period_data['units'][i] + ")" line.title = "报告期消耗" + " - " + names[i] + "(" + reporting_period_data['units'][i] + ")"
lc.style = 10 line.style = 10
lc.height = 8.40 # cm 1.05*8 1.05cm = 30 pt line.x_axis.majorTickMark = 'in'
lc.width = 31 line.y_axis.majorTickMark = 'in'
lc.x_axis.majorTickMark = 'in' line.smooth = True
lc.y_axis.majorTickMark = 'in' line.x_axis.crosses = 'min'
times = Reference(ws, min_col=2, min_row=row_sat + 2 + row_title, line.height = 8.25
max_row=row_sat + 2 + row_title + time_len) line.width = 24
lc_data = Reference(ws, min_col=3 + i, min_row=row_sat + 1 + row_title, line.dLbls = DataLabelList()
max_row=row_sat + 1 + row_title + time_len) line.dLbls.dLblPos = 't'
lc.add_data(lc_data, titles_from_data=True) line.dLbls.showVal = True
lc.set_categories(times) times = Reference(ws, min_col=2, min_row=detailed_start_row_number + 2,
ser = lc.series[0] max_row=detailed_start_row_number + 2 + time_len)
line_data = Reference(ws, min_col=3 + i, min_row=detailed_start_row_number + 1,
max_row=detailed_start_row_number + 1 + time_len)
line.add_data(line_data, titles_from_data=True)
line.set_categories(times)
ser = line.series[0]
ser.marker.symbol = "diamond" ser.marker.symbol = "diamond"
ser.marker.size = 5 ser.marker.size = 5
ws.add_chart(lc, 'B' + str(row_sat + 10 * i)) ws.add_chart(line, 'B' + str(analysis_end_row_number + 6 * i))
filename = str(uuid.uuid4()) + '.xlsx' filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename) wb.save(filename)

View File

@ -5,6 +5,7 @@ import config
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
from core import utilities from core import utilities
from decimal import Decimal from decimal import Decimal
import excelexporters.combinedequipmentstatistics
class Reporting: class Reporting:
@ -560,4 +561,11 @@ class Reporting:
"values": parameters_data['values'] "values": parameters_data['values']
} }
# export result to Excel file and then encode the file to base64 string
result['excel_bytes_base64'] = excelexporters.combinedequipmentstatistics.export(result,
combined_equipment['name'],
reporting_start_datetime_local,
reporting_end_datetime_local,
period_type)
resp.body = json.dumps(result) resp.body = json.dumps(result)