功能变化: 导出模板优化

pull/64/head
李强 2022-06-14 22:59:23 +08:00
parent 8817edd603
commit f768cc6dea
2 changed files with 84 additions and 10 deletions

View File

@ -7,7 +7,7 @@ from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated
from application import dispatch
from dvadmin.system.models import Users
from dvadmin.system.models import Users, Role, Dept
from dvadmin.system.views.role import RoleSerializer
from dvadmin.utils.json_response import ErrorResponse, DetailResponse
from dvadmin.utils.serializers import CustomModelSerializer
@ -239,11 +239,33 @@ class UserViewSet(CustomModelViewSet):
"name": "用户名称",
"email": "用户邮箱",
"mobile": "手机号码",
"gender": "用户性别(男/女/未知)",
"is_active": "帐号状态(启用/禁用)",
"gender": {
"title": "用户性别",
"choices": {
"data": [{"未知": 2}, {"": 1}, {"": 0}],
}
},
"is_active": {
"title": "帐号状态",
"choices": {
"data": [{"启用": True}, {"禁用": False}],
}
},
"password": "登录密码",
"dept": "部门ID",
"role": "角色ID",
"dept": {
"title": "部门",
"choices": {
"queryset": Dept.objects.filter(status=True),
"values_list": "name"
}
},
"role": {
"title": "角色",
"choices": {
"queryset": Role.objects.filter(status=True),
"values_list": "name"
}
},
}
@action(methods=["GET"], detail=False, permission_classes=[IsAuthenticated])

View File

@ -4,7 +4,8 @@ from urllib.parse import quote
from django.db import transaction
from django.http import HttpResponse
from openpyxl import Workbook
from openpyxl.utils import get_column_letter
from openpyxl.worksheet.datavalidation import DataValidation
from openpyxl.utils import get_column_letter, quote_sheetname
from openpyxl.worksheet.table import Table, TableStyleInfo
from rest_framework.request import Request
@ -15,13 +16,28 @@ from dvadmin.utils.request_util import get_verbose_name
class ImportSerializerMixin:
"""
自定义导模板导入功能
自定义导模板导入功能
"""
# 导入字段
import_field_dict = {}
# 导入序列化器
import_serializer_class = None
# 表格表头最大宽度默认50个字符
export_column_width = 50
def get_string_len(self, string):
"""
获取字符串最大长度
:param string:
:return:
"""
length = 4
if string is None:
return length
for char in string:
length += 2.1 if ord(char) > 256 else 1
return round(length, 1) if length <= self.export_column_width else self.export_column_width
@transaction.atomic # Django 事务,防止出错
def import_data(self, request: Request, *args, **kwargs):
@ -44,10 +60,46 @@ class ImportSerializerMixin:
"Content-Disposition"
] = f'attachment;filename={quote(str(f"导入{get_verbose_name(queryset)}模板.xlsx"))}'
wb = Workbook()
ws1 = wb.create_sheet("data", 1)
ws1.sheet_state = 'hidden'
ws = wb.active
row = get_column_letter(len(self.import_field_dict) + 1)
column = 10
ws.append(["序号", *self.import_field_dict.values()])
header_data = ["序号", ]
validation_data_dict = {}
for index, ele in enumerate(self.import_field_dict.values()):
if isinstance(ele, dict):
header_data.append(ele.get('title'))
choices = ele.get('choices', {})
if choices.get('data'):
data_list = []
for data in choices.get('data'):
data_list.extend(data.keys())
validation_data_dict[ele.get('title')] = data_list
elif choices.get('queryset') and choices.get('values_list'):
data_list = choices.get('queryset').values_list(choices.get('values_list'), flat=True)
validation_data_dict[ele.get('title')] = list(data_list)
else:
continue
column_letter = get_column_letter(len(validation_data_dict))
dv = DataValidation(type="list",
formula1=f"{quote_sheetname('data')}!${column_letter}$2:${column_letter}${len(validation_data_dict[ele.get('title')]) + 1}",
allow_blank=True)
ws.add_data_validation(dv)
dv.add(f"{get_column_letter(index + 2)}2:{get_column_letter(index + 2)}1048576")
else:
header_data.append(ele)
# 添加数据列
ws1.append(list(validation_data_dict.keys()))
for index, validation_data in enumerate(validation_data_dict.values()):
for inx, ele in enumerate(validation_data):
ws1[f"{get_column_letter(index + 1)}{inx + 2}"] = ele
# 插入导出模板正式数据
df_len_max = [self.get_string_len(ele) for ele in header_data]
ws.append(header_data)
#  更新列宽
for index, width in enumerate(df_len_max):
ws.column_dimensions[get_column_letter(index + 1)].width = width
tab = Table(displayName="Table1", ref=f"A1:{row}{column}") # 名称管理器
style = TableStyleInfo(
name="TableStyleLight11",