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 相关文章推荐
JS+ACTIVEX实现网页选择本地目录路径对话框
Mar 18 Javascript
javascript如何创建表格(javascript绘制表格的二种方法)
Dec 10 Javascript
javascript删除数组元素并且数组长度减小的简单实例
Feb 14 Javascript
基于JS实现密码框(password)中显示文字提示功能代码
May 27 Javascript
BootStrap与validator 使用笔记(JAVA SpringMVC实现)
Sep 21 Javascript
jQuery设置Easyui校验规则(推荐)
Nov 21 Javascript
使用Vue做一个简单的todo应用的三种方式的示例代码
Oct 20 Javascript
详解async/await 异步应用的常用场景
May 13 Javascript
javascript面向对象三大特征之继承实例详解
Jul 24 Javascript
vue 路由子组件created和mounted不起作用的解决方法
Nov 05 Javascript
vue-router重写push方法,解决相同路径跳转报错问题
Aug 07 Javascript
Vue 打包的静态文件不能直接运行的原因及解决办法
Nov 19 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
删除无限分类并同时删除它下面的所有子分类的方法
2010/08/08 PHP
PHP的autoload机制的实现解析
2012/09/15 PHP
织梦sitemap地图实时推送给百度的教程
2015/08/03 PHP
php封装的pdo数据库操作工具类与用法示例
2019/05/08 PHP
JQuery 确定css方框模型(盒模型Box Model)
2010/01/22 Javascript
兼容ie、firefox的图片自动缩放的css跟js代码分享
2012/01/21 Javascript
js Dialog 实践分享
2012/10/22 Javascript
鼠标滑过出现预览的大图提示效果
2014/02/26 Javascript
Node.js 学习笔记之简介、安装及配置
2015/03/03 Javascript
vue之数据交互实例代码
2017/06/20 Javascript
NodeJs form-data格式传输文件的方法
2017/12/13 NodeJs
JavaScript正则表达式函数总结(常用)
2018/02/22 Javascript
js找出5个数中最大的一个数和倒数第二大的数实现方法示例小结
2020/03/04 Javascript
vue keep-alive的简单总结
2021/01/25 Vue.js
[57:38]2018DOTA2亚洲邀请赛3月30日 小组赛A组 OpTic VS OG
2018/03/31 DOTA
python模拟新浪微博登陆功能(新浪微博爬虫)
2013/12/24 Python
用Python实现通过哈希算法检测图片重复的教程
2015/04/02 Python
python对url格式解析的方法
2015/05/13 Python
Python数据结构与算法之二叉树结构定义与遍历方法详解
2017/12/12 Python
python Spyder界面无法打开的解决方法
2018/04/27 Python
python plotly绘制直方图实例详解
2019/07/22 Python
python实现复制文件到指定目录
2019/10/16 Python
django自定义模板标签过程解析
2019/12/14 Python
Html5 Geolocation获取地理位置信息实例
2016/12/09 HTML / CSS
德国体育用品网上商店:SC24.com
2016/08/01 全球购物
将世界上最美丽的摄影作品转化为艺术作品:Photos.com
2017/11/28 全球购物
香港唯港荟酒店预订:Hotel ICON
2018/03/27 全球购物
求两个数的乘积和商数,该作用由宏定义来实现
2013/03/13 面试题
采购部岗位职责
2013/11/24 职场文书
村官工作鉴定评语
2014/01/27 职场文书
小学三年级数学教学反思
2014/01/31 职场文书
农民工工资支付承诺函
2014/03/31 职场文书
审计班子对照检查材料
2014/08/27 职场文书
奖学金感谢信
2015/01/21 职场文书
入党积极分子党支部意见
2015/06/02 职场文书
ubuntu下常用apt命令介绍
2022/06/05 Servers