前后端分离,导出CSV(隐藏表单提交)

ajax不能实现的原因

$.ajax方法的回调函数中,只能处理xml,json,script或者html类型,对返回的文件流没办法弹出对话框让用户下载

解决方案:隐藏form表单提交,同时也能携带token

因为response原因,一般请求浏览器是会处理服务器输出的response,例如生成png、文件下载等,然而ajax请求只是个“字符型”的请求,即请求的内容是以文本类型存放的。文件的下载是以二进制形式进行的,虽然可以读取到返回的response,但只是读取而已,是无法执行的,说白点就是js无法调用到浏览器的下载处理机制和程序

为什么不用a标签呢? a标签缺陷在于token无法处理,token长度决定了a标签不适合
js
主要是下面这句话

$(’’).appendTo(‘body’).submit().remove();

$("#export").click(function () {
            $("#export").click(function () {
                var url="http://localhost:8080/employee/exportCVS?startDate=2018-12-30&endDate=2018-12-31";
                $('<form method="get" action="' + url + '"></form>').appendTo('body').submit().remove();
            })
        })
@RequestMapping(value = "/export",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "导出csv格式")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startDate",value = "开始日期",required = true),
            @ApiImplicitParam(name = "endDate",value = "结束日期",required = true)
    })
    public Map<String, Object> exportCorpBetweenDate(@RequestParam(value = "startDate",required = true) Date startDate,
                                                     @RequestParam(value = "endDate",required = true) Date endDate,
                                                     HttpServletResponse response,
                                                     @RequestHeader(value = "token") String token){
        bizLogger.info(LogFormatter.format(
                LogFormatter.LogEvent.START,
                "/export",
                LogFormatter.getKV("startDate", startDate),
                LogFormatter.getKV("endDate", endDate)
        ));
        try {
            //更新token放到响应头部
            CorpStaffVO corpStaffVO = JwtUtil.check(token);
            String newToken = JwtUtil.sign(corpStaffVO);
            response.addHeader("token",newToken);

            List<CorpCountWithCreatorVO> corpCountBetweenDate = corpQueryService.getCorpCountBetweenDate(startDate,endDate);
            //写
            //写入临时文件
            File tempFile = File.createTempFile("vehicle", ".csv");
            CsvWriter csvWriter=new CsvWriter(tempFile.getCanonicalPath(),',', Charset.forName("utf-8"));
            //写入表头
            String[] heads={"id","公司id","公司名称","创建人id","创建人名称","创建时间"};
            csvWriter.writeRecord(heads);
            //写入内容
            String[] record;
            //写内容
            for(CorpCountWithCreatorVO corpCountWithCreatorVO : corpCountBetweenDate){
                csvWriter.write(corpCountWithCreatorVO.getId().toString());
                csvWriter.write(corpCountWithCreatorVO.getCorpId().toString());
                csvWriter.write(corpCountWithCreatorVO.getCorpName().toString());
                csvWriter.write(corpCountWithCreatorVO.getCreatorUserId().toString());
                csvWriter.write(corpCountWithCreatorVO.getCreatorName().toString());
                csvWriter.write(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(corpCountWithCreatorVO.getGmtCreate()));
                csvWriter.endRecord();
            }
            //关闭csvWriter流
            csvWriter.close();

            //输出
            ServletOutputStream outputStream = response.getOutputStream();
            byte[] bytes=new byte[1024];
            File fileLoad=new File(tempFile.getCanonicalPath());
            response.reset();
            response.setContentType("application/csv");
            SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMdd");
            response.setHeader("content-disposition", "attachment; filename="+simpleDateFormat.format(startDate)+"_"+simpleDateFormat.format(endDate)+".csv");
            long fileLength = fileLoad.length();
            String length1 = String.valueOf(fileLength);
            response.setHeader("Content_Length", length1);
            FileInputStream in = new java.io.FileInputStream(fileLoad);
            //将要输出的内容设置BOM标识(以 EF BB BF 开头的字节流)
            outputStream.write(new byte []{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF});
            int n;
            while ((n = in.read(bytes)) != -1) {
                outputStream.write(bytes, 0, n); //每次写入out1024字节
            }
            in.close();
            outputStream.close();
            //返回数据
            Map<String,Object> map=new HashMap<>();
            map.put("data",corpCountBetweenDate);

            return HttpResult.getSuccess(map);
        }catch (Exception e){
            bizLogger.error(LogFormatter.format(
                    LogFormatter.LogEvent.EXCEPTION,
                    "/export",
                    LogFormatter.getKV("startDate", startDate),
                    LogFormatter.getKV("endDate", endDate)
            ), e);
            return HttpResult.getFailure(HttpResultCode.SYS_ERROR.getErrCode(),HttpResultCode.SYS_ERROR.getErrMsg());
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章