前端菜鸟一个.
刚开始就 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);
- })
- });
- }
只做记录使用, 如有帮助, 谢谢观看, 如有不对, 谢谢指教.
来源: https://www.cnblogs.com/sweetbullet/p/9843178.html