资讯专栏INFORMATION COLUMN

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

abson / 2638人阅读

摘要:首发我的博客最近接到这么个需求,要把显示的数据导出成表。之,发现又成了一座分水岭。后来开放标准,可以导出格式的文件,就有了用武之地,导出数据并保存为有了更好的选择。输出内容套用模版之后,我们就有了完整的表格数据。至此,此项功能宣告圆满。

  

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

最近接到这么个需求,要把

显示的数据导出成Excel表。类似的需求并不稀罕,过去我通常用PHP输出.csv文件,不过这次似乎不能这么做:数据源表格允许用户筛选和排序,与原始数据表有区别,而传递操作又比较麻烦;另外.csv文件的功能受限严重,难以扩展。所以我准备尝试下别的做法。

Google之,发现HTML5又成了一座分水岭。之前在IE浏览器下,用户可以利用ActiveXObject创建Excel.application对象来处理——当然不兼容Mac。后来Excel开放标准,可以导出xml格式的文件,dataURI就有了用武之地,导出

数据并保存为Excel有了更好的选择。

(以下内容与StackOverflow中的答案有重合,那个3条赞同的我认为是最佳答案,可惜我没法顶他……)

准备工作

创建一个空白的Excel文档

另存为“XML表格”,xml格式

好了,模版搞定

图省事儿的也可以直接使用我的模板(这一段我使用了Handlebars,以便将来填充数据)

template = "
  
  
  
    {{#each tables}}
{{{this}}}
{{/each}} "; 复制表格数据

复制数据比较简单了。如前面模版所示,这里我很野蛮的直接复制theadtbody的全部代码,填充内容。当然为了体现用户操作,我只复制显示的tr。这里需要注意的是,jQuery判断一个dom是否处于显示状体基于以下3点:

display:none

表单元素,type="hidden"

宽高为0

父级以上节点不显示,自己也不会显示

所以,不能先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已经支持里的download属性。那么这就好办了,因为onclick事件会先于系统默认行为触发,所以我可以在这个事件的处理函数中将生成的Base64放在被点击按钮的href里,并将其download属性设为容易理解的“某年某月末日至某年某月某日广告数据分析.xls”。至此,此项功能宣告圆满。

HTML部分(使用到Bootstrap和Handlebars):

 导出

JavaScript部分

tableToExcel: function (tableList, name) {
  var tables = [],
      uri = "data:application/vnd.ms-excel;base64,",
      template = Handlebars.compile("{{#each tables}}{{{this}}}
{{/each}}"); 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 = $("
"); 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带来的优秀体验,我们的开发成本也能降得更低。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/77929.html

相关文章

  • 使用js-xlsx纯前端导出excel

    摘要:前言最近公司需要将几张统计表格导出到由于公司现有导出功能是前后端配合的导出,觉得麻烦,所以想找一个纯前端导出的工具,最后找到了,评价还是挺高的,但是中文文档没找到百度也没有找到一个比较全面的教程所以踩了很多坑,自己记录下,方便以后使用。 前言 最近公司需要将几张统计表格导出到excel,由于公司现有导出excel功能是前后端配合的导出,觉得麻烦,所以想找一个纯前端导出的工具,最后找到了...

    inapt 评论0 收藏0
  • 使用js-xlsx纯前端导出excel

    摘要:前言最近公司需要将几张统计表格导出到由于公司现有导出功能是前后端配合的导出,觉得麻烦,所以想找一个纯前端导出的工具,最后找到了,评价还是挺高的,但是中文文档没找到百度也没有找到一个比较全面的教程所以踩了很多坑,自己记录下,方便以后使用。 前言 最近公司需要将几张统计表格导出到excel,由于公司现有导出excel功能是前后端配合的导出,觉得麻烦,所以想找一个纯前端导出的工具,最后找到了...

    Cheriselalala 评论0 收藏0
  • 使用js-xlsx纯前端导出excel

    摘要:前言最近公司需要将几张统计表格导出到由于公司现有导出功能是前后端配合的导出,觉得麻烦,所以想找一个纯前端导出的工具,最后找到了,评价还是挺高的,但是中文文档没找到百度也没有找到一个比较全面的教程所以踩了很多坑,自己记录下,方便以后使用。 前言 最近公司需要将几张统计表格导出到excel,由于公司现有导出excel功能是前后端配合的导出,觉得麻烦,所以想找一个纯前端导出的工具,最后找到了...

    LeanCloud 评论0 收藏0
  • 【实战教程】使用云函数将数据导出 Excel 文件

    摘要:本文将介绍通过知晓云云函数来实现将数据表导出为文件的功能,并使用和将代码打包上传到知晓云。 在日常的工作中,常常需要根据运营需求对数据进行各种格式的处理和导出。导出后,不少人偏爱将数据放入 excel 在进行处理。 一般来说,处理数据导出时需要对数据进行一些运算整理。在以前,处理的方式是在一台独立的服务器上跑脚本。 而现在有了知晓云,不再需要维护服务器,直接写代码就能把相关事都都丢给云...

    iOS122 评论0 收藏0
  • 纯前端开发案例:用 SpreadJS 搭建信息系统软件开发平台

    摘要:葡萄城的是一个基于技术的纯控件,控件性能流畅,有类似的在线表格编辑器,适合非专业程序员设计报表模板,很符合平台部分无编码开发的理念。葡萄城控件产品对于项目的价值控件主要用于本项目中的报表设计,展示,打印等功能。 showImg(https://segmentfault.com/img/bVbalYk?w=1000&h=400); 华闽通达 - R 平台应用所使用产品:SpreadJS ...

    Heier 评论0 收藏0

发表评论

0条评论

abson

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<