前端下载⽂件成功后执⾏回调的⽅法
在项⽬中经常会有下载⽂件的需求,⼤多数时候我都是⼀个a标签或者window.location.href = "";⼀⾏代码搞定,但是最近有⼀个⽂件下载需求,因为下载的⽂件有点⼤,所以速度确实慢,基本以10m+才能下载下来,所以做了⼀个进度条,然后问题来了,怎么可以监听⽂件是否下载完成,然后取消掉进度条。。。
开始折腾了半天的jquery,整不成,决定⽤原⽣ajax写,其中也⾃⼰整理了⼏种⽅法,特此记录哈
第⼀种⽅法:原⽣ajax+FileReader
$("#execlTo_btn").on("click",function(){
var itime = 0;
$(btn).attr("disabled", "disabled");
$(btn).html(`正在下载<i >${itime}</i>`);
var hurl = `yjToExel?yjjb=123`;
var xhr = new XMLHttpRequest();
xhr.open('get', hurl, true);
if (this.status === 200) {
var blob = sponse;
var reader = new FileReader;
var headerName = ResponseHeader("Content-disposition");
var fileName = decodeURIComponent(headerName).substring(20);
var a = ateElement("a");
a.download = fileName;
a.href = sult;
$("body").append(a);
a.click();
$(a).remove();
clearTimeout(downloadTimer);
$(btn).html("导出Execl");
$(btn).removeAttr("disabled");
}
}
}
xhr.send();
var downloadTimer = setInterval(() => {
$(btn).children("i").text(++itime);
}, 1000);
})
代码解析:⾸先点击下载按钮肯定先把按钮给禁⽤了,等下载完成再运⾏点击,这段代码的关键在于获取reponse的数据然后通过adAsDataURL(blob);把字节流转为base64,然后再下载下来,这样最⼤的缺点是数据量太⼤的时候,浏览器内存会爆,主要是字节流转bese64后数据字符猛增导致的
第⼆种⽅法:window.open()
var itime = 0;
$(btn).attr("disabled", "disabled");
$(btn).html(`正在下载<i >${itime}</i>`);
loadExeclBtn();
var hurl = `yjToExel?yjjb=123`;
jquery下载文件请求let net = window.open(hurl);
net.addEventListener("beforeunload", (e) => {
clearTimeout(downloadTimer);
$(btn).html("导出Execl");
$(btn).removeAttr("disabled");
});
var downloadTimer = setInterval(() => {
$(btn).children("i").text(++itime);
}, 1000);
代码解析:⾸先⼀眼看去代码是简洁很多,⽽且进⾏⼤数据量的下载也是没问题了,进⾏数据监听也是很⽅便,但是这个⽅法最⼤的问题在
于点击下载后会新打开⼀个浏览器窗⼝,给我感觉相当不好,故弃之
第三种⽅法:原⽣ajax+分页查询+递归下载pyqt还是tkinter
// exel导出按钮
//总条数
var datanum = 0;
//请求地址数组
var getUrl = [];
$("#execlTo_btn").on("click", function() {
java培训学多久getUrl = [];
var btn = this;
$.get("getYjCount", {
"yjjb": 123
}, function(data) {
if (data && data < 50000) {
if (data > 5000) {
$("#queding_btn").show();
$("#guanbi_btn").show();
$("#fileListNum").text(data);
$("#fileList_Modal").modal("show");
datanum = il(data / 5000);
let html = "";
for (var i = 0; i < datanum; i++) {
if (data - i * 5000 > 5000) {
html += `<li data-pagelist="${i}">${i*5000+1}条-${(i+1)*5000}条  <button data-ts="${i*5000+1}-${(i+1)*5000}条" id="to_execl_btn_${i}" class="btn                        } else {
html += `<li data-pagelist="${i}">${i*5000+1}条-${data}条 <button  data-ts="${i*5000+1}-${data}条" id="to_execl_btn_${i}" class="btn btn-default                        }
getUrl.push(i);
}
$("#fileList_ul").html(html);
} else {
//第三个⽅法cyx
var hurl = `yjToExel?nowpage=999&yjjb=123`;
loadToExeclData(hurl, btn, "导出Execl", "导出数据.xlsx");
}
} else {
toastr.warning("最⼤数据下载量5万!");
}
});
});
//点击确定按钮,只有在5000条以上的时候才有这个事件
$("#queding_btn").on("click", function() {
if (getUrl && getUrl.length > 0) {
$("#queding_btn").hide();
$("#queding_btn").hide();
sqlitemanger$("#guanbi_btn").hide();
var hurl = `yjToExel?nowpage=0&yjjb=123`;
loadToExeclData(hurl, ElementById("to_execl_btn_0"), "已下载", "预警导出数据(1-5000条).xlsx");
}
});
function loadToExeclData(hurl, btn, btnName, fileName){
var itime = 0;
log4j漏洞 阿里云$(btn).attr("disabled", "disabled");
$(btn).html(`正在下载<i >${itime}</i>`);
//进度条的,不贴代码了,⾃⼰可以随便写
loadExeclBtn(btn);
var xhr = new XMLHttpRequest();
xhr.open('get', hurl, true);
if (this.status === 200) {
var res = sponse;
const blob = new Blob([res], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
});
const a = ateElement('a');
a.download = fileName;
a.href = ateObjectURL(blob);
a.click();
$(a).remove();
clearTimeout(downloadTimer);
$(btn).html(btnName);
$(btn).removeAttr("disabled");
if (getUrl && getUrl.length > 0) {
getUrl.splice(0, 1);
spring修图软件
console.log(getUrl);
if (getUrl.length > 0) {
var loadBtn = ElementById(`to_execl_btn_${getUrl[0]}`);
var loadUrl = `yjToExel?nowpage=${getUrl[0]}&yjjb=123`;
console.log(loadUrl);
loadToExeclData(loadUrl, loadBtn, "已下载", `预警导出数据(${loadBtn.dataset.ts}).xlsx`);
}else{
$("#guanbi_btn").show();
}
}
}
}
xhr.send();
var downloadTimer = setInterval(() => {
$(btn).children("i").text(++itime);
}, 1000);
}
代码解析:这个⽅法是我最终使⽤的⽅法,咋⼀看,代码量虽是猛然剧增,其实是把原来的⽅法给剥离成了两个⽅法,主要的思路是⼤于5000条数据就分次查询然后递归下载,下载之后的数据直接使⽤字节流数据,可以节省很多的内存空间,下载⼤数据量的速度也有了质的提升,后端的代码也不贴了,就是⼀个分页查询,然后返回byte[]字节流,很简单

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。