将序列化后的数据导出成excel格式
# 导入依赖
import io
from openpyxl import Workbook
# 将格式化的数据导出为excel的方法
def output_excel(data):
# 创建Excel工作簿
wb = Workbook()
ws = wb.active
ws.title = "文件标题"
# 写入表头
headers = ["ID", "单个字段", "多个字段"]
ws.append(headers)
# 写入数据行
for row_data in data:
ws.append(list(row_data.values()))
# 保存为Excel文件并返回响应
output = io.BytesIO()
wb.save(output)
output.seek(0)
response = HttpResponse(output, content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=导出文件名称.xlsx'
return response
class XXXView(GenericViewSet):
# 视图类中的导出方法
@action(methods=['GET'], detail=False)
def output(self, request, *args, **kwargs):
ser = XXXSerializer(xxx, many=True)
formatted_data = []
for item in ser.data:
单个字段 = item.get('单个字段')
多个字段 = item.get('多个字段', [])
formatted_item = {
"ID": item['id'],
"单个字段": item['单个字段'],
"逗号分割多个字段": ", ".join([content for content in 多个字段]),
}
formatted_data.append(formatted_item)
# 另写一个导出方法
return output_excel(formatted_data)
读取传入的excel数据并进行处理
# 导入依赖
from openpyxl.reader.excel import load_workbook
class XXXView(GenericViewSet):
# 读取传入的excel内容信息的方法
@action(methods=['POST'], detail=False, parser_classes=[MultiPartParser])
def input(self, request, *args, **kwargs):
file = request.FILES.get('file')
if not file:
return HttpDataNotFoundResponse(msg="未提供文件", data=None)
# 读取Excel文件
try:
wb = load_workbook(filename=file, data_only=True)
ws = wb.active
except Exception as e:
return HttpDataNotFoundResponse(msg=f"读取文件失败: {str(e)}", data=None)
# 获取表头并校验
headers = ["ID", "单个字段", "多个字段"]
if [cell.value for cell in ws[1]] != headers:
return HttpDataNotFoundResponse(msg="文件格式不正确", data=None)
# 导入数据
error_rows = [] # 用于记录出错的行
with transaction.atomic(): # 整个操作在一个事务中,保证一致性
for row_index, row in enumerate(ws.iter_rows(min_row=2, values_only=True), start=2):
try:
id, 单个字段, 多个字段 = row
格式化后的多个字段 = [p.strip() for p in 多个字段.split(',')] if 多个字段 else []
# 进行后续的数据处理
pass
# 如果有错误行,则全部回滚
if error_rows:
raise Exception(error_rows)
# 如果没有错误,返回成功的结果
return HttpSuccessResponse(msg="数据导入成功", data=None)