前端菜鸟一个.
刚开始就ajax POST请求接口下载Excel, 但是状态为200, 也不下载文档,也不报错, 换了好几种方式才知道ajax因为response流的原因不可以下载文档.
后参考了https://www.jb51.net/article/122797.htm ,实现了功能 //冷汗
特此记录一下代码
这是js写的方式
utils.downLoadFile(url,参数,名称)
//这是写的service中的工具类, js中可以直接function downLoadFile(){...}
downLoadFile: function (url, params, filName) { //随机生成10位随机数追加在Excel名称后面 var randomNumber = String(Math.random()).substring(2,12) var xhr = new XMLHttpRequest(); xhr.open('POST', url, true); // 也可以使用POST方式,根据接口 /** * 关于Blob 如何获取内容 * https://developer.mozilla.org/zh-CN/docs/Web/API/Blob * reader.result 包含转化为类型数组的blob */ xhr.responseType = "blob"; // 返回类型blob xhr.open('post', url, true); xhr.setRequestHeader("Content-Type", "application/json"); // 定义请求完成的处理函数,请求前也可以增加加载框/禁用下载按钮逻辑 xhr.onload = function () { // 请求完成 if (this.status === 200) { // 返回200 var blob = this.response; var reader = new FileReader(); reader.readAsDataURL(blob); // 转换为base64,可以直接放入a标签href reader.onload = function (e) { // 转换完成,创建一个a标签用于下载 var a = document.createElement('a'); a.download = filName+randomNumber+'.xlsx'; a.href = e.target.result; $("body").append(a); // 修复firefox中无法触发click a.click(); $(a).remove(); } } }; //以json格式为参数发送ajax请求 xhr.send(JSON.stringify(params)); }
这种方式在ts中写的
//下载excel文件 downLoadFile(url: any, data: any, fileName: any) { let other=this; // other.messageService.error("ssskkk") return new Promise((resolve, reject) => { let that = this, options: any = {}, loginInfo = UserInfo.loginInfo; let tenatInfo = AppCommon.currentTenant || ""; this.httpClient.post(url, data, { headers: new HttpHeaders().set('current_tenant', tenatInfo.tenantId) .set('current_app', AppCommon.currentAppcode || null), responseType: 'blob', observe: 'response' }).subscribe(res => { // console.log(res); // var resHeaders = res.headers.toJSON() || {}; // //console.log(resHeaders); /** * 关于Blob 如何获取内容 * https://developer.mozilla.org/zh-CN/docs/Web/API/Blob * reader.result 包含转化为类型数组的blob */ var reader = new FileReader(); reader.readAsText(res.body, 'utf-8'); // reader.readAsArrayBuffer(res.body); reader.addEventListener("loadend", () => { let toJson; try { /** * 尝试将接口返回的数据转换成json格式 * 接口正常情况下返回的数据流的形式,转成json数据肯定会报错。 * catch捕获后执行文件下载。 * * 假如能够顺利转成json,说明接口是报错状态,返回的是错误数据 */ toJson = JSON.parse(reader.result) } catch (error) { /* * 获取reseponse headers中的 文件名 */ // console.log("ssss"); // alert("ssssssssssss"); let disposition = res.headers.get('content-disposition'); let status_code=res.headers.get('status_code'); // console.log(status_code); // let resHeaders = res.headers.toJSON() || {}; if(status_code=="11060"){ // if(status_code==null){ // console.log("ksjk"); // that.messageService.error("ssssssssssss"); //报错 let status_msgs = res.headers.get('status_msg') ||res.headers.get('Status_msg')|| []; let status_msg = status_msgs[0] || ""; let base64 = new Base64(); status_msg = base64.decode(status_msg) || "服务异常"; resolve({ error_msg: "数据量过大,不能正常导出,请缩小查询范围" }) return; } let newfileName = ''; if (disposition) { newfileName = decodeURI(disposition.split('=')[1]); //newfileName=newfileName.substring(0,fileName.length); fileName = newfileName; } this.downFile(res.body, fileName); // resolve(); return null; } //报错 reject(toJson.msg); }); }, err => { reject(err.msg); }) }); }
只做记录使用,如有帮助,谢谢观看,如有不对,谢谢指教.