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 相关文章推荐
Javascript操作select方法大全[新增、修改、删除、选中、清空、判断存在等]
Sep 26 Javascript
JS代码判断IE6,IE7,IE8,IE9的函数代码
Aug 02 Javascript
js判读浏览器是否支持html5的canvas的代码
Nov 18 Javascript
javascript文本框内输入文字倒计数的方法
Feb 24 Javascript
URL中“#” “?” &amp;“”号的作用浅析
Feb 04 Javascript
vue-router3.0版本中 router.push 不能刷新页面的问题
May 10 Javascript
vue2.0使用v-for循环制作多级嵌套菜单栏
Jun 25 Javascript
Vue下路由History模式打包后页面空白的解决方法
Jun 29 Javascript
Vue中的基础过渡动画及实现原理解析
Dec 04 Javascript
简单了解常用的JavaScript 库
Jul 16 Javascript
Element InputNumber计数器的使用方法
Jul 27 Javascript
HTML元素拖拽功能实现的完整实例
Dec 04 Javascript
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作的文本留言本的例子(二)
2006/10/09 PHP
php将url地址转化为完整的a标签链接代码(php为url地址添加a标签)
2014/01/17 PHP
php函数serialize()与unserialize()用法实例
2014/11/06 PHP
smarty简单入门实例
2014/11/28 PHP
JavaScript中的new的使用方法与注意事项
2007/05/16 Javascript
jquery 操作DOM案例代码分享
2012/04/05 Javascript
js将控件隐藏及display属性的使用介绍
2013/12/30 Javascript
js实现按Ctrl+Enter发送效果
2014/09/18 Javascript
jQuery xml字符串的解析、读取及查找方法
2016/03/01 Javascript
javascript的BOM
2016/05/03 Javascript
Ajax分页插件Pagination从前台jQuery到后端java总结
2016/07/22 Javascript
BootStrap中Datepicker控件带中文的js文件
2016/08/10 Javascript
AngularJS  双向数据绑定详解简单实例
2016/10/20 Javascript
js实现字符全排列算法的简单方法
2017/05/01 Javascript
详解Angular 4.x NgIf 的用法
2017/05/22 Javascript
JavaScript 中的 this 简单规则
2017/09/19 Javascript
vue中当图片地址无效的时候,显示默认图片的方法
2018/09/18 Javascript
JavaScript动态添加数据到表单并提交的几种方式
2019/06/26 Javascript
vue.js实现二级菜单效果
2019/10/19 Javascript
微信小程序实现横向滚动导航栏效果
2019/12/12 Javascript
vue3 watch和watchEffect的使用以及有哪些区别
2021/01/26 Vue.js
手把手教你python实现SVM算法
2017/12/27 Python
Python实现PS图像明亮度调整效果示例
2018/01/23 Python
python安装pywin32clipboard的操作方法
2019/01/24 Python
pytorch实现mnist数据集的图像可视化及保存
2020/01/14 Python
Python urllib2运行过程原理解析
2020/06/04 Python
Python通过Schema实现数据验证方式
2020/11/12 Python
python实现在列表中查找某个元素的下标示例
2020/11/16 Python
解决pycharm 格式报错tabs和space不一致问题
2021/02/26 Python
利用Bootstrap实现漂亮简洁的CSS3价格表实例源码
2017/03/02 HTML / CSS
什么是View State?
2013/01/27 面试题
社区文化建设方案
2014/05/02 职场文书
师德标兵先进事迹材料
2014/12/19 职场文书
酒店前台接待岗位职责
2015/04/02 职场文书
什么是SOLID
2022/03/24 Javascript
试用1103暨1103、1101同门大比武 [ DAIWEI ]
2022/04/05 无线电