js基于FileSaver.js 浏览器导出Excel文件的示例


Posted in Javascript onAugust 15, 2017

本文介绍了js基于FileSaver.js 浏览器导出Excel文件,分享给大家,也给自己做个笔记

限制一:不同浏览器对 blob 对象有不同的限制

具体看看下面这个表格(出自FileSaver.js):

Browser Constructs as Filenames Max Blob Size Dependencies
Firefox 20+ Blob Yes 800 MiB None
Firefox data: URI No n/a Blob.js
Chrome Blob Yes 500 MiB None
Chrome for Android Blob Yes 500 MiB None
Edge Blob Yes ? None
IE 10+ Blob Yes 600 MiB None
Opera 15+ Blob Yes 500 MiB None
Opera data: URI No n/a Blob.js
Safari 6.1+* Blob No ? None
Safari data: URI No n/a Blob.js

限制二:构建完 blob 对象后才会转换成文件

这一点限制对小文件(几十kb)可能没什么影响,但对稍微大一点的文件影响就很大了。试想,用户要下载一个 100mb 的文件,如果他点击了下载按钮之后没看到下载提示的话,他肯定会继续按,等他按了几次之后还没看到下载提示时,他就会抱怨我们的网站,然后离开了。

然而事实上下载的的确确发生了,只是要等到下载完文件之后才能构建 blob 对象,再转化成文件。而且,用户再触发多几次下载就会造成一些资源上的浪费。

因此,如果是要下载大文件的话,还是推荐直接创建一个 <a> 标签拉~
写 html 也好,写 JavaScript 动态创建也好,用自己喜欢的方式去创建就好了。

FileSaver.js 

/* FileSaver.js
 * A saveAs() FileSaver implementation.
 * 1.3.2
 * 2016-06-16 18:25:19
 *
 * License: MIT
 *  See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
 */

/*global self */
/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */

/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */

var saveAs = saveAs || (function(view) {
  "use strict";
  // IE <10 is explicitly unsupported
  if (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) {
    return;
  }
  var
     doc = view.document
     // only get URL when necessary in case Blob.js hasn't overridden it yet
    , get_URL = function() {
      return view.URL || view.webkitURL || view;
    }
    , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
    , can_use_save_link = "download" in save_link
    , click = function(node) {
      var event = new MouseEvent("click");
      node.dispatchEvent(event);
    }
    , is_safari = /constructor/i.test(view.HTMLElement) || view.safari
    , is_chrome_ios =/CriOS\/[\d]+/.test(navigator.userAgent)
    , throw_outside = function(ex) {
      (view.setImmediate || view.setTimeout)(function() {
        throw ex;
      }, 0);
    }
    , force_saveable_type = "application/octet-stream"
    // the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to
    , arbitrary_revoke_timeout = 1000 * 40 // in ms
    , revoke = function(file) {
      var revoker = function() {
        if (typeof file === "string") { // file is an object URL
          get_URL().revokeObjectURL(file);
        } else { // file is a File
          file.remove();
        }
      };
      setTimeout(revoker, arbitrary_revoke_timeout);
    }
    , dispatch = function(filesaver, event_types, event) {
      event_types = [].concat(event_types);
      var i = event_types.length;
      while (i--) {
        var listener = filesaver["on" + event_types[i]];
        if (typeof listener === "function") {
          try {
            listener.call(filesaver, event || filesaver);
          } catch (ex) {
            throw_outside(ex);
          }
        }
      }
    }
    , auto_bom = function(blob) {
      // prepend BOM for UTF-8 XML and text/* types (including HTML)
      // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
      if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
        return new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type});
      }
      return blob;
    }
    , FileSaver = function(blob, name, no_auto_bom) {
      if (!no_auto_bom) {
        blob = auto_bom(blob);
      }
      // First try a.download, then web filesystem, then object URLs
      var
         filesaver = this
        , type = blob.type
        , force = type === force_saveable_type
        , object_url
        , dispatch_all = function() {
          dispatch(filesaver, "writestart progress write writeend".split(" "));
        }
        // on any filesys errors revert to saving with object URLs
        , fs_error = function() {
          if ((is_chrome_ios || (force && is_safari)) && view.FileReader) {
            // Safari doesn't allow downloading of blob urls
            var reader = new FileReader();
            reader.onloadend = function() {
              var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;');
              var popup = view.open(url, '_blank');
              if(!popup) view.location.href = url;
              url=undefined; // release reference before dispatching
              filesaver.readyState = filesaver.DONE;
              dispatch_all();
            };
            reader.readAsDataURL(blob);
            filesaver.readyState = filesaver.INIT;
            return;
          }
          // don't create more object URLs than needed
          if (!object_url) {
            object_url = get_URL().createObjectURL(blob);
          }
          if (force) {
            view.location.href = object_url;
          } else {
            var opened = view.open(object_url, "_blank");
            if (!opened) {
              // Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html
              view.location.href = object_url;
            }
          }
          filesaver.readyState = filesaver.DONE;
          dispatch_all();
          revoke(object_url);
        }
      ;
      filesaver.readyState = filesaver.INIT;

      if (can_use_save_link) {
        object_url = get_URL().createObjectURL(blob);
        setTimeout(function() {
          save_link.href = object_url;
          save_link.download = name;
          click(save_link);
          dispatch_all();
          revoke(object_url);
          filesaver.readyState = filesaver.DONE;
        });
        return;
      }

      fs_error();
    }
    , FS_proto = FileSaver.prototype
    , saveAs = function(blob, name, no_auto_bom) {
      return new FileSaver(blob, name || blob.name || "download", no_auto_bom);
    }
  ;
  // IE 10+ (native saveAs)
  if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) {
    return function(blob, name, no_auto_bom) {
      name = name || blob.name || "download";

      if (!no_auto_bom) {
        blob = auto_bom(blob);
      }
      return navigator.msSaveOrOpenBlob(blob, name);
    };
  }

  FS_proto.abort = function(){};
  FS_proto.readyState = FS_proto.INIT = 0;
  FS_proto.WRITING = 1;
  FS_proto.DONE = 2;

  FS_proto.error =
  FS_proto.onwritestart =
  FS_proto.onprogress =
  FS_proto.onwrite =
  FS_proto.onabort =
  FS_proto.onerror =
  FS_proto.onwriteend =
    null;

  return saveAs;
}(
    typeof self !== "undefined" && self
  || typeof window !== "undefined" && window
  || this.content
));
// `self` is undefined in Firefox for Android content script context
// while `this` is nsIContentFrameMessageManager
// with an attribute `content` that corresponds to the window

