后端返回二进制流前端实现Excel下载(Vue2.0、Aixos)

235 阅读1分钟

前端发送请求时,需设置

responseType: 'blob'

如在封装后Axios中:

batchExportExample(params) {
    const url = '/project/case/batch/download';
    return service.post(url, params, { responseType: 'blob' });
}

【注意】aixos的响应拦截器是否对响应结果进行了处理,若进行了处理需额外的逻辑判断。 如:

// response拦截器
service.interceptors.response.use((response) => {
    removePending(response.config);
    const res = response.data;
    // 文件流形式
    const headers = response.headers;
    if (headers['content-type'] === 'application/octet-stream' || headers['content-type'] === 'application/atom+xml') {
         // 文件流形式直接返回result
        const result = {
            content: headers['content-disposition'] ? headers['content-disposition'] : '',
            file: res
        };
        return result;
    }
    if (res.code === 'A0102') {
        // Notification.error({
        //     title: langs.$t('status.error'),
        //     message: res.detail || res.msg,
        //     offset: 100
        // });
        const userData = {
            userName: null,
            displayName: null,
            userId: null,
            token: null,
            tenantId: null,
            userOwenGroup: [],
            authToken: null
        };
        store.commit('setUserData', userData);
        store.commit('clearStore');
        const url = `${ window.location.origin }/#/login`;
        window.open(url, '_self');
        return new Promise(() => {
        });
    }
    // 无权限不弹框
    if (res.code === 'A0204') {
        return Promise.reject(res.detail || res.msg);
    }
    if (res.code !== '0') {
        Notification.error({
            title: langs.$t('status.error'),
            message: res.detail || res.msg,
            offset: 100
        });
        return Promise.reject(res.detail || res.msg);
    }
    // JSON格式返回res.result
    return res.result;
}, (error) => {
    // eslint-disable-next-line no-underscore-dangle
    if (error.__CANCEL__) {
        return new Promise(() => {
        }); // 取消axios请求时不报错
    }
    if (error.code === 'ECONNABORTED' && error.message.indexOf('timeout') !== -1) {
        Notification.warning({
            title: langs.$t('messages.reqTimeoutTitle'),
            message: langs.$t('messages.reqTimeoutMes'),
            offset: 100
        });
        return Promise.reject(error);
    }
    Notification.error({
        title: langs.$t('status.error'),
        message: error,
        offset: 100
    });
    return Promise.reject(error);
});

后端返回格式为:

content: "attachment;filename=????sp1-??.xlsx;filename*=utf-8''%E5%BC%80%E5%8F%91%E5%B9%B3%E5%8F%B0sp1-%E7%94%A8%E4%BE%8B.xlsx"
file:{
  size: 3902
  type: "application/atom+xml"
  }

image.png 前端接收并下载:

this.$httpService.projectManageServece.batchExportExample(params).then((result) => {
    const fileName = `${projectName }-用例.xlsx`;
    this.downExcel(fileName, result.file);
    this.$message({
        type: 'success',
        message: `${this.$t('operationMsg.exportSuccess')}`
    });
}).then(() => {
    this.$refs.exampleTable.clearSelection();
    this.$parent.getCaseList();
});

通用下载方法:

downExcel(fileName, data) {
    const blob = new Blob([data], { type: 'application/vnd.ms-excel;charset=utf-8' });
    const fileUrl = URL.createObjectURL(blob);
    const downEle = document.createElement('a');
    const a = document.body.appendChild(downEle);
    a.setAttribute('href', fileUrl);
    a.setAttribute('download', fileName);
    a.click();
    document.body.removeChild(downEle);
    URL.revokeObjectURL(fileUrl);
},