如何获取后台文件流,并弹出下载框?
前台:
1.模拟a标签的点击
function exportExcel(){
var a = document.createElement("a");
a.href = '/lowFareFind/exportExcel?token='+token;
a.target = '_blank'; //新的标签页
a.click(); //模拟点击并触发a标签默认行为 (使用jquery 方式click() 只会触发绑定的click函数行为,不会触发元素默认行为) ,如何触发默认行为?
}
2.通过隐藏iframe
<iframe id="iframeFile" style="display:none"></iframe>
function exportExcel(){
document.getElementById('iframeFile').src = '/lowFareFind/exportExcel?token='+token;
}
注意 :需要设置X-Frame-Options HTTP响应头 值为 SAMEORIGIN , 默认为DENY (会拒绝引入资源到iframe中)
(Refused to display 'your url...' in a frame because it set 'X-Frame-Options' to 'DENY'.)
3.XMLHttpRequest Level 2 + iframe
XMLHttpRequest 2 支持了对流的获取操作,得到blob对象,使用URL.createObjectURL 获得对象URL
<iframe id="iframeFile" style="display:none"></iframe>
function exportExcel(){
var oReq = new XMLHttpRequest();
var url = '/lowFareFind/exportExcel?token='+token;
oReq.open('get',url,true);
oReq.responseType = 'blob';
oReq.onload = function(e){
if(oReq.status == 200)
var blob = oReq.response;
document.getElementById('iframeFile').src = window.URL.createObjectURL(blob);
console.log(blob);
};
oReq.send();
}
后台
从redis中提取数据对象list,包装数据为Workbook对象并返回文件流
@RequestMapping("/exportExcel")
public void exportExcel(@RequestParam("token") String token,HttpServletResponse response){
try {
String jsonStr = (String) redisTemplate.opsForHash().get(token, "ticketList");
List<LowFareFindTicketVO> list = JSON.parseArray(jsonStr, LowFareFindTicketVO.class);
Workbook workbook = lowFareFindExcelService.writeExcelFile(list);
String fileName = IdGenerator.getTimestamp()+ "_比较后结果.xlsx";
fileName = URLEncoder.encode(fileName,"utf-8");
response.setHeader("Content-disposition","attachment; filename=" + fileName);
response.setHeader("X-Frame-Options", "SAMEORIGIN");
response.setContentType("application/msexcel");
ServletOutputStream servletOut = response.getOutputStream();
workbook.write(servletOut);
} catch (Exception e){
logger.error("#",e);
}
}
HTTP头 - response响应头属性设置
ContentType : 设置MIME类型 MIME类型解释
X-Frame-Options : 给浏览器指示允许一个页面可否在 <frame>
, <iframe>
或者 <object>
中展现的标记 ,网站可以使用此功能,来确保自己网站的内容没有被嵌到别人的网站中去,也从而避免了点击劫持 (clickjacking) 的攻击。 X-Frame-Options
Content-disposition : 消息头指示回复的内容该以何种形式展示,是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地。 Content-Dispostion
参考 MDN WEB DOCS