You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

331 lines
14 KiB

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@Date:2022/08/27 11:05:06
'''
import sys
sys.path.append('.')
import string
import os
import datetime
from openpyxl.workbook import Workbook
from openpyxl.styles import Alignment, Side, Border, Font, PatternFill
class ReportData:
def __init__(self):
# 新建一个workbook
self.wb = Workbook()
# 定义设置样式
self.a = 0
def set_style(self, title='sheet1'):
# 如果是第一次调用则删除默认创建的sheet表
if self.a == 0:
self.wb.remove(self.wb['Sheet'])
self.a += 1
# 创建第几个sheet
self.ws = self.wb.create_sheet()
# 设置sheet的标题
self.ws.title = title
# 设置1 2 3 行固定的高度
self.ws.row_dimensions[1].height = 35
self.ws.row_dimensions[2].height = 25
self.ws.row_dimensions[3].height = 28
# 水平对齐, 居中对齐
self.alignment_style = Alignment(
horizontal='center', vertical='center')
# 定义Border边框样式
left, right, top, bottom = [Side(style='thin', color='000000')] * 4
self.border_style = Border(
left=left, right=right, top=top, bottom=bottom)
# 设置列宽
# 生成前14个大写字母 ascii_uppercase生成所有大写字母
self.upper_string = string.ascii_uppercase[:15]
# 定义字体
self.font_size = Font(size=9)
for col in self.upper_string:
self.ws.column_dimensions[col].width = 20
# 创建第一行
def create_row1(self, value, length):
# 合并第1行1-14列单元格
self.ws.merge_cells(start_row=1, end_row=1,
start_column=1, end_column=length)
# 写入值
self.ws.cell(row=1, column=1).value = value
self.ws['A1'].alignment = self.alignment_style
self.ws['A1'].font = Font(size=16, bold=True)
self.create_row2(length)
def create_row2(self, length):
# 第2行写入值
now_time = datetime.datetime.now().strftime('%Y%m%d %H%M')
# 格式化时间为中文年月日
now_time = now_time[:4] + '' + now_time[4:6] + '' + \
now_time[6:8] + '' + now_time[8:11] + '' + now_time[11:13] + ''
self.ws.cell(row=2, column=1).value = '报表导出时间:{}'.format(now_time)
self.ws.cell(row=2, column=3).value = '终端系统版本:3.1'
self.ws.cell(row=2, column=5).value = ''
self.ws.cell(row=2, column=7).value = '报表导出位置:终端'
# 合并单元格
x = 1
while x < 6:
self.ws.merge_cells(start_row=2, end_row=2,
start_column=x, end_column=x + 1)
x += 2
self.ws.merge_cells(start_row=2, end_row=2,
start_column=7, end_column=length)
# 遍历取1, 3, 5, 7为第二行添加样式
for x in range(1, 8, 2):
self.ws.cell(row=2, column=x).font = Font(size=9)
# 水平对齐 垂直对齐
self.ws.cell(row=2, column=x).alignment = self.alignment_style
if x < 7:
# 边框样式
self.ws.cell(row=2, column=x).border = self.border_style
self.ws.cell(row=2, column=x + 1).border = self.border_style
else:
# 因为第2行第7-14列是合并的单元格 所以需要循环添加边框样式
while x < length + 1:
self.ws.cell(row=2, column=x).border = self.border_style
x += 1
# 创建第三行, 需要传入一个列表用来写入单元格的值
def create_row3(self, data_list):
for data in range(1, len(data_list) + 1):
# 第三行写入值
self.ws.cell(row=3, column=data).value = data_list[data - 1]
# 设置文本水平居中, 垂直居中
self.ws.cell(row=3, column=data).alignment = self.alignment_style
# 设置字体加粗
self.ws.cell(row=3, column=data).font = Font(bold=True, size=9)
# 背景颜色
self.ws.cell(row=3, column=data).fill = PatternFill(
fill_type='solid', fgColor='EE9A49')
# 边框样式
self.ws.cell(row=3, column=data).border = self.border_style
# 创建多行固定样式 start_row从第几行开始有规律 传入一个数据库获取的列表对象的值, 传入一个数据对象keys列表
def create_multiple_rows(self, start_row, data_list, keys_list):
# 从第4行创建
for row_number in range(start_row, len(data_list) + start_row):
# 设置每一行的行高
self.ws.row_dimensions[row_number].height = 18
# 遍历每一个对象的长度
col_ = 1
for key_ in keys_list:
# 写入值
try:
# 判断是否时datetime 类型,
if isinstance(dict(data_list[row_number - start_row]).get(key_), datetime.datetime):
value = dict(data_list[row_number - start_row]).get(key_).replace(tzinfo=None)
# 判断是否时state
elif key_=='state':
value = dict(data_list[row_number - start_row]).get(key_).value
else:
value = dict(data_list[row_number - start_row]).get(key_)
except :
value = "/"
self.ws.cell(row=row_number, column=col_).value = value
# 设置文本水平居中, 垂直居中
self.ws.cell(row=row_number,
column=col_).alignment = self.alignment_style
# 设置边框样式
self.ws.cell(row=row_number,
column=col_).border = self.border_style
# 设置字体大小
self.ws.cell(row=row_number, column=col_).font = Font(size=9)
col_ += 1
# 保存文件
def save(self, file_path):
self.wb.save('{}.xlsx'.format(file_path))
self.close()
# 关闭文件
def close(self):
self.wb.close()
# 替换空白
def replace_space(self, length):
self.max_lines = self.ws.max_row
upper_letter_str = string.ascii_uppercase[:length]
for upper_letter in upper_letter_str:
print(upper_letter)
for row_ in range(1, self.max_lines + 1):
b = self.ws[upper_letter + str(row_)].value
# print(b)
if not b:
self.ws[upper_letter + str(row_)].value = 'null'
# 编辑excel表格中列药剂状态1 2 3 替换为在库 出库
def editor_status(self, col_):
self.max_lines = self.ws.max_row
for row_ in range(4, self.max_lines + 1):
b = self.ws[col_ + str(row_)].value
if b == 1:
self.ws[col_ + str(row_)].value = '在库'
elif b == 0:
self.ws[col_ + str(row_)].value = '待入库'
elif b == 2:
self.ws[col_ + str(row_)].value = '出库'
elif b == 3:
self.ws[col_ + str(row_)].value = '空瓶'
elif b == 4:
self.ws[col_ + str(row_)].value = '销毁'
# 编辑 温度报警类型 01 替换为正常和异常
def eidtor_temperature_type(self,col_):
self.max_lines = self.ws.max_row
for row_ in range(4,self.max_lines +1):
b = self.ws[col_ + str(row_)].value
if b==0:
self.ws[col_ + str(row_)].value = "正常"
elif b ==1 :
self.ws[col_ + str(row_)].value = "异常"
# 编辑药剂重点监管列为1 0 替换为是 否
def editor_isSupervise(self, col_):
self.max_lines = self.ws.max_row
for row_ in range(4, self.max_lines + 1):
b = self.ws[col_ + str(row_)].value
if b == 1:
self.ws[col_ + str(row_)].value = ''
elif b == 0:
self.ws[col_ + str(row_)].value = ''
# 编辑操作类型 1 2 3 入库 领用 归还
def editor_RecordType(self, col_):
self.max_lines = self.ws.max_row
for row_ in range(4, self.max_lines + 1):
b = self.ws[col_ + str(row_)].value
if b == 1:
self.ws[col_ + str(row_)].value = '入库'
elif b == 2:
self.ws[col_ + str(row_)].value = '领用'
elif b == 3:
self.ws[col_ + str(row_)].value = '归还'
# 替换sqlAlchemy时间格式
def editor_time(self, keys_list, params):
self.max_lines = self.ws.max_row
for row_ in range(4, self.max_lines + 1):
col_ = string.ascii_uppercase[keys_list.index(params)]
b = self.ws[col_ + str(row_)].value
# print('sssssssssssssssssssssssssssssssssssssssssassssssssssssssss:::', b,type(b))
try:
if len(b) == 19:
self.ws[col_ + str(row_)].value = b.replace('T', ' ')
except Exception as e :
pass
# print(e)
# 编辑用户管理列为1 0 替换为正常 禁用
def editor_user_status(self, col_):
self.max_lines = self.ws.max_row
for row_ in range(4, self.max_lines + 1):
b = self.ws[col_ + str(row_)].value
if b == 1:
self.ws[col_ + str(row_)].value = '正常'
elif b == 0:
self.ws[col_ + str(row_)].value = '禁用'
# 构建文件内容
def build_file(self,**kwargs):
data_list = kwargs.pop("data_list")
key_list = kwargs.pop("key_list")
finds_name = kwargs.pop("finds_name")
self.set_style(title="Sheet")
file_name = kwargs.pop("file_name")
self.create_row1(file_name, len(finds_name))
self.create_row3(finds_name)
self.create_multiple_rows(4, data_list, key_list)
for i in key_list:
if "date" in i:
self.editor_time(key_list, i)
if "state" in i:
self.editor_status(string.ascii_uppercase[key_list.index(i)])
if "temperature_type" in i:
self.eidtor_temperature_type(string.ascii_uppercase[key_list.index(i)])
if "is_supervise" in i:
self.editor_isSupervise(string.ascii_uppercase[key_list.index(i)])
if "record_type" == i:
self.editor_RecordType(
string.ascii_uppercase[key_list.index(i)])
return self
# 下载文件
@staticmethod
def download_excel(filename, chunk_size=512):
try:
f = open(filename, 'rb')
except:
return
while True:
c = f.read(chunk_size)
if c:
yield c
else:
f.close()
os.remove(filename)
break
# # 导出用户数据报表接口
# @dataReport.route('/downloadUserReport', methods=["GET", "POST"])
# def downloadUserReport():
# try:
# uPath = Utils.getUDiskPath()
# if (uPath == ''):
# return jsonify(Utils.resultData(1, '未检测到U盘'))
# else:
# data_user_list = BllUser().findList().all()
# data_user_list = json.loads(
# Utils.resultAlchemyData(data_user_list))
# # 创建一个报表类实例
# a = ReportData()
# a.set_style(title='Sheet')
# data_list = ['工号', '角色', '姓名', '性别', 'QQ', '手机', '邮箱',
# '条码', '状态', '最后一次登录时间', ]
# a.create_row1('用户角色数据统计表', len(data_list))
# a.create_row3(data_list)
# keys_list = ['UserCode', 'RoleName', 'RealName', 'Sex', 'QQ', 'Mobile', 'Email',
# 'BarCode', 'IsEnabled', 'LastVisitDate', ]
# a.create_multiple_rows(4, data_user_list, keys_list)
# a.replace_space(len(data_list))
# a.editor_time(keys_list, 'LastVisitDate')
# # 判断用户角色
# for row_ in range(4, a.max_lines + 1):
# col_ = string.ascii_uppercase[keys_list.index('UserCode')]
# b = a.ws[col_ + str(row_)].value
# if b == 'admin':
# for col_value in range(1, len(keys_list) + 1):
# a.ws.cell(row=row_, column=col_value).fill = PatternFill(
# fill_type='solid', fgColor='FF0000')
# elif b == 'yanyi':
# for col_value in range(1, len(keys_list) + 1):
# a.ws.cell(row=row_, column=col_value).fill = PatternFill(
# fill_type='solid', fgColor='FFFF00')
# # 优化用户性别
# for row_ in range(4, a.max_lines + 1):
# col_ = string.ascii_uppercase[keys_list.index('Sex')]
# b = a.ws[col_ + str(row_)].value
# if b == 0:
# a.ws[col_ + str(row_)].value = '女'
# else:
# a.ws[col_ + str(row_)].value = '男'
# a.editor_user_status('I')
# file_name = '用户角色数据统计表{}'.format(Utils.UUID())
# a.save(uPath + '/' + file_name)
# returnData = Utils.resultData(0, '导出成功')
# return jsonify(returnData)
# except Exception as e:
# return jsonify(Utils.resultData(2, str(e)))