【HTML5版】导出Table数据并保存为Excel

首发我的博客 http://blog.meathill.com/tech/js/export-table-data-into-a-excel-file.html

近来接到这么个需求,要把<table>显现的数据导出成Excel表。相似的需求并不希奇,过去我通经常运用PHP输出.csv文件,不过此次好像不能这么做:数据源表格许可用户挑选和排序,与原始数据表有区分,而通报操纵又比较贫苦;别的.csv文件的功用受限严峻,难以扩大。所以我预备尝试下别的做法。

Google之,发明HTML5又成了一座分水岭。之前在IE浏览器下,用户能够应用ActiveXObject建立Excel.application对象来处置惩罚——固然不兼容Mac。厥后Excel开放规范,能够导出xml花样的文件,dataURI就有了用武之地,导出<table>数据并保存为Excel有了更好的挑选。

(以下内容与StackOverflow中的答案有重合,谁人3条赞许的我以为是最佳答案,惋惜我没法顶他……)

预备工作

  1. 建立一个空缺的Excel文档
  2. 另存为“XML表格”,xml花样
  3. 好了,模版搞定

图省事儿的也能够直接运用我的模板(这一段我运用了Handlebars,以便未来添补数据)

template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40">\
  <head><!--[if gte mso 9]>\
    <xml>\
      <x:ExcelWorkbook>\
        <x:ExcelWorksheets>\
          <x:ExcelWorksheet>\
            <x:Name>{{worksheet}}</x:Name>\
            <x:WorksheetOptions>\
              <x:DisplayGridlines/>\
            </x:WorksheetOptions>\
          </x:ExcelWorksheet>\
        </x:ExcelWorksheets>\
      </x:ExcelWorkbook>\
    </xml><![endif]-->\
  </head>\
  <body>\
    {{#each tables}}<table>{{{this}}}</table>{{/each}}\
  </body>\
</html>';

复制表格数据

复制数据比较简单了。如前面模版所示,这里我很蛮横的直接复制theadtbody的悉数代码,添补内容。固然为了表现用户操纵,我只复制显现的tr。这里须要注重的是,jQuery推断一个dom是不是处于显现状体基于以下3点:

  1. display:none
  2. 表单元素,type=”hidden”
  3. 宽高为0
  4. 父级以上节点不显现,本身也不会显现

所以,不能先clone()find(':hidden').remove(),由于没添加到主Dom树的节点宽高都是0,也就会被以为还没显现,这下就都干掉了。

输出内容

套用模版以后,我们就有了完全的表格数据。接下来,我们须要把其转换成base64花样,以便套用dataURI输出。因而便要运用btoa这个函数(将二进制数据转换成base64花样的字符串,HTML5的大礼之一,操纵二进制的API),不过注重,这个函数不能直接转换一般unicode字符,不然大多数浏览器都邑抛出非常。所以须要先经由两步转换:

function base64(string) {
  return window.btoa(unescape(encodeURIComponent(string)));
}

(MDN中还引荐了别的一种做法,经由过程Typed Array做中介,我没有实操,有兴致的能够试下)

然后配上base64头和mime范例,就能够触发下载了:

var uri = 'data:application/vnd.ms-excel;base64,';
location.href = uri + base64(template(tables));

提拔体验

貌似到这里就完成了,不过作为一位挂职产物总监的码农,我很难容忍下载的文件文件名是“下载”,而且还没有扩大名(Windows 8下没有;Windows 7 和 Mac下会有.xls的扩大名,我以为和已装软件注册过的mime范例有关)。

这是个用在内部管理背景的需求,我之前曾请求人人必需运用Chrome接见背景;而且我晓得,Chrome已支撑<a>里的download属性。那末这就好办了,由于onclick事宜会先于体系默许行动触发,所以我能够在这个事宜的处置惩罚函数中将天生的Base64放在被点击按钮的href里,并将其download属性设为轻易明白的“某年某月末日至某年某月某日广告数据剖析.xls”。至此,此项功用宣布美满。

HTML部份(运用到Bootstrap和Handlebars):

<a href="#" title="点击下载" class="btn btn-primary export-button" download="{{start}}至{{end}}广告数据剖析.xls"><i class="icon-download-alt icon-white"></i> 导出</a>

JavaScript部份

tableToExcel: function (tableList, name) {
  var tables = [],
      uri = 'data:application/vnd.ms-excel;base64,',
      template = Handlebars.compile('<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{{worksheet}}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body>{{#each tables}}<table>{{{this}}}</table>{{/each}}</body></html>');

  for (var i = 0; i < tableList.length; i++) {
    tables.push(tableList[i].innerHTML);
  }
  var data = {
    worksheet: name || 'Worksheet',
    tables: tables
  };
  return uri + base64(template(data));
},
exportHandler: function (event) {
  var tables = this.$('table'),
      table = null;
  tables.each(function (i) {
    var t = $('<table><thead></thead><tbody></tobdy></table>');
    t.find('thead').html(this.tHead.innerHTML);
    t.find('tbody').append($(this.tBodies).children(':visible').clone());
    t.find('.not-print').remove(); // not-print 是@media print中不会打印的部份
    t.find('a').replaceWith(function (i) { // 表格中不再须要的超链接也移除了
      return this.innerHTML;
    });
    table = table ? table.add(t) : t;
  });
  event.currentTarget.href = Dianjoy.utils.tableToExcel(table, '广告数据');
}

尾声

说是美满,实在也不尽然,由于URL有2M的长度限定,碰到真正的大表依然能够出题目(我没实测)。

末了例行吐槽:老板(指导)想提拔工作效力,光逼员工没啥意义,必需关注员工一样平常运用的软件:不准用杂乱无章的浏览器,一致Chrome;360一率禁用(近来碰到N起晋级Chrome Dev 30版致使种种bug的题目);悉数装Windows 8(自带杀毒,险些一切外设秒配)。能做到这几点,公司办公效力提拔1倍不止。

再多说两句:我们对外的背景虽然做到了基础兼容,但假如用户运用非Chrome接见,依然会发起他换用Chrome。现在Chrome接见占比已上升到90%,IE678不到5%,愿望不久的未来,我们的用户都能恣意享用HTML5带来的优异体验,我们的开辟本钱也能降得更低。

    原文作者:Meathill
    原文地址: https://segmentfault.com/a/1190000000336643
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