前後端分離,導出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());
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章