先放一张效果图

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

上代码

新建一个 js 文件 插入以下代码

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)
            }
        )
    })
}

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

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

调用

 <el-button 
     type="success" 
     size ="mini" 
     icon="el-icon-download"  
     @click='onDownload()'>导出
 </el-button>
// 导出
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

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

随知修行乃当务之急,然怠惰度日至今。