if (typeof module !== "undefined" && module.exports) {
 module.exports.saveAs = saveAs;
} else if ((typeof define !== "undefined" && define !== null) && (define.amd !== null)) {
 define("FileSaver.js", function() {
  return saveAs;
 });
}

调用方法

function expToExcel(){
      var content = $("#report").html();
      var blob = new Blob(["Hello, world!"], { type: "text/plain;charset=utf-8" });
      saveAs(blob, "hello world.txt");      
    }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery tablesorter.js 支持中文表格排序改进
Dec 09 Javascript
原生js拖拽(第一课 未兼容)拖拽思路
Mar 29 Javascript
checkbox勾选判断代码分析
Jun 11 Javascript
AngularJS下对数组的对比分析
Aug 24 Javascript
JavaScript正则表达式实例详解
Oct 16 Javascript
关于Node.js的events.EventEmitter用法介绍
Apr 01 Javascript
使用JQuery实现图片轮播效果的实例(推荐)
Oct 24 jQuery
Vue2.0 slot分发内容与props验证的方法
Dec 12 Javascript
vue的diff算法知识点总结
Mar 29 Javascript
vue获取时间戳转换为日期格式代码实例
Apr 17 Javascript
js键盘事件实现人物的行走
Jan 17 Javascript
vue选项卡切换的实现案例
Apr 11 Vue.js
form表单序列化详解(推荐)
Aug 15 #Javascript
JavaScript上传文件时不用刷新页面方法总结(推荐)
Aug 15 #Javascript
JavaScript阻止表单提交方法(附代码)
Aug 15 #Javascript
jQuery DOM节点的遍历方法小结
Aug 15 #jQuery
Mongoose实现虚拟字段查询的方法详解
Aug 15 #Javascript
深入浅析Vue不同场景下组件间的数据交流
Aug 15 #Javascript
React应用中使用Bootstrap的方法
Aug 15 #Javascript
You might like
解析php通过cookies获取远程网页的指定代码
2013/06/25 PHP
PHP利用APC模块实现文件上传进度条的方法
2015/01/26 PHP
PHP使用GETDATE获取当前日期时间作为一个关联数组的方法
2015/03/19 PHP
CI框架网页缓存简单用法分析
2018/12/26 PHP
javascript function调用时的参数检测常用办法
2010/02/26 Javascript
仅IE不支持setTimeout/setInterval函数的第三个以上参数
2011/05/25 Javascript
使用jquery mobile做幻灯播放效果实现步骤
2013/01/04 Javascript
jQuery中is()方法用法实例
2015/01/06 Javascript
使用Javascript实现选择下拉菜单互移并排序
2016/02/23 Javascript
微信小程序 radio单选框组件详解及实例代码
2017/01/10 Javascript
Vue2.0使用过程常见的一些问题总结学习
2017/04/10 Javascript
微信小程序实现图片放大预览功能
2020/10/22 Javascript
实现div滚动条默认最底部以及默认最右边的示例代码
2017/11/15 Javascript
JS实现移动端触屏拖拽功能
2018/07/31 Javascript
小试SVG之新手小白入门教程
2019/01/08 Javascript
Java Varargs 可变参数用法详解
2020/01/28 Javascript
H5+css3+js搭建带验证码的登录页面
2020/10/11 Javascript
vue+elementui通用弹窗的实现(新增+编辑)
2021/01/07 Vue.js
Python时间戳与时间字符串互相转换实例代码
2013/11/28 Python
Python的时间模块datetime详解
2017/04/17 Python
解决pandas无法在pycharm中使用plot()方法显示图像的问题
2018/05/24 Python
python leetcode 字符串相乘实例详解
2018/09/03 Python
Python打印特殊符号及对应编码解析
2020/05/07 Python
用纯css3实现的图片放大镜特效效果非常不错
2014/09/02 HTML / CSS
英国的屈臣氏:Boots博姿
2017/12/23 全球购物
Marmot土拨鼠官网:美国专业户外运动品牌
2018/01/11 全球购物
实习生自荐信范文
2013/11/13 职场文书
节能减排倡议书
2014/04/15 职场文书
八一建军节营销活动方案
2014/08/31 职场文书
成都人事代理协议书
2014/10/25 职场文书
财务审计整改报告
2014/11/06 职场文书
2015年销售人员工作总结
2015/04/07 职场文书
学校财务管理制度
2015/08/04 职场文书
导游词之嵊泗列岛
2019/10/30 职场文书
总结python多进程multiprocessing的相关知识
2021/06/29 Python
Python 全局空间和局部空间
2022/04/06 Python