关于文件导出有2中方法,一种是后端写接口,前端调用,一种是纯前端做,下面分别介绍这两种方法。

一、后端做下载/导出功能,前端调接口

注意:需要指定服务器响应的数据类型 —> responseType: 'blob'

// 导出/下载
import request from './request';
export default {
  exportData(params) {
    return request.post('/export', params, {
      responseType: 'blob'
    });
  },
}

    注意:request.js文件里需要判断响应数据中 config.responseType 的类型

import axios from 'axios';
import Vue from 'vue';
import store from '@/store/index'

// 取消请求(用于当没有 token 时,取消当前的请求,直到获取 token)
const CancelToken = axios.CancelToken;
const source = CancelToken.source();

// 过滤掉空字符串
function filterEmptyKey(params) {
  Object.keys(params).forEach(key => {
    if (
    	params[key] === null ||
    	params[key] === '' || 
    	params[key] === 'null' || 
    	params[key] === undefined
    ) {
      delete params[key];
    }
  });
}

// 环境的切换
let baseURL = null
if (process.env.NODE_ENV === 'development') {
  baseURL = 'http://localhost:8080';
} else if (process.env.NODE_ENV === 'debug') {
  baseURL = '';
} else if (process.env.NODE_ENV === 'production') {
  baseURL = 'http://bandu.com';
}

const service = axios.create({
  baseURL: baseURL,
  timeout: 30000,
  cancelToken: source.token
});

// 请求拦截
service.interceptors.request.use(
  (config) => {
    // 每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,
    // 不用每次请求都手动添加了
    // 即使本地存在token,也有可能token是过期的,所以在响应拦截器中要对返回状态进行判断
    const token = store.state.token;
    token && (config.headers.Authorization = token);
    if (config.method === 'post') {
      const params = {
        ...config.data
      };
      filterEmptyKey(params); // 过滤掉空字符串
      config.headers['Content-Type'] = 'application/json';
      config.data = params;
    } else if (config.method === 'get') {
      config.params = {
        _t: Date.parse(new Date()) / 1000,
        ...config.params
      };
      filterEmptyKey(config.params); // 过滤掉空字符串
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// 响应拦截
service.interceptors.response.use(
  (res) => {
    const { data, config } = res
    // 如果是下载文件则需要加上这一段类型判断
    if (config.responseType === 'blob') {
      return response
    }
    if (!data.status) {
      // 错误提醒
      let message = data.message ? data.message : '未知错误'
      Vue.prototype.$message({
        message: config.action + '失败:' + message,
        type: 'error'
      });
    }
    return Promise.resolve(data) || {};
  },
  (error) => {
    return Promise.reject(error);
  }
);

export default service;

    下载/导出函数

export function downLoad(res, filename) {
  // res 调用接口后返回的数据
  // filename自定义文件名
  let blob = new Blob([res.data]); // 将返回的数据通过Blob的构造方法,创建Blob对象
  if ('msSaveOrOpenBlob' in navigator) {
    window.navigator.msSaveOrOpenBlob(blob, filename); // 针对浏览器
  } else {
    const elink = document.createElement('a'); // 创建a标签
    elink.download = filename;
    elink.style.display = 'none';
    // 创建一个指向blob的url,这里就是点击可以下载文件的根结
    elink.href = URL.createObjectURL(blob);
    document.body.appendChild(elink);
    elink.click();
    URL.revokeObjectURL(elink.href); //移除链接
    document.body.removeChild(elink); //移除a标签
  }
}

 

页面中使用

    注意:这种方法需要自己写文件名称,名称后面要写上文件后缀名

 

<template>
	<el-button type="primary" @click="handleExport">导出/下载</el-button>
</template>
<script>
import { exportData } from '@/api/index';
import { downLoad } from '@/utils/index';
export default {
	data() {
		return {
			startTime: '',
			endTime: ''
		}
	},
	methods: {
		const params = {
          startTime: this.startTime,
          endTime: this.endTime
        };
        exportData(params).then(res => {
          downLoad(res, '文件.xlsx'); // 需要自己写文件名称和类型
        });
	}
}
</script>

 参考vue中实现导出、下载文件_半度℃温热的博客-CSDN博客_vue 导出文件

 方法二、纯前端

Vue实现表格导出以及表格表头样式修改_ConstSuccess的博客-CSDN博客_vue表格样式

vue 使用xlsx导出功能(及其选择导出,条件导出,部分字段导出)_太阳姐姐的博客-CSDN博客_vue xlsx导出 

 

Logo

前往低代码交流专区

更多推荐