Files
django-vue3-admin-gd/backend/utils/export_mixin.py
2025-10-08 14:46:43 +08:00

102 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import pandas as pd
from rest_framework.decorators import action
from django.http import HttpResponse
class ExportMixin:
"""
导出功能 Mixin提供数据导出为 Excel 或 CSV 的功能
"""
# 导出配置
export_fields = {} # 字段映射配置
export_filename = None # 导出文件名
@action(detail=False, methods=['get'], url_path='export')
def export_data(self, request):
"""
导出数据功能
支持通过参数控制导出字段:
- fields: 指定要导出的字段,多个字段用逗号分隔
- format: 导出格式 (excel/csv)默认excel
"""
# 获取查询集
queryset = self.filter_queryset(self.get_queryset())
# 获取导出字段配置
export_config = self.get_export_fields(request)
# 序列化数据
serializer = self.get_serializer(queryset, many=True)
data = serializer.data
# 处理数据
processed_data = self.process_export_data(data, export_config)
# 生成文件名
filename = self.export_filename or f"{self.__class__.__name__}_export"
# 根据格式返回响应
export_format = request.query_params.get('format', 'excel').lower()
if export_format == 'csv':
return self.generate_csv_response(processed_data, filename)
else:
return self.generate_excel_response(processed_data, filename)
def get_export_fields(self, request):
"""
获取导出字段配置
支持通过URL参数指定字段: ?fields=id,name,email
"""
# 优先使用请求参数中的字段
fields_param = request.query_params.get('fields')
if fields_param:
field_names = [f.strip() for f in fields_param.split(',')]
# 只返回指定字段的配置
return {field: self.export_fields.get(field, field) for field in field_names}
# 默认返回所有配置字段
return self.export_fields or {}
def process_export_data(self, data, export_config):
"""
处理导出数据,根据配置映射字段名和处理数据
"""
if not export_config:
return data
processed_data = []
for item in data:
processed_item = {}
for field_key, field_config in export_config.items():
# field_config 可以是字符串(列名)或字典(包含列名和处理函数)
if isinstance(field_config, dict):
column_name = field_config.get('name', field_key)
processor = field_config.get('processor')
value = item.get(field_key)
if processor and callable(processor):
value = processor(value, item)
processed_item[column_name] = value
else:
# 简单映射
processed_item[field_config] = item.get(field_key, '')
processed_data.append(processed_item)
return processed_data
def generate_excel_response(self, data, filename):
"""生成Excel格式响应"""
df = pd.DataFrame(data)
response = HttpResponse(
content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
)
response['Content-Disposition'] = f'attachment; filename="{filename}.xlsx"'
df.to_excel(response, index=False)
return response
def generate_csv_response(self, data, filename):
"""生成CSV格式响应"""
df = pd.DataFrame(data)
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = f'attachment; filename="{filename}.csv"'
df.to_csv(response, index=False)
return response