摘要:本篇HTML5教程讲解了如何导出Table数据并保存为Excel,希望阅读本篇文章以后大家有所收获,帮助大家对HTML5的理解更加深入。
现有需求,要把<table>显示的数据导出成Excel表。数据源表格允许用户筛选和排序,与原始数据表有区别,而传递操作又比较麻烦;另外.csv文件的功能受限严重,难以扩展。可以尝试下别的做法。
Google之,发现HTML5又成了一座分水岭。之前在IE浏览器下,用户可以利用ActiveXObject创建Excel.application对象来处理——当然不兼容Mac。后来Excel开放标准,可以导出xml格式的文件,dataURI就有了用武之地,导出<table>数据并保存为Excel有了更好的选择。
准备工作
1. 创建一个空白的Excel文档
2. 另存为“XML表格”,xml格式
3. 好了,模版搞定
图省事儿的也可以直接使用我的模板
template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="//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>';
复制表格数据
复制数据比较简单了。如前面模版所示,这里直接复制thead和tbody的全部代码,填充内容。当然为了体现用户操作,只复制显示的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))); }
然后配上base64头和mime类型,就可以触发下载了:
var uri = 'data:application/vnd.ms-excel;base64,'; location.href = uri + base64(template(tables));
提升体验
貌似到这里就完成了,不过下载的文件文件名是“下载”,而且还没有扩展名。
这是个用在内部管理后台的需求,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="//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的长度限制,遇到真正的大表仍然可能出问题。
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标WEB前端HTML5/CSS3频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号