前端下载 excel 文件流【方法1】
业务需求
将后端接口返回的excel文件流进行下载
【方法1】
1.代码实现
- 封装将二进制的数据导出为 excel 的方法
@/utils/exportExcel.js
/** * 将二进制的数据导出为 excel * @param {string} data 数据 * @param contentType * @param {string} fileName 文件名称 */ export function exportResponseData(data, contentType, fileName) { const downloadLink = window.document.createElement('a') downloadLink.href = window.URL.createObjectURL(new Blob([data], { type: contentType })) downloadLink.download = fileName document.body.appendChild(downloadLink) downloadLink.click() document.body.removeChild(downloadLink) }
- 封装导出二进制文件请求
@/utils/request.js
import axios from 'axios' import { getToken, removeToken } from '@/utils/auth' import dayjs from 'dayjs' import { exportResponseData } from './exportExcel' // 【主要代码】 let apiHost = require('../setting/api-host').apiHost // create an axios instance const service = axios.create({ baseURL: apiHost, // api 的 base_url timeout: 300000 // request timeout }) let loadingInstance // request 请求 拦截器 service.interceptors.request.use(config => { if (config.responseType === 'blob') { config.headers['responseType'] ='blob' } loadingInstance = Loading.service({ text: '加载中...', background: 'rgba(0, 0, 0, 0.5)', }) config.headers['X-Token'] = getToken() return config }, error => { // Do something with request error // console.log(error) // for debug Promise.reject(error) }) // respone 响应 拦截器 service.interceptors.response.use( response => { /** * 判断是否为excel文件【主要代码】 */ if (response.config.isExportExcel) { const data = response.data const contentType = response.headers['content-type'] let fileName if (response.headers['content-disposition']) { fileName = decodeURI( response.headers['content-disposition'].match(/filename=(.*)/)[1] ) } else { fileName = dayjs().format('YYYYMMDD') } exportResponseData(data, contentType, fileName) loadingInstance.close() return } /** * code为非20000是抛错 可结合自己业务进行修改 */ loadingInstance.close() return response.data }, error => { loadingInstance.close() ... } ) /** * 导出 excel 数据【主要代码】 */ export const exportExcel = config => { return service({ method: 'post', isExportExcel: true, responseType: 'blob', ...config }) } export default service
- 封装接口请求
@/api/api.js
import request, { exportExcel } from '@/utils/request' // 导出接口 export function exportList(data) { return exportExcel({ url: '...', data }) }
- 调用接口进行excel文件下载
import { exportList } from '@/api/api.js' methods: { exportHandelr(){ let params = { ... } exportList(params).then(res=>{ console.log('导出成功') }) } }
2.页面展示
-
点击“结果导出”按钮
-
后端接口返回文件流
-
弹出另存文件选择路径,进行下载
【方法2】
let url = '/api/XXXXX?' // 后端处理导出 - 返回文件流的导出接口
for (let i in this.defaultData) {
if (this.defaultData[i]) {
if (i !== 'page' && i !== 'rows' && i !== 'time') {
url += i + '=' + this.defaultData[i] + '&' // 接口请求地址拼接一些查询参数
}
}
}
url += `cdt-token=${getToken()}`
window.open(url)
【补充】下载
1.根据接口返回服务器文件路径下载文件
// 下载文件
downloadFile(val) {
const url = '服务器文件地址前缀' + val.wjlj // 文件路径
const downloadLink = window.document.createElement('a')
downloadLink.href = url
downloadLink.download = val.wjmc
document.body.appendChild(downloadLink)
downloadLink.click()
document.body.removeChild(downloadLink)
},
2.将页面转为图片下载下来
handleDownload() {
this.downloadLoading = true;
html2canvas(this.$refs.downLoad).then((canvas) => {
const imgUrl = canvas.toDataURL('image/png')
console.log('imgUrl----',imgUrl)
let image = document.createElement('img')
image.src = imgUrl
let a = document.createElement('a')
a.href = imgUrl
a.download = this.title
a.click()
a = null
image = null
}).finally(()=>{
this.downloadLoading = false;
});
},
3.下载文件的两种方法
// 操作栏
operationHandleDialog(type, data) {
if (type === 'editDialog') {
this.$refs.EditDialogRef.open(type, data)
} else if (type === 'download') {
// 【下载文件-方法1】当前页直接下载(不会打开新窗口闪一下,直接下载)
const downloadLink = window.document.createElement('a') // 创建一个 a 标签
let suffix = data.mblj.split('.') // 将文件路径通过 . 分隔转为数组
suffix = suffix[suffix.length - 1] // 取出文件名
// downloadLink.href = `${this.sysConfigData.mon_oss_filepath +
// data.mblj}?Download=true&fileName=${data.bmbt}.${suffix}` // 多了一个文件类型(不需要)
downloadLink.href = `${this.sysConfigData.mon_oss_filepath +
data.mblj}?Download=true&fileName=${data.bmbt}` // 拼接 a 链接的 href 地址
document.body.appendChild(downloadLink) // 将 a 标签添加到 body 中
downloadLink.click() // a 标签触发点击事件
document.body.removeChild(downloadLink) // 将 a 标签移除
// 【下载文件-方法2】打开新窗口下载文件(但是不会出现选择文件路径弹框,默认下载到浏览器下载文件位置)(打开新窗口下载文件只是闪一下新窗口,立即又关闭了,不好)
// window.open(
// `${this.sysConfigData.mon_oss_filepath + data.mblj}?Download=true&fileName=${data.bmbt}`
// )
}
}