前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >前后端分离导出Excel

前后端分离导出Excel

原创
作者头像
Wyc
修改2021-07-01 14:27:29
1.4K0
修改2021-07-01 14:27:29
举报
文章被收录于专栏:Python研发Python研发

前端React

后端Django

正常导出Excel确实很简单, 前端请求接口,接口处理数据,数据处理完按成之后自动生成Excel保存到指定目录,api把文件名称,文件路径返回给前端,前端一个a标签超链接就可以下载,然而在本地开发是可以直接下载的,但是在服务器上通过链接,直接就打开了文件流,并没有下载,这下就需要前端请求文件链接,下载数据流。

以下是实现方式

代码语言:javascript
复制
# React 前端
请求组件使用的 axios
    exportExcel = () => {
        const {startEndTime, selectedItems} = this.state
        let currentUser = JSON.parse(localStorage.getItem('userInfo'));
        const {dispatch} = this.props
        if (startEndTime.length === 2) {
        // 这块是请求后台接口自动生成Excel
            dispatch({
                type: 'GetStaticsCount/exportExcelData',
                payload: {
                    apiPath: '/wx/kpi_export/',
                    user_id:  currentUser.weights > 0? selectedItems:[currentUser.id],
                    startEndTime
                },
                // 请求成功回调返回, response 里边有  文件路径,文件名称
                callback: response => {
                // 当前封装的axios不能和请求文件流的使用同一个,所以单独写了一个
                // 这块是获取到文件路径,请求文件流
                    axios.post(response.filePath, '', {
                    
                        headers: {
                            'Content-Type': 'application/x-www-form-urlencoded', //请求的数据类型为form data格式
                        },
                        'responseType': 'blob'  //设置响应的数据类型为一个包含二进制数据的 Blob 对象,必须设置!!!
                    }).then(function (response) {
                        console.log(`数据流: ${response.data}`)
                        const blob = new Blob([response.data]);
                        const fileName = 'KPI统计.xlsx';
                        const linkNode = document.createElement('a');
                        linkNode.download = fileName; //a标签的download属性规定下载文件的名称
                        linkNode.style.display = 'none';
                        linkNode.href = URL.createObjectURL(blob); //生成一个Blob URL
                        document.body.appendChild(linkNode);
                        linkNode.click();  //模拟在按钮上的一次鼠标单击
                        URL.revokeObjectURL(linkNode.href); // 释放URL 对象
                        document.body.removeChild(linkNode);
                    }).catch(function (error) {
                        console.log(error);
                    });
                }
            })
        } else {
            message.error("请选择导出时间")
        }
    }

代码语言:javascript
复制
 # Django处理数据自动生成Excel到指定目录, 并返回文件路径和名称
 def post(self, request, *args, **kwargs):
        export_time = request.data.get('startEndTime')
        user_id = request.data.get('user_id')
        if len(user_id) == 1 and 0 in user_id:
            message_content = StatisticsMessageCount.objects.filter(
            creat_time__range=(export_time[0] + " 00:00:00", export_time[1] + " 23:59:59"))
        elif len(user_id) > 1 and 0 in user_id:
            return JsonResponse({"code": 201, "message": "导出失败,请把全部选项去除!"})
        else:
            message_content = StatisticsMessageCount.objects.filter(user_id__in=user_id,
                                                                    creat_time__range=(export_time[0] + " 00:00:00",
                                                                                       export_time[1] + " 23:59:59"))
        wb = xlwt.Workbook(encoding='utf8')
        sheet = wb.add_sheet('sheet', cell_overwrite_ok=True)
        style_heading = xlwt.easyxf("""
                font:
                    height 220;
                align:
                    vert center,
                    horiz center;
                pattern:
                    pattern solid,
                    fore-colour 0x16;
                borders:
                    left thin, 
                    right thin, 
                    top thin, 
                    bottom thin
                """)
        for i in range(0, len(message_content)):
            sheet.col(i).width = 256 * 30
            sheet.row(i).height = 20 * 80
        sheet.write(0, 0, '序号', style_heading)
        sheet.write(0, 1, '销售', style_heading)
        sheet.write(0, 2, '地区', style_heading)
        sheet.write(0, 3, 'Qustions', style_heading)
        sheet.write(0, 4, 'Answer', style_heading)
        sheet.write(0, 5, '解答人', style_heading)
        # 写入数据
        data_row = 0
        # UserTable.objects.all()这个是查询条件,可以根据自己的实际需求做调整.

        file_name = None
        for i in message_content:
            # 格式化datetime
            data_row += 1
            if len(user_id) > 1 or len(user_id) == 1 and 0 in user_id:
                file_name = "KPI统计"
            else:
                file_name = i.answerer
            sheet.write(data_row, 0, data_row)
            sheet.write(data_row, 1, i.sales)
            sheet.write(data_row, 2, i.area, )
            sheet.write(data_row, 3, i.problem)
            sheet.write(data_row, 4, i.answer)
            sheet.write(data_row, 5, i.answerer, )
        try:
            import os
            test_url = "http://127.0.0.1:8081"
            test_path = str('/medias/weekly/{}.xlsx'.format(file_name))
            ret = os.getcwd()
            print(ret)
            wb.save(os.getcwd() + pord_path)

            return JsonResponse({"code": 200,
                                 "fileName": "{}.xlsx".format(file_name),
                                 "filePath": pord_url + pord_path })
            # return HttpResponse(response)
        except Exception as e:
            print("异常: {}".format(e))
            return JsonResponse({"code": 201, "message": "导出失败,请关闭当前本地电脑打开的相同Excel重新导出!"})

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档