发布于 

vue 配合后台实现 wd 文件导出功能

开始

vue 框架中,与传统的根据路径下载文件 document.getElementById("").src='' 方式不同,有时候,我们会需要将上传的文件在后台直接进行处理再回传到前端,这种情况下文件没有实际的可获取的路径,无法通过链接方式下载。但是可以通过将其转成blob对象,添加到 iframe 标签中来模拟下载(或者pdf预览)。具体的接收方式如下:

效果图

代码

新建 fileDownload.js 插入以下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import axios from 'axios'

/**
* 封装导出Excel文件请求
* @param url
* @param data
* @returns {Promise}
*/
export function exportExcel(url,params) {
return new Promise((resolve, reject) => {
axios({
method: 'post',
url: url, // 请求地址
data: params, // 参数
responseType: 'blob' // 表明返回服务器返回的数据类型
}).then( response => {
console.log(response);
resolve(response.data)
let blob = new Blob([response.data], {
type: 'application/vnd.ms-excel'
})
// 获取响应头里的 filename
let fileName = response.headers['content-disposition'].split(";")[1].split("filename=")[1];
fileName = decodeURI(fileName); // 解码
if (window.navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(blob, fileName)
} else { // 非 ie下载
var link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
link.download = fileName
link.click()
//释放内存
window.URL.revokeObjectURL(link.href)
}
},
err => {
reject(err)
}
)
})
}

在需要的组件中引用上面的 fileDownload.js

1
import { exportExcel } from '@/utils/fileDownload';

调用

1
2
3
4
5
6
<el-button
type="success"
size ="mini"
icon="el-icon-download"
@click='onDownload()'>导出
</el-button>
1
2
3
4
5
6
 // 导出
onDownload(){
let url = '/roof/api/driving/queryDataExcel' // 请求接口
let params = {} // 参数
exportExcel(url, params)
}

问题笔记

vue axios 设置 responseType: 'blob' 无效

mock模块会影响原生的ajax请求,使得服务器返回的blob类型变成乱码

去除 mock 后

后台通过响应头返回的文件名导致前台获取导致乱码

F12 查看响应头没问题

但是 console.log() 打印后却出现乱码

最终无解,只能另辟蹊径

让后端使用 URLEncoder.encode(fileName, "UTF8") 对文件名进行编码处理!!一堆百分号那种东西!!直接返回给前端

前端则使用 decodeURI(fileName) 进行解码,效果图看 gif

1
2
3
// 获取响应头里的 filename
let fileName = response.headers['content-disposition'].split(";")[1].split("filename=")[1];
fileName = decodeURI(fileName); // 解码

总结完毕!