diff --git a/ruoyi-fastapi-backend/module_admin/service/config_service.py b/ruoyi-fastapi-backend/module_admin/service/config_service.py index 1d8ec76..312006d 100644 --- a/ruoyi-fastapi-backend/module_admin/service/config_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/config_service.py @@ -7,7 +7,8 @@ from exceptions.exception import ServiceException from module_admin.dao.config_dao import ConfigDao from module_admin.entity.vo.common_vo import CrudResponseModel from module_admin.entity.vo.config_vo import ConfigModel, ConfigPageQueryModel, DeleteConfigModel -from utils.common_util import CamelCaseUtil, export_list2excel +from utils.common_util import CamelCaseUtil +from utils.excel_util import ExcelUtil class ConfigService: @@ -207,17 +208,12 @@ class ConfigService: 'remark': '备注', } - data = config_list - - for item in data: + for item in config_list: if item.get('configType') == 'Y': item['configType'] = '是' else: item['configType'] = '否' - new_data = [ - {mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data - ] - binary_data = export_list2excel(new_data) + binary_data = ExcelUtil.export_list2excel(config_list, mapping_dict) return binary_data diff --git a/ruoyi-fastapi-backend/module_admin/service/dict_service.py b/ruoyi-fastapi-backend/module_admin/service/dict_service.py index 5354083..bfe6489 100644 --- a/ruoyi-fastapi-backend/module_admin/service/dict_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/dict_service.py @@ -15,7 +15,8 @@ from module_admin.entity.vo.dict_vo import ( DictTypeModel, DictTypePageQueryModel, ) -from utils.common_util import CamelCaseUtil, export_list2excel +from utils.common_util import CamelCaseUtil +from utils.excel_util import ExcelUtil class DictTypeService: @@ -192,17 +193,12 @@ class DictTypeService: 'remark': '备注', } - data = dict_type_list - - for item in data: + for item in dict_type_list: if item.get('status') == '0': item['status'] = '正常' else: item['status'] = '停用' - new_data = [ - {mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data - ] - binary_data = export_list2excel(new_data) + binary_data = ExcelUtil.export_list2excel(dict_type_list, mapping_dict) return binary_data @@ -448,9 +444,7 @@ class DictDataService: 'remark': '备注', } - data = dict_data_list - - for item in data: + for item in dict_data_list: if item.get('status') == '0': item['status'] = '正常' else: @@ -459,9 +453,6 @@ class DictDataService: item['isDefault'] = '是' else: item['isDefault'] = '否' - new_data = [ - {mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data - ] - binary_data = export_list2excel(new_data) + binary_data = ExcelUtil.export_list2excel(dict_data_list, mapping_dict) return binary_data diff --git a/ruoyi-fastapi-backend/module_admin/service/job_log_service.py b/ruoyi-fastapi-backend/module_admin/service/job_log_service.py index f4c9f37..596abe7 100644 --- a/ruoyi-fastapi-backend/module_admin/service/job_log_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/job_log_service.py @@ -6,7 +6,7 @@ from module_admin.dao.job_log_dao import JobLogDao from module_admin.entity.vo.common_vo import CrudResponseModel from module_admin.entity.vo.job_vo import DeleteJobLogModel, JobLogModel, JobLogPageQueryModel from module_admin.service.dict_service import DictDataService -from utils.common_util import export_list2excel +from utils.excel_util import ExcelUtil class JobLogService: @@ -115,7 +115,6 @@ class JobLogService: 'createTime': '创建时间', } - data = job_log_list job_group_list = await DictDataService.query_dict_data_list_from_cache_services( request.app.state.redis, dict_type='sys_job_group' ) @@ -129,7 +128,7 @@ class JobLogService: ] job_executor_option_dict = {item.get('value'): item for item in job_executor_option} - for item in data: + for item in job_log_list: if item.get('status') == '0': item['status'] = '正常' else: @@ -138,9 +137,6 @@ class JobLogService: item['jobGroup'] = job_group_option_dict.get(str(item.get('jobGroup'))).get('label') if str(item.get('jobExecutor')) in job_executor_option_dict.keys(): item['jobExecutor'] = job_executor_option_dict.get(str(item.get('jobExecutor'))).get('label') - new_data = [ - {mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data - ] - binary_data = export_list2excel(new_data) + binary_data = ExcelUtil.export_list2excel(job_log_list, mapping_dict) return binary_data diff --git a/ruoyi-fastapi-backend/module_admin/service/job_service.py b/ruoyi-fastapi-backend/module_admin/service/job_service.py index 2d06b6f..55263c1 100644 --- a/ruoyi-fastapi-backend/module_admin/service/job_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/job_service.py @@ -8,8 +8,9 @@ from module_admin.dao.job_dao import JobDao from module_admin.entity.vo.common_vo import CrudResponseModel from module_admin.entity.vo.job_vo import DeleteJobModel, EditJobModel, JobModel, JobPageQueryModel from module_admin.service.dict_service import DictDataService -from utils.common_util import CamelCaseUtil, export_list2excel +from utils.common_util import CamelCaseUtil from utils.cron_util import CronUtil +from utils.excel_util import ExcelUtil from utils.string_util import StringUtil @@ -227,7 +228,6 @@ class JobService: 'remark': '备注', } - data = job_list job_group_list = await DictDataService.query_dict_data_list_from_cache_services( request.app.state.redis, dict_type='sys_job_group' ) @@ -241,7 +241,7 @@ class JobService: ] job_executor_option_dict = {item.get('value'): item for item in job_executor_option} - for item in data: + for item in job_list: if item.get('status') == '0': item['status'] = '正常' else: @@ -260,9 +260,6 @@ class JobService: item['concurrent'] = '允许' else: item['concurrent'] = '禁止' - new_data = [ - {mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data - ] - binary_data = export_list2excel(new_data) + binary_data = ExcelUtil.export_list2excel(job_list, mapping_dict) return binary_data diff --git a/ruoyi-fastapi-backend/module_admin/service/log_service.py b/ruoyi-fastapi-backend/module_admin/service/log_service.py index 0c80a60..0983b1a 100644 --- a/ruoyi-fastapi-backend/module_admin/service/log_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/log_service.py @@ -14,7 +14,7 @@ from module_admin.entity.vo.log_vo import ( UnlockUser, ) from module_admin.service.dict_service import DictDataService -from utils.common_util import export_list2excel +from utils.excel_util import ExcelUtil class OperationLogService: @@ -122,7 +122,6 @@ class OperationLogService: 'costTime': '消耗时间(毫秒)', } - data = operation_log_list operation_type_list = await DictDataService.query_dict_data_list_from_cache_services( request.app.state.redis, dict_type='sys_oper_type' ) @@ -131,18 +130,14 @@ class OperationLogService: ] operation_type_option_dict = {item.get('value'): item for item in operation_type_option} - for item in data: + for item in operation_log_list: if item.get('status') == 0: item['status'] = '成功' else: item['status'] = '失败' if str(item.get('businessType')) in operation_type_option_dict.keys(): item['businessType'] = operation_type_option_dict.get(str(item.get('businessType'))).get('label') - - new_data = [ - {mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data - ] - binary_data = export_list2excel(new_data) + binary_data = ExcelUtil.export_list2excel(operation_log_list, mapping_dict) return binary_data @@ -253,16 +248,11 @@ class LoginLogService: 'loginTime': '登录日期', } - data = login_log_list - - for item in data: + for item in login_log_list: if item.get('status') == '0': item['status'] = '成功' else: item['status'] = '失败' - new_data = [ - {mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data - ] - binary_data = export_list2excel(new_data) + binary_data = ExcelUtil.export_list2excel(login_log_list, mapping_dict) return binary_data diff --git a/ruoyi-fastapi-backend/module_admin/service/post_service.py b/ruoyi-fastapi-backend/module_admin/service/post_service.py index 5215539..9338a9f 100644 --- a/ruoyi-fastapi-backend/module_admin/service/post_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/post_service.py @@ -5,7 +5,8 @@ from exceptions.exception import ServiceException from module_admin.dao.post_dao import PostDao from module_admin.entity.vo.common_vo import CrudResponseModel from module_admin.entity.vo.post_vo import DeletePostModel, PostModel, PostPageQueryModel -from utils.common_util import CamelCaseUtil, export_list2excel +from utils.common_util import CamelCaseUtil +from utils.excel_util import ExcelUtil class PostService: @@ -172,16 +173,11 @@ class PostService: 'remark': '备注', } - data = post_list - - for item in data: + for item in post_list: if item.get('status') == '0': item['status'] = '正常' else: item['status'] = '停用' - new_data = [ - {mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data - ] - binary_data = export_list2excel(new_data) + binary_data = ExcelUtil.export_list2excel(post_list, mapping_dict) return binary_data diff --git a/ruoyi-fastapi-backend/module_admin/service/role_service.py b/ruoyi-fastapi-backend/module_admin/service/role_service.py index 24f9bee..4b633de 100644 --- a/ruoyi-fastapi-backend/module_admin/service/role_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/role_service.py @@ -15,7 +15,8 @@ from module_admin.entity.vo.role_vo import ( from module_admin.entity.vo.user_vo import UserInfoModel, UserRolePageQueryModel from module_admin.dao.role_dao import RoleDao from module_admin.dao.user_dao import UserDao -from utils.common_util import CamelCaseUtil, export_list2excel +from utils.common_util import CamelCaseUtil +from utils.excel_util import ExcelUtil from utils.page_util import PageResponseModel @@ -295,17 +296,12 @@ class RoleService: 'remark': '备注', } - data = role_list - - for item in data: + for item in role_list: if item.get('status') == '0': item['status'] = '正常' else: item['status'] = '停用' - new_data = [ - {mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data - ] - binary_data = export_list2excel(new_data) + binary_data = ExcelUtil.export_list2excel(role_list, mapping_dict) return binary_data diff --git a/ruoyi-fastapi-backend/module_admin/service/user_service.py b/ruoyi-fastapi-backend/module_admin/service/user_service.py index dc79430..c149b56 100644 --- a/ruoyi-fastapi-backend/module_admin/service/user_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/user_service.py @@ -31,7 +31,8 @@ from module_admin.service.config_service import ConfigService from module_admin.service.dept_service import DeptService from module_admin.service.post_service import PostService from module_admin.service.role_service import RoleService -from utils.common_util import CamelCaseUtil, export_list2excel, get_excel_template +from utils.common_util import CamelCaseUtil +from utils.excel_util import ExcelUtil from utils.page_util import PageResponseModel from utils.pwd_util import PwdUtil @@ -461,7 +462,7 @@ class UserService: header_list = ['部门编号', '登录名称', '用户名称', '用户邮箱', '手机号码', '用户性别', '帐号状态'] selector_header_list = ['用户性别', '帐号状态'] option_list = [{'用户性别': ['男', '女', '未知']}, {'帐号状态': ['正常', '停用']}] - binary_data = get_excel_template( + binary_data = ExcelUtil.get_excel_template( header_list=header_list, selector_header_list=selector_header_list, option_list=option_list ) @@ -492,9 +493,7 @@ class UserService: 'remark': '备注', } - data = user_list - - for item in data: + for item in user_list: if item.get('status') == '0': item['status'] = '正常' else: @@ -505,10 +504,7 @@ class UserService: item['sex'] = '女' else: item['sex'] = '未知' - new_data = [ - {mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data - ] - binary_data = export_list2excel(new_data) + binary_data = ExcelUtil.export_list2excel(user_list, mapping_dict) return binary_data diff --git a/ruoyi-fastapi-backend/utils/excel_util.py b/ruoyi-fastapi-backend/utils/excel_util.py new file mode 100644 index 0000000..875a41d --- /dev/null +++ b/ruoyi-fastapi-backend/utils/excel_util.py @@ -0,0 +1,104 @@ +import io +import pandas as pd +from openpyxl import Workbook +from openpyxl.styles import Alignment, PatternFill +from openpyxl.utils import get_column_letter +from openpyxl.worksheet.datavalidation import DataValidation +from typing import Dict, List + + +class ExcelUtil: + """ + Excel操作类 + """ + + @classmethod + def __mapping_list(cls, list_data: List, mapping_dict: Dict): + """ + 工具方法:将list数据中的字段名映射为对应的中文字段名 + + :param list_data: 数据列表 + :param mapping_dict: 映射字典 + :return: 映射后的数据列表 + """ + mapping_data = [{mapping_dict.get(key): item.get(key) for key in mapping_dict} for item in list_data] + + return mapping_data + + @classmethod + def export_list2excel(cls, list_data: List, mapping_dict: Dict): + """ + 工具方法:将需要导出的list数据转化为对应excel的二进制数据 + + :param list_data: 数据列表 + :param mapping_dict: 映射字典 + :return: list数据对应excel的二进制数据 + """ + mapping_data = cls.__mapping_list(list_data, mapping_dict) + df = pd.DataFrame(mapping_data) + binary_data = io.BytesIO() + df.to_excel(binary_data, index=False, engine='openpyxl') + binary_data = binary_data.getvalue() + + return binary_data + + @classmethod + def get_excel_template(cls, header_list: List, selector_header_list: List, option_list: List[Dict]): + """ + 工具方法:将需要导出的list数据转化为对应excel的二进制数据 + + :param header_list: 表头数据列表 + :param selector_header_list: 需要设置为选择器格式的表头数据列表 + :param option_list: 选择器格式的表头预设的选项列表 + :return: 模板excel的二进制数据 + """ + # 创建Excel工作簿 + wb = Workbook() + # 选择默认的活动工作表 + ws = wb.active + + # 设置表头文字 + headers = header_list + + # 设置表头背景样式为灰色,前景色为白色 + header_fill = PatternFill(start_color='ababab', end_color='ababab', fill_type='solid') + + # 将表头写入第一行 + for col_num, header in enumerate(headers, 1): + cell = ws.cell(row=1, column=col_num) + cell.value = header + cell.fill = header_fill + # 设置列宽度为16 + ws.column_dimensions[chr(64 + col_num)].width = 12 + # 设置水平居中对齐 + cell.alignment = Alignment(horizontal='center') + + # 设置选择器的预设选项 + options = option_list + + # 获取selector_header的字母索引 + for selector_header in selector_header_list: + column_selector_header_index = headers.index(selector_header) + 1 + + # 创建数据有效性规则 + header_option = [] + for option in options: + if option.get(selector_header): + header_option = option.get(selector_header) + dv = DataValidation(type='list', formula1=f'"{",".join(header_option)}"') + # 设置数据有效性规则的起始单元格和结束单元格 + dv.add( + f'{get_column_letter(column_selector_header_index)}2:{get_column_letter(column_selector_header_index)}1048576' + ) + # 添加数据有效性规则到工作表 + ws.add_data_validation(dv) + + # 保存Excel文件为字节类型的数据 + file = io.BytesIO() + wb.save(file) + file.seek(0) + + # 读取字节数据 + excel_data = file.getvalue() + + return excel_data