前端导出csv/excel文件的几种方式

前言

经常做后管项目,里面必然会遇到的就是导出(下载)各种列表,一般就是excel或者csv格式的,有时候也会要求pdf格式,因为今天改了一个关于导出文件乱码的bug,就顺便小结一下。

一、Excel和CSV格式文件

在开始说导出(下载)方式之前,先来提一下Excel和csv格式是什么,有什么区别?直接下载Excel不就行了。可以仔细看一下下表,也可直接跳过看主要内容;

Exce CSV
这是一个二进制文件,它保存有关工作簿中所有工作表的信息 CSV代表Comma Separated Values 。这是一个纯文本格式,用逗号分隔一系列值
Excel不仅可以存储数据,还可以对数据进行操作 CSV文件只是一个文本文件,它存储数据,但不包含格式,公式,宏等。它也被称为平面文件
Excel是一个电子表格,将文件保存为自己的专有格式,即xls或xlsx CSV是将表格信息保存为扩展名为.csv的分隔文本文件的格式
保存在excel中的文件不能被文本编辑器打开或编辑 CSV文件可以通过文本编辑器(如记事本)打开或编辑
在数据仓库中,对于详细的标准化模式规范来说,Excel是最好的 在数据仓库中,CSV遵循相当平坦,简单的模式
任何用于解析Excel数据的编程语言库通常都会更大,更慢,更复杂 任何编程语言来解析CSV数据是微不足道的,生成它是非常容易的
由于数值和文本之间没有明确的区别或区分,Excel可以使用自动格式化功能搞乱您的邮政编码和信用卡号码 CSV是安全的,可以清楚地区分数值和文本。CSV不处理数据并按原样存储。
在Excel中,必须为每一行中的每一列都有一个开始标记和结束标记 在CSV中,只能编写一次列标题
Excel导入数据时消耗更多的内存 导入CSV文件可以更快,而且消耗更少的内存
在Excel中读取大文件的用户在END中更容易。此外,您还可以使用其他功能,例如选择要导入的单个单元格,自动转换日期和时间,读取公式及其结果,过滤器,排序等。 以CSV格式读取大文件不会像最终用户的Excel文件那样简单
除了文本,数据也可以以图表和图表的形式存储 每条记录都存储为一行文本文件,每一条新行都表示一个新的数据库行。CSV不能存储图表或图形
Excel文件只能用Microsoft Excel文档打开 CSV可以用Windows中的任何文本编辑器打开,如记事本,MS Excel,Microsoft Works 9等
Excel可以连接到外部数据源来获取数据。您可以使用Excel中的自定义加载项来增加其功能。Excel允许使用详细的跟踪和评论功能查看数据。 所有这些功能在CSV中都是不可能的
作为开发人员,由于Excel是专有的,因此很难以编程方式操纵Excel文件。.NET以外的其他语言尤其如此 作为开发人员,以编程方式操作CSV很容易,因为毕竟它们是简单的文本文件。

Excel和CSV的主要区别:

  1. CSV是纯文本文件,excel不是纯文本,excel包含很多格式信息在里面。

  2. CSV文件的体积会更小,创建分发读取更加方便,适合存放结构化信息,比如记录的导出,流量统计等等。

  3. CSV文件在windows平台默认的打开方式是excel,但是它的本质是一个文本文件。

  4. 一般用CSV主要用于导出导入表格。

二、前端根据后端返回导出文件

  1. 后端直接返回文件URL
    前端请求接口返回一个正常静态文件URL, window.location.href=URL
    这种是前端最简单的实现方式,但是缺点是耗资源,后端需要把数据转化为excel存起来,并且直接暴露连接。
  2. 后端直接返回一个outputStream数据流
    前端请求接口返回一个数据流,前端实现浏览器将数据下载为文件;
axios.request({
     url: url,
     method: 'get',
     params,
     responseType: 'blob' 
}).then(res => {
   downLoadBlobFile(res.data,name,typeStr); 
}).catch(err =>console.log(err))

上面的代码为vue中使用axios请求,怎么请求不重要,重要的是,responseType: 'blob’这一句,之后就可以对返回的blob二进制文件流做操作了。
什么是Blob呢,MDN官方解释:Blob 对象表示一个不可变、原始数据的类文件对象。Blob 表示的不一定是JavaScript原生格式的数据。
responseType值的类型可为如下:

数据类型
’ ‘ DOMString (这个是默认类型)
arraybuffer ArrayBuffer对象
blob Blob对象
document Document对象
json JavaScript object, parsed from a JSON string returned by the server
text DOMString

对于微软系浏览器(IE和Edge)和非微软系列浏览器采用两种不同的方式进行下载:

  1. IE和Edge 采用了 navigator.msSaveBlob 方法 此方法为IE10及以上特有,IE10以下勿采用
  2. 非微软浏览器 使用a标签的click事件进行下载
 /*
	*封装函数 downLoadFile.js
	*data:二进制文件
	*name:自定义文件名称
	*typeStr:参数type为MIME类型(text/csv,application/vnd.ms-excel)
 */
downloadFile (data, name?,typeStr) {
   if (!data) {
     this.$message.error('解析数据为空!')
     return
   }
   if (this.MyBrowserIsIE()) {
   	 const blob = new Blob([data], { type: typeStr });
     navigator.msSaveBlob(blob, name);
   } else{
	 const blob = new Blob([data], { type: typeStr });
     // 创建一个新的url,此url指向新建的Blob对象
     let url = window.URL.createObjectURL(blob)
     // 创建a标签,并隐藏改a标签
     let link = document.createElement('a')
     link.style.display = 'none'
     // a标签的href属性指定下载链接
     link.href = url
     link.download = name?name:'下载列表'
     link.click()
     // URL.revokeObjectURL() 静态方法用来释放一个之前已经存在的、通过调用
     window.URL.revokeObjectURL(url)
   }
   
 }
// 判断是否IE浏览器
MyBrowserIsIE() {
  let isIE = false;
  if (
    navigator.userAgent.indexOf("compatible") > -1 &&
    navigator.userAgent.indexOf("MSIE") > -1
  ) {
    isIE = true;   // ie浏览器
  }
  if (navigator.userAgent.indexOf("Trident") > -1) {
    isIE = true;   // edge 浏览器
  }
  return isIE;
}

这里需要注意的有两点:

  1. 我下载xls格式的type直接用的application/vnd.ms-excel,下载csv格式的直接用的text/csv;但是这种形式需要后端返回对应的excel流或者csv流,否则会有问题;
    下载excel也可以用xlsx插件,具体可以去网上查找一下,好处就是可以操作excel表,缺点就是麻烦;
    参数type为MIME类型,常见文档类型的MIME可参考MDN
  2. 下载csv格式文件,Excel打开可能乱码,但是wps等正常。是因为微软家发明了一个bom头,只需要添加一个’\uFEFF就可以了,但是这个方法只兼容高版本Excel,经测试office2007不生效,office2010是可以的;关于bom头,大家可以看看这篇文章,(今天也是因为这个在windows的Excel打开csv文件是乱码这个bug )。
转换前: const blob = new Blob([data], { type: typeStr });
转换后: const blob = new Blob([’\uFEFF‘+data], { type: typeStr });

到这里前端根据后端返回的数据流操作浏览器下载就差不多了,但是一般导出的方法都写在公用的请求方法里面例如:
前端导出csv/excel文件的几种方式_第1张图片

三、前端自己制作表格导出文件

导出文件大部分情况下是后端处理,有时候我们只需要js处理 该怎么做呢?主要就是获取根据table获取数据流,下面以拼接 csv格式为例,csv格式其实就是个纯文本文件,中间使用逗号或者换行符进行拼接; 也会有浏览器兼容问题,参考上文;


四、导出csv遇到的坑

  1. 导出CSV文件之后在excel中打开中文乱码,WPS没有问题。
    解决方案: 添加一个bom头,’\uFEFF就可以了,但是这个方法只兼容高版本Excel,经测试office2007不生效,office2010是可以的;
  2. 针对超过10位的数字用科学计数法展示;
    解决方案: 这是excel自带的功能;可以让后端在纯数字里面拼接一个子符,缺点就是导出表格里面这个符号去不掉,需要在表格里面批量操作;也可以直接转换成xls或者xlsx格式,看需求吧!

参考文章 :
vue通用导出组件的实现导出 excel csv pdf
Node.js 解决 csv 文件乱码的两种办法

你可能感兴趣的:(前端进阶知识,javascript,vue.js)