vue导出excel表格-后端返回blob流文件,前端接收并导出(处理导出以后打开文件损坏问题)

简介: vue导出excel表格-后端返回blob流文件,前端接收并导出(处理导出以后打开文件损坏问题)

问题描述

我们日常做项目,特别是后台管理系统,常常需要导出excel文件。实现方式有三种

方式一(后端处理)

后端直接返回一个excel表格地址,前端点击下载即可。不过这种方式,会导致后端的excel越存越多,造成冗余。不过如果是固定模板表格内容不会变得情况下,这种方式还是不错的。当然解决方案就是后端写一个定时器,每隔一段时间清理一次

看情况使用,如果是固定的表格,一两年都不更换的excel表格用这种方式倒是也可以的。后端固定写死只把这个固定的表格传递给前端,这样的话,也能用
方式二(后端处理)

后端返回一个blob流文件,这样的话,是一次性的流文件,使用一次就没了,就不会造成后端excel越存越多。这种方式挺好

目前这种方式使用的会稍微多一些点
方式三(前端处理)

前端保存需要导出的表格内容,然后下载并使用excel插件轮子,就可以导出了。不过众所周知,前端只是拿到数据,并展示数据的。如果表格内容比较多,或者用户对于前端速度有要求的话,或者主管老大不希望我们在项目中下载安装太多的轮子从而导致最终打包文件过大的话,这种方式就不太好

不推荐

流文件导出步骤

流文件导出注意事项

需要加responseType: 'blob',否则文件会损坏

注意,excel流文件一定要在请求的时候加上响应类型字段,也就是:responseType: 'blob'或者,responseType: 'arraybuffer' ,否则下载出来的excel文件就会损坏,就会打不开。损坏文件如下图所示:

ArrayBuffer和Blob一样,都是二进制数据的容器,而ArrayBuffer相比更为底层一些,他可以去操作去修改这些二进制值,以此同时,二者之间也是可以相互转换的。导出excel用哪个都行的

如何加responseType: 'blob'

我使用的axios发请求,所以需要在请求的时候加上,又因为给axios做了二次封装,使用了请求拦截器和相应拦截器,以及包装函数导出,(请求拦截器和相应拦截器就不写了,主要看包装函数导出)代码写法是这样的:

export default (method, url, data = null, headers = 'application/json;charset=UTF-8', responseType = null) => {
    if (method == "post") {
        return http({
            method: 'post',
            url: rootUrl + url,
            // url: url,
            data: data,
            headers: {
                'Content-Type': headers,
            }, 
            responseType: responseType // 相应类型如果有的话,就用接口中的,如果没有就默认为null
        });
    } else if (method == "get") {
        return http({
            method: 'get',
            url: rootUrl + url,
            // url: url,
            params: data,
            headers: {
                'Content-Type': headers
            },
            responseType: responseType // 相应类型如果有的话,就用接口中的,如果没有就默认为null
        });
    } else {
        return;
    }
}
这里包装的return出去的http函数接收的参数除了method请求方式、url请求地址、data请求参数、以及请求头(编码方式制定UTF-8)之外,再多一个相应类型responseType,默认为null,所以只需要在写接口的时候,最后一个位置参数附上就行了。

查看我们加上去的responseType

我们打印一下相应拦截器的结果就能看到了

http.interceptors.response.use((res) => {
    console.log('响应拦截器查看',res); // 打印这个结果就能看到responseType了
    return res.data
}, (error) => {
    return Promise.reject(error);
})

没加的responseType为null

加上就是blob或者ArrayBuffer

步骤一

在导出的接口加上声明接收参数 最后一个参数就是指定类型为blob或者arraybuffer

export const export = (params) => http("get", `api/export`, params, 'application/json; charset=UTF-8', 'arraybuffer')

步骤二

假设我们点击按钮导出excel表格

  // 导出按钮的回调函数中
  async outExcelData() {
      // 准备参数
      let params = xxx
      const res = await this.$api.export(params);
      const blob = new Blob([res]);  // 把得到的结果用流对象转一下
      var a = document.createElement("a"); //创建一个<a></a>标签
      a.href = URL.createObjectURL(blob); // 将流文件写入a标签的href属性值
      a.download = "基础工艺数据.xlsx"; //设置文件名
      a.style.display = "none";  // 障眼法藏起来a标签
      document.body.appendChild(a); // 将a标签追加到文档对象中
      a.click(); // 模拟点击了a标签,会触发a标签的href的读取,浏览器就会自动下载了
      a.remove(); // 一次性的,用完就删除a标签
    },

总结

注意,必须要声明流文件且得到的结果用流文件转一下,这样的话,就不会出现excel文件损坏、或者乱码的情况。

相关文章
|
14天前
|
前端开发
前端引入字体文件
文章介绍了如何在前端项目中引入字体文件,并展示了具体的HTML和CSS代码示例,包括如何使用`@font-face`规则来定义字体和在页面中应用自定义字体。
36 1
前端引入字体文件
|
14天前
|
存储 前端开发 数据库
前端项目一键换肤vue+element(ColorPicker)
本文介绍了如何在前端项目中实现一键换肤功能,通过使用CSS变量和Element UI的颜色选择器组件(ColorPicker),并结合Vuex进行状态管理和持久化,实现主题颜色的动态切换。
32 3
前端项目一键换肤vue+element(ColorPicker)
|
3天前
|
JavaScript 前端开发 网络架构
|
1天前
|
前端开发 JavaScript 应用服务中间件
linux安装nginx和前端部署vue项目(实际测试react项目也可以)
本文是一篇详细的教程,介绍了如何在Linux系统上安装和配置nginx,以及如何将打包好的前端项目(如Vue或React)上传和部署到服务器上,包括了常见的错误处理方法。
9 0
linux安装nginx和前端部署vue项目(实际测试react项目也可以)
|
10天前
|
存储 JavaScript 前端开发
前端 vue:路由的高级使用
前端 vue:路由的高级使用
|
10天前
|
资源调度 JavaScript 前端开发
前端vue:路由的基本使用
前端vue:路由的基本使用
|
27天前
|
SpringCloudAlibaba JavaScript 前端开发
谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架
分布式组件、nacos注册配置中心、openfegin远程调用、网关gateway、ES6脚本语言规范、vue、elementUI
谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架
|
2月前
|
存储 前端开发 JavaScript
前端语言串讲 | 青训营笔记
前端语言串讲 | 青训营笔记
31 0
|
4月前
|
JSON 前端开发 JavaScript
前端Ajax、Axios和Fetch的用法和区别笔记
前端Ajax、Axios和Fetch的用法和区别笔记
76 2
|
4月前
|
前端开发 JavaScript 数据库
如何实现前后端分离-----前端笔记
如何实现前后端分离-----前端笔记