大部分前端开发人员在做项目的过程中应该都遇到过这个问题:
在前端点击一个导出或者下载的按钮,从后端导出包含列表中的数据的excel文件。
那么如何实现呢?
方法一:
如果项目中没有涉及要要权限验证的问题,可以直接让后端返回你一个下载文件的地址,然后前端直接访问该地址就可下载文件到本地。
比如:
window.location.href = url
这个方法一般是不会用的,因为正常点的项目基本都会涉及到token验证等问题,你直接访问下载链接是会被拒绝的。
当然你也可以选择将token直接带在url后面的方式提供权限验证,但是这种方式仍然不推荐。
方法二:
让后端通过接口把文件流的数据返回给前端,前端再模拟一个下载的动作,进行文件数据的转换并且下载到本地。
这里着重讨论的是,通过blob的数据格式,利用createObjectURL方法,将blob对象创建成blob URL,然后模拟点击下载。
例如:
exportFile(params).then(res => {
// 直接返回来就是blob数据
if (res) {
const xlsx = 'application/vnd.ms-excel'
const blob = new Blob([res], { type: xlsx })
const a = document.createElement('a') // 转换完成,创建一个a标签用于下载
a.download = 'fileName.xls'
a.href = window.URL.createObjectURL(blob)
a.click()
a.remove()
} else {
this.$message.error('导出失败')
}
exportFile调用的是后端接口,直接将返回的文件数据转成Blob。注意:这里需要指明下载的文件类型,excel对应的是:'application/vnd.ms-excel'。
a.download = 'fileName.xls' 指定下载文件的名称,包含后缀名,如果后端的excel是xls格式,那前端也必须是xsl格式,否则下载后打开文件会报错。如果是xslx格式则修改为对应的xlsx格式,必须对应。
接口方法:
export function exportFile (params) {
return axios({
url: httpUrlFormat('/api/v1/file/export', baseUrl),
method: 'get',
params: params,
header: {
headers: { 'Content-Type': 'application/x-download' }
},
responseType: 'blob'
})
}
这里:
声明headers中的Content-Type为 application/x-download
声明responseType 为blob
欢迎留言补充。