使用JavaScript下载csv文件

前端可以使用JavaScript在客户端下载包含页面数据的文件,这里以下载CSV格式文件为例,代码如下:

function downloadData(data, filename, type) {
    var file = new Blob(["ufeff" + data], { type: type });
    if (window.navigator.msSaveOrOpenBlob)
      // IE10+
      window.navigator.msSaveOrOpenBlob(file, filename);
    else {
      // Others
      var a = document.createElement("a"),
        url = URL.createObjectURL(file);
      a.href = url;
      a.download = filename;
      document.body.appendChild(a);
      a.click();
      setTimeout(function() {
        document.body.removeChild(a);
        window.URL.revokeObjectURL(url);
      }, 0);
    }
  }

让我们解释一下这段代码:

(一)downloadData 函数

首先,downloadData函数接收三个参数:

  1. data:需要下载的数据(注意数据格式需要符合csv格式规范);
  2. filename:需要下载的文件名,注意需要添加符合数据格式的文件名的后缀,这提示了操作系统应该以何种方式打开;
  3. type:代表了将会被放入到Blob对象中的数组内容的MIME类型;

(二)Blob 构造函数

接着,我们来解析下面这条语句:

var file = new Blob(["ufeff" + data], { type: type });

可以看到,我们使用了Blob构造函数,创建了一个Blob实例对象fileBlob构造函数有什么用呢?它接收的两个参数是什么?让我们在下面一一作答:

① Blob 构造函数的作用

Blob构造函数会根据传入的数组参数构造出一个新的Blob对象实例,该对象实例的值由以下两步生成:

  1. Blob构造函数会将第一个参数,即一个数组内的所有值串联起来;
  2. Blob会将被串联的值转换为二进制编码的数据然后返回;

注意,Blob对象实例的值是不可变的,它只有两个只读的属性:size:表示对象中所包含数据的大小(单位是字节),以及type:值是一个字符串,表示该对象实例所包含数据的MIME类型(即我们传入Blob构造函数的第二个参数中指定的type值,默认为"")。

② Blob 构造函数接收的参数

Blob构造函数接收的第一个参数为数组类型,数组内的所有值会在实例化时被串联。若传入数组的值中有DOMString类型的值,则会被编码为UTF-8格式。而为了让导出的CSV格式文件在Excel中打开时,中文不出现乱码,需要在数组的首位添加一个BOM(Byte Order Mark “字节次序标记”)头ufeff

BOM是一个不可见的字符,它是ES5新增的空白符,在Unicode3.2之前,uFEFF表示“零宽不换行空格(Zero Width No-Break Space)”,但在Unicode3.2之后,新增了u2060表示零宽不换行空格,uFEFF就只用来表示字节次序的标记了。而在Microsoft中,其记事本程序发明了一种UTF-8变体(Python 2.5称为“utf-8-sig”)以提高可检测到UTF-8编码的可靠性,该编码要求在任何Unicode字符被写入之前都需要编写一个UTF-8编码的BOM(看起来像是一个字节序列:0xef,0xbb,0xbf)。

Blob构造函数接收的第二个参数是一个对象,该对象有以下两个属性:

  1. type:默认值为"",它表示第一个参数内,数组内容的MIME类型;
  2. options:这个属性目前还没有被很好的支持,所以不用管它;

总之,我们通过new Blob()获得了一个Blob类型的二进制文件。


(三)下载文件

接着我们要做的便是下载我们生成好的文件了,有两种方式,第一种方式最简单,因为IE浏览器直接提供了下载文件的接口window.navigator.msSaveOrOpenBlob(file, filename);,正如函数签名所示,我们只需要向函数中传入我们生成好的二进制文件,以及文件名就可以让浏览器自动下载文件了。

抛下IE浏览器,要实现文件下载就稍微麻烦些,我们需要通过创建一个a标签,并模拟点击这个a标签实现文件下载,让我们将与之相关的代码贴在下面:

var a = document.createElement("a"),
     url = URL.createObjectURL(file);
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
setTimeout(function() {
  document.body.removeChild(a);
  window.URL.revokeObjectURL(url);
}, 0);

注意这段代码的第二行,我们会发现一个新的API:URL.createObjectURL()函数,这个函数接收一个参数,一个Blob对象,并为该对象生成一个指向该对象的URL对象,需要注意的是只要当下文档没有被关闭,该URL对象就会一直存储在内存中不会被回收,因此一旦确定不再需要该URL对象,一定要及时使用URL.revokeObjectURL()清理。

以上,我们就解释了在前端以CSV格式下载数据的方法和原理,需要注意的是,该段代码只适用于IE10及以上的现代浏览器,因为无论是Blob构造函数还是URL.createObjectURL()API都只有这些浏览器提供支持。

原文地址:https://www.cnblogs.com/libinfs/p/8080985.html