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之选择组件的深入解析
Jun 19 Javascript
DOM节点删除函数removeChild()用法实例
Jan 12 Javascript
浅谈JavaScript中指针和地址
Jul 26 Javascript
JS实现新浪博客左侧的Blog管理菜单效果代码
Oct 22 Javascript
javascript实现无法关闭的弹框
Nov 27 Javascript
js实现本地图片文件拖拽效果
Jul 18 Javascript
微信小程序 本地图片按照屏幕尺寸处理
Aug 04 Javascript
HTML5+JS+JQuery+ECharts实现异步加载问题
Dec 16 jQuery
浅谈TypeScript的类型保护机制
Feb 23 Javascript
VUE-ElementUI 自定义Loading图操作
Nov 11 Javascript
如何在vue 中使用柱状图 并自修改配置
Jan 21 Vue.js
vue3语法糖内的defineProps及defineEmits
Apr 14 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面向对象全攻略 (七) 继承性
2009/09/30 PHP
微信支付开发教程(一)微信支付URL配置
2014/05/28 PHP
Yii核心组件AssetManager原理分析
2014/12/02 PHP
PHP使用redis消息队列发布微博的方法示例
2017/06/22 PHP
javascript实现十六进制颜色值(HEX)和RGB格式相互转换
2014/06/20 Javascript
5个可以帮你理解JavaScript核心闭包和作用域的小例子
2014/10/08 Javascript
jquery实现导航固定顶部的效果仿蘑菇街
2014/10/22 Javascript
Vuejs第九篇之组件作用域及props数据传递实例详解
2016/09/05 Javascript
vue 请求后台数据的实例代码
2017/06/22 Javascript
Vue框架中正确引入JS库的方法介绍
2017/07/30 Javascript
Postman模拟发送带token的请求方法
2018/03/31 Javascript
在vscode里使用.vue代码模板的方法
2018/04/28 Javascript
微信小程序购物车、父子组件传值及calc的注意事项总结
2018/11/14 Javascript
微信小程序云开发 生成带参小程序码流程
2019/05/18 Javascript
JS箭头函数和常规函数之间的区别实例分析【 5 个区别】
2020/05/27 Javascript
jQuery实现简单弹幕制作
2020/12/10 jQuery
[00:21]DOTA2亚洲邀请赛 Logo演绎
2015/02/07 DOTA
[00:52]玛尔斯技能全介绍
2019/03/06 DOTA
python用ConfigObj读写配置文件的实现代码
2013/03/04 Python
wxpython 最小化到托盘与欢迎图片的实现方法
2014/06/09 Python
python实现守护进程、守护线程、守护非守护并行
2018/05/05 Python
python发送邮件脚本
2018/05/22 Python
Python + selenium + requests实现12306全自动抢票及验证码破解加自动点击功能
2018/11/23 Python
Python将string转换到float的实例方法
2019/07/29 Python
Python实现括号匹配方法详解
2020/02/10 Python
Python如何将图像音视频等资源文件隐藏在代码中(小技巧)
2020/02/16 Python
10个python爬虫入门实例(小结)
2020/11/01 Python
新西兰珠宝品牌:Michael Hill
2017/09/16 全球购物
机械电子工程专业推荐信范文
2013/11/20 职场文书
公司授权委托书
2014/04/04 职场文书
实习报告评语
2014/04/26 职场文书
运动会演讲稿
2014/05/07 职场文书
大学生暑期实践报告
2015/07/13 职场文书
2020年基层司法所建设情况调研报告
2019/11/30 职场文书
HTML页面滚动时部分内容位置固定不滚动的实现
2021/04/14 HTML / CSS
关于vue中如何监听数组变化
2021/04/28 Vue.js