ajax请求下载excel
ajax请求下载excel,数据流的误区
最近项目有个需求是根据条件进行下载excel,而且要无刷新请求下载excel,本来想的很简单,点击按钮直接用post方式传递到后台,后台返回响应数据流生成excel完成下载,我这里用的是谷歌和火狐浏览器,最后都可以下载,但是火狐浏览器的画面中有些控件的样式改变了,于是开始了两天的挣扎。。。。。
前端是jquery,后台是php的symfony框架
在这里申明一下,不考虑画面样式的直接可以用form中的post方式实现
前台代码
var form=$("<form>");//定义一个form表单
form.attr("style","display:none");
form.attr("target","");
form.attr("method","post");
form.attr("action","{{path('tquick_common_download_calls')}}");
$("body").append(form);//将表单放置在web中
form.append(inputs);//定义的input数据
form.submit();//表单提交
form.remove()
后台核心代码
‘$baseLogic->writeTempFile 是生成excel文件并返回文件路径
// ‘$baseLogic->writeTempFile 是生成excel文件并返回文件路径
$filePath = $baseLogic->writeTempFile($this->get('phpexcel'), $headInfoAndDatas);
$response = new BinaryFileResponse($filePath);
$response->headers->set('Content-Type', 'text/vnd.ms-excel; charset=utf-8');
$response->setContentDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT, date("YmdHis") . $entity . '.xlsx'
);
return $response;
这样直接就可以完成下载了,不得不说symfony框架还是蛮方便的
谷歌浏览器正常下载,火狐浏览器的样式变了,页面还是刷新
最后只能用ajax,一开始选择用post方式直接,想通过获取数据流进行转换,最后发现根本实现不了,原因是返回来的数据全是乱码,网上很多种方法说重新定义一个a标签链接至数据流的地方,当我把前后台的字符集调试成一样时能够生成excel,但是无法打开。
最后还是用了一个笨但是实用的方法
用ajax的post方式生成临时文件,然后用get方式下载临时文件
这样总算搞定了
$.ajax({
cache: false,
type: "POST",
url: createExcelUrl,
data: data,
success: function(data, status, response){
//创建一个a标签
var oReq = new XMLHttpRequest();
oReq.open("GET", getExcelUrl, true);
oReq.responseType = "blob";
oReq.onload = function (oEvent) {
var content = oReq.response;
var elink = document.createElement('a');
var fileName = oReq.getResponseHeader("Content-Disposition").split(";") [1].split("filename=")[1];//文件名
ileName = fileName.substr(1,fileName.length-2);
elink.download = fileName;
elink.style.display = 'none';
var blob = new Blob([content]);
elink.href = URL.createObjectURL(blob);
document.body.appendChild(elink);
elink.click();
document.body.removeChild(elink);
};
oReq.send();
layer.closeAll("loading");
},
error: function(){
layer.closeAll("loading");
alert("下载失败");
}
});
后台
post生成临时文件的代码就不贴了,根据自己的业务来就行,主要是记录文件路径
//get 方式直接下载
if (file_exists($savePath)) {
$response = new BinaryFileResponse($savePath);
$response->headers->set('Content-Type', 'application/zip');
$response->setContentDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT, date("YmdHis") . $flag . ".zip");
return $response;
}
return $this->rawResponse(ErrorMessage::FILE_NOT_EXISTS);
好了,结束。
[1]: http://meta.math.stackexchange.com/questions/5020/mathjax-basic-tutorial-and-quick-reference
[2]: https://mermaidjs.github.io/
[3]: https://mermaidjs.github.io/
[4]: http://adrai.github.io/flowchart.js/