项目导出excel数据的时候遇到了乱码问题,但是通过接口文档下载的文件正常,乱码截图如下:
查看后端接口响应数据,能顺利拿到数据流,所有接口没问题。
很多博主说的文件格式与响应类型对不上,要加responseType: 'blob'或者设置编码 UTF-8,我都尝试过了,依旧没有解决问题。在axios的请求拦截器中直接把响应数据打印出来看看,发现,responseType是空的,data不是blob对象而是一个字符串,这就有问题了。
正常来说,前端响应接收到应该是一个blob对象,如下图:
然后又回去看如何调导出接口,发现了一个疑点。因为这个项目用的是TDesign封装的框架,只封装了axios,但是没有封装接口,前接手的同事顺着框架的风格走,直接在页面引入axios实例发起请求,导致responseType失效。
toExport(){
const FORM_URLENCODED = 'application/x-www-form-urlencoded;charset=UTF-8';
const params = this.filterData
const url = "/sys/export";
const QSparams = Qs.stringify(params)
this.loading = true
this.$request.post(url,QSparams,{responseType:'blob',headers:{'Content-type':FORM_URLENCODED}}).then((res)=>{
if(res.code){
this.$message.error(res.message)
}else{
download(res)
}
}).finally(()=>{
this.loading = false
})
}
既然简单粗暴地调接口不行,那就封装接口再使用。
// 新建API.ts接口文件
import request from './request'
export function exportGet(url:string) {
return request({
url: url,
method: 'get',
// 在封装的接口这里加blob才有效啊!
responseType: 'blob',
});
}
修改导出方法:
<script>
import { download } from '@/utils/download';
import { exportGet } from '@/utils/API';
import Qs from 'querystring';
toExport() {
const params = this.filterData;
for (const key in params) {
if (!params[key] || (Array.isArray(params[key]) && params[key].length === 0)) {
delete params[key];
}
}
// application/x-www-form-urlencoded;charset=UTF-8 时 参数要stringify才是form-data的参数格式
const QSparams = Qs.stringify(params);
const url = '/sys/export' + '?' + QSparams;
this.loading = true;
exportGet(url)
.then((res) => {
if (res.code) {
this.$message.error(res.msg);
} else {
download(res);
}
})
.finally(() => {
this.loading = false;
});
},
</script>
导出excel方法:
export const download = (res = null) => {
if (!res.data) return
// const blob = new Blob([res.data], { type: 'application/vnd.ms-excel;charset=utf-8' })
const blob = new Blob([res.data], { type: 'application/octet-stream;charset=UTF-8' })
const contentDisposition = res.headers['content-disposition']
const patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*')
const $link = document.createElement('a')
$link.href = URL.createObjectURL(blob)
$link.download = decodeURIComponent(patt.exec(contentDisposition)[1])
$link.click()
document.body.appendChild($link)
document.body.removeChild($link) // 下载完成移除元素
window.URL.revokeObjectURL($link.href) // 释放掉blob对象
}
// 自己自定义下载的excel文件名称
export const download2 = (flow = null) => {
if (!flow) return
const blob = new Blob([flow],{type: 'application/vnd.ms-excel'})
const blobUrl = window.URL.createObjectURL(blob)
const dateTimeFormat = dayjs().format('YYYY_MM_DD_hh_mm_ss')
const fileName = `账单导出${dateTimeFormat}.xlsx`
const a = document.createElement('a')
a.style.display = 'none'
a.download = fileName // 自定义下载的文件名
a.href = blobUrl
a.click()
}
最终文件顺利导出!高清无乱码!