这段代码演示了如何通过JavaScript的axios库异步获取HTTP资源,以blob形式处理响应数据,
创建一个可供下载的Word文档(客流日报.docx)。它设置特定的请求头,传递日期参数,并监听下载完成以释放内存中的URL对象。
const wordExportTwo = async () => { try { const response = await axios.get('http://192.168.0.108:8080/Word/Report/Export', { responseType: 'blob', headers: { Accept: 'application/json', }, params: { date: choiceYesterdayDate, }, }); const fileName = '客流日报.docx'; // 替换为实际的文件名 const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=utf-8', }); const url = window.URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.setAttribute('download', fileName); document.body.appendChild(link); // 触发点击事件开始下载 link.click(); // 下载完成后释放 URL 对象 link.addEventListener('click', () => { setTimeout(() => { window.URL.revokeObjectURL(url); document.body.removeChild(link); }, 100); }, { once: true }); } catch (error) { console.error('导出失败:', error); } };
VUE 描述"application/x-www-form-urlencoded"传值问题
var qs = require('qs') let param = { 'ids':id }; let token = window.localStorage.getItem("token"); axios .post(api.purchase, qs.stringify(param), { headers: { "Content-Type": "application/x-www-form-urlencoded", Authorization: token } }) .then(res => { console.log(res.data); // Toast("程序异常,请稍后再试"); }); },
例2:
<template> <div class="content-box"> <div class="container"> <div>。。。</div> </div> </div> </template> <script> import { exportProjectStandard } from '@/api/brand/standard' export default { props: {}, data() { return {} }, methods: { gotoExport(row){ // console.log(row); try { // window.location.href = `${ process.env.VUE_APP_BASE_BRAND_API }/v1/inspectionstandard/exportProject?id=${row.id}&standardName=${row.title}` // window.open(`${ process.env.VUE_APP_BASE_BRAND_API }/v1/inspectionstandard/exportProject?id=${row.id}&standardName=${row.title}`) // this.$message.success('数据导出中,请稍等') // 调接口文件流形式 let parmas = { id: row.id, standardName: row.title } exportProjectStandard(parmas).then(res => { console.log(res); // 因为后端直接返回的就是blob数据流格式 // if (res.code == 200) { const content = res; const blob = new Blob([content]) const fileName = row.title + '.xls'; //自定义下载文件的名字 if ('download' in document.createElement('a')) { // 非IE下载 const elink = document.createElement('a'); elink.download = fileName; elink.style.display = 'none'; elink.href = URL.createObjectURL(blob); document.body.appendChild(elink); elink.click(); URL.revokeObjectURL(elink.href); // 释放URL 对象 document.body.removeChild(elink); } else { // IE10+下载 navigator.msSaveBlob(blob, fileName); } // } }).catch((error) => { this.$message.error('导出异常,请稍后重试') console.log(error.response) //可获取错误的返回信息 if (error.response.status == 400) {} }).finally(() => {}) } catch (error) { this.$message.error('导出失败') } } } } </script> <style lang="scss" scoped> </style>
前端文件下载的几种方式
后端直接给文件url,
这种情况很简单,直接将url付给a标签,a标签加上download属性即可
后端返回的是文件流,但是请求是get请求
此种情况下,要获取文件原始文件名,也简单。一种是使用window.open(url),一种是直接将请求地址给a标签
后端由于需要,只能使用post请求(比如下载文件时需要携带过多的参数),使用这种方式获取下载文件的原始文件名,比之前两种麻烦些,本文重点说的是这种情况
思路如下:
1) 使用ajax发起请求,指定接收类型为blob
2)读取请求返回的头部信息里的content-disposition,返回的文件名就在这里面
3)使用URL.createObjectURL将请求的blob数据转为可下载的url地址
4)使用a标签下载
export const downloadFile = (url,data)=>{ function down(fileUrl,fileName){ fileName=decodeURIComponent(fileName) let a=document.createElement('a') a.setAttribute('href',fileUrl) a.setAttribute('download',fileName) document.body.appendChild(a) a.click() document.body.removeChild(a) } axios({ url, data, responseType:'blob', method:'POST', }).then(res=>{ let data=res.data let dis= res.headers['content-disposition'] let url=URL.createObjectURL(data) let fileName=dis.split('attachment;filename=')[1] down(url,fileName) })
需要说明的是,content-disposition 取值是res.headers[‘content-disposition’],res.headers[‘content-disposition’] 的值是如下类型字符串 attachment;filename=xxx.xlsx,需要自己切分。另外,如果文件名是中文,则需要后端配合转码,后端在发送文件时,组要将文件名进行java.net.URLEncoder.encode(fileName, “UTF8”) 转码,否则前端接收到的 res.headers[‘content-disposition’] 的中文信息是乱码的。后端转码后,前端通过decodeURIComponent 解码即可
==========================================================
vue实现导出二进制流(blob)文件(get请求)
说明:该导出主要是基于后端做的,前端拿到二进制blob文件流
方法一:导出后直接打开的是表格
handleExport() { let _this = this; if (_this.exportIds.length == 0) { return _this.$message.info("暂无选择要导出的数据"); } axios.get("https://********/****/export.do", { params: { ids: _this.exportIds.join(","), _t: new Date().getTime() }, responseType: "blob" // 1.首先设置responseType对象格式为 blob: }).then(res => { //resolve(res) // 2.获取请求返回的response对象中的blob 设置文件类型,这里以excel为例 let blob = new Blob([res.data], { type: "application/vnd.ms-excel" }); // 3.创建一个临时的url指向blob对象 let url = window.URL.createObjectURL(blob); // 4.创建url之后可以模拟对此文件对象的一系列操作,例如:预览、下载 let a = document.createElement("a"); a.href = url; a.download = "导出数据_" + new Date().getTime() + ".xlsx"; //自定义导出文件名 a.click(); // 5.释放这个临时的对象url window.URL.revokeObjectURL(url); return _this.$message.success("导出成功"); }, err => { resolve(err.response); } ).catch(error => { reject(error); }); }
方法二:导出后需要用excel 打开
handleExport() { let _this = this; if (_this.exportIds.length == 0) { return _this.$message.info("暂无选择要导出的数据"); } axios({ method: 'get', url: 'https://******e/export.do', responseType: 'blob', params: { ids: _this.exportIds.join(","), _t: new Date().getTime() } }).then((res) => { if (res.code != 0) { _this.loading = false; return _this.$message.error(res.msg); } let blob = new Blob([res.data], { type: 'application/vnd.ms-excel', }); let link = document.createElement('a') let body = document.querySelector('body') link.href = window.URL.createObjectURL(blob) // link.style.display = 'none' // 让这个a标签不可见 link.download = '导出文件' //文件名称 body.appendChild(link) link.click() // 创建了新的a标签之后模拟点击事件,开始传输文件 body.removeChild(link) // 下载完成之后,移除按钮,垃圾回收,减少页面内存消耗 window.URL.revokeObjectURL(link.href) // 移除之前使用createObjectURL创建的URL,垃圾回 return _this.$message.success("导出成功"); }); }
方法三: 兼容IE和谷歌、火狐浏览器
//导出兼容ie浏览器 handleExport() { let _this = this; if (_this.exportIds.length == 0) { return _this.$message.info("请选择要导出的数据!"); } axios({ url: "8888888", method: "get", responseType: 'blob', //文件流数据一定要写 params: { ids: _this.exportIds.join(","), _t: new Date().getTime() }, }).then(res => { const blob = new Blob([res.data]); //处理文档流 const fileName = '发票管理.xlsx'; //导出后的文件名 if (!!window.ActiveXObject || "ActiveXObject" in window || window.navigator.userAgent .indexOf('Edge/') > 0) { //判断是不是ie的浏览器 window.navigator.msSaveOrOpenBlob(blob, fileName); console.log('ieeeeee') } else { const elink = document.createElement('a'); elink.download = fileName; elink.style.display = 'none'; elink.href = URL.createObjectURL(blob); document.body.appendChild(elink); elink.click(); URL.revokeObjectURL(elink.href); // 释放URL 对象 document.body.removeChild(elink); console.log('noieeeee') } }).catch(err => { console.log(err) }) }