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());
}
}