导出excel,并将数据返回给前端(包含权限判断)
一.先写导出按钮接口
1.此接口对用户权限进行判断
2.此接口将前端的参数组合拼凑到下一个接口的url中去,用于条件筛选
3.用户有权限的情况下将用户的权限信息保存到redis中去,并将token写到url的参数中,以便对用户下载时权限的验证
class ExportInfoButtonView(APIView): permission_classes = [SupserPermisson,] def get(self, request,pk): res = {'error':'','success':''} cinema_obj = Cinema.objects.filter(cinema_code=pk) if not cinema_obj: res['error'] = '信息不存在' return JsonResponse(data=res, code=400, desc="success", status=status.HTTP_400_BAD_REQUEST) params_dic=dict(request.query_params) del_keys=[] for i in params_dic: if params_dic[i][0] == '': del_keys.append(i) else: params_dic[i] = params_dic[i][0] if del_keys: for key in del_keys: params_dic.pop(key) params_dic['token'] = make_token(request.user.username) params = urlencode(params_dic,encoding='utf8') data = {} data['url'] = '127.0.0.1:8000/test/export_info_excel/{0}?{1}'.format(pk,params) res['success'] = data return JsonResponse(data=res, code=200, desc="success", status=status.HTTP_200_OK)
1.1 说明:创建token 和验证token的函数
import time import hashlib import redis from ticket_audit import settings_sample redis_obj = redis.Redis(host=settings_sample.REDIS_HOST, port=settings_sample.REDIS_PORT) def make_token(user): #创建token的函数 返回一个有过期时间的token ti=str(time.time()) md5_obj = hashlib.md5(ti.encode('utf8')) md5_obj.update(user.encode('utf8')) token=md5_obj.hexdigest() print(token) redis_obj.set(token,'1',ex=20) return token def check_token(token): #token 验证函数,验证带过来的token是否在redis中存在 print(redis_obj.get(token),'这是题啃=======') if redis_obj.get(token): return True return False
二.下载接口
class ExportCinemaMovieExcelView(GenericAPIView): serializer_class = InfoSerializers queryset = Info.objects.all() filter_backends = (DjangoFilterBackend,) filter_class = InofFilter def get(self, request, pk): res = {'error': '', 'success': {}} token = request.query_params.get('token', None)
#验证用户token if not token or not check_token(token): res['error'] = '用户没有权限' return JsonResponse(data=res, code=401, desc="success", status=status.HTTP_401_UNAUTHORIZED) info_obj = Info.objects.filter(code=pk) if not cinfo_obj: res['error'] = '不存在' return JsonResponse(data=res, code=400, desc="success", status=status.HTTP_400_BAD_REQUEST) dic,_ = info_data_to_dict(pk, report_data, data1, data2) #获取到数据之后 将数据写入到excel中去 name,file_name = export_cinema_movie_excel(dic)
#读取刚刚写好的excel文件 并将文件返回给前端 with open(name, 'rb') as model_excel: result = model_excel.read() response = HttpResponse(result) response['Content-Disposition'] = 'attachment; filename=%s'%file_name os.remove(name) return response
2.1函数export_cinema_movie_excel
from io import BytesIO,StringIO import datetime # 定义时间标志变量 import xlwt as xlwt from django.http import HttpResponse def expor_info_excel(result): sheet_time = datetime.datetime.now() sheet_mark = sheet_time.strftime('%Y-%m-%d') book_mark = sheet_time.strftime('%Y%m%d') # 查询数据结果和字段名字 赋值给两个变量 result = result #查询的数据信息 fields = ['a','b','c','d','e','f','试试人数','生物偏差','城市偏差'] # 查询到的标题描述信息 response = HttpResponse(content_type='application/vnd.ms-excel') # 指定返回为excel文件 response['Content-Disposition'] = 'attachment;filename=cinema_movie_%s.xls' %book_mark # 指定返回文件名 wb = xlwt.Workbook(encoding='utf-8') # 设定编码类型为utf8 sheet = wb.add_sheet(sheet_mark) # excel里添加类别 for field in range(0,len(fields)): sheet.write(0,field,fields[field]) #数据坐标0,0 ~ row,col row取决于:result的行数;col取决于fields的总数 # for row in range(1,len(result)+1): row = 1 j = 1 while row <= len(result): for i in result: sheet.write(row, 0, j) sheet.write(row, 1, i) sheet.write(row, 2, result[i].get('num_a',None)) sheet.write(row, 3, result[i].get('num_b',None)) sheet.write(row, 4, result[i].get('report_c',None)) sheet.write(row, 5, result[i].get('num_d',None)) sheet.write(row, 6, result[i].get('num_r',None)) sheet.write(row, 7, result[i].get('report_f',None)) sheet.write(row, 8, result[i].get('report_g',None)) row += 1 j += 1 import os name=os.getcwd()+'/temp/cinema_movie_%s.xls'%book_mark fields_name = 'cinema_movie_%s.xls'%book_mark wb.save(name)#将数据写入到这个地址的这个xls文件中 return name, fields_name