当前位置: 首页 > news >正文

前端导出Excel兼容写法

今天整理出在Web前端导出Excel的写法,写了一个工具类,对各个浏览器进行了兼容。

首先,导出的数据来源可能有两种:

1. 页面的HTML内容(一般是table)

2. 纯数据

PS:不同的数据源,导出的写法也是不相同的。

技术方案

IE

无论数据来源是哪里,都是用ActiveXObject对象及相关的命令,IE10、11有点不同。 

非IE

纯数据的,使用一个FileSaver.js,如果有浏览器不支持Blob的,还需要引入Blob.js,来做导出。

HTML内容的,构造一个base64字符串的路径,跳转地址下载,其实也可以将数据抽出来,用纯数据的方式。

PS:自行了解Blob对象。

关键问题

1. 非IE导出纯数据中文乱码

解决方法:在Blob的数据要加上"\uFEFF"做修正。

2. Safari的Blob报TypeError: '[object BlobConstructor]' is not a constructor

原因:应该Safari的Blob是不完整的。

解决方法:需要引入一个Blob.js做修正,不过下载的文件会显示"UnKnown",但加上后缀名xls,文件内容还是可以看的(暂时没有很好办法)。

3. Blob每个值是以逗号分隔,那数据有逗号怎么办

解决方法:需要在每个值额外裹上双引号,这样不会影响导出结果,导出内容也是正确的。

4. 非IE导出HTML内容(非table),样式丢失

解决方法:额,这个没有办法,可以将数据抽出来,用纯数据的方式导出。

代码实现

(function(){
     var EXCEL_CONTENTTYPE = "application/vnd.ms-excel;",
          EXCEL_URI = 'data:application/vnd.ms-excel;base64,',
          EXCE_TEMPLATE = '<html><head><meta charset="UTF-8"></head><body>{html}</body></html>',
          __PREVFIX = "\uFEFF",
          ieVersion = window.navigator.userAgent.toLowerCase().match(/(msie\s|trident.*rv:)([\w.]+)/),
          useIE = ieVersion && ieVersion[2] < 10,
          isIE1011 = ieVersion && ieVersion[2] > 9;

     var Export = {
          /*
          *@param datas Two-dimensional array : datas, export only with data
                            or String : DOM id, export html content
          *@param fileName export file name
          */
          toExcel: function(datas, fName){
               var isId = typeof datas === 'string';
               if(isId || datas instanceof Array){
                    if(useIE || isId && isIE1011){
                         Export.__ieExport(datas);
                    } else{
                         Export.__oTherExport(datas, fName);
                    }              
               } else{
                    alert("datas params need Two-dimensional array or String.");
               }
          },
          __ieExport : function(datas){
             
                var oXL = new ActiveXObject("Excel.Application"),
                oWB = oXL.Workbooks.Add(),
                oSheet = oWB.ActiveSheet,
                    i = 0,
                    j; 

               if(typeof datas === 'string'){

                    var elem = document.getElementById(datas); 
                   var sel = document.body.createTextRange(); 
                    sel.moveToElementText(elem); 
                    try{
                         sel.select(); 
//there ie10、11 will be error, i don't know why, but also can export } catch(e){} sel.execCommand("Copy"); oSheet.Paste(); } else { for(; i < datas.length; i++){ var row = datas[i]; for (j = 0; j < row.length; j++) { oSheet.Cells(i + 1, j + 1).value = row[j]; } } } oXL.Visible = true; }, __oTherExport : function(datas, fileName){ if(typeof datas === 'string'){ var elem = document.getElementById(datas), content = EXCE_TEMPLATE.replace("{html}", elem.outerHTML); //TODO: need test large amount of data window.location.href = EXCEL_URI +
window.btoa(unescape(encodeURIComponent(content))); } else { var blob, i = 0, j, str = __PREVFIX; for(; i < datas.length; i++){ var row = datas[i]; // the value add double quotation marks on both sides, for separate values. str += "\""+ row.join("\",\"") + "\"\n"; } //on safari: TypeError: '[object BlobConstructor]' is not a constructor (evaluating 'new Blob([str],{ //import Blob.js to fix, but still have a problem : the fileName will be 'Unknown' ,
//but if you add suffix name, content can be seen.
blob = new Blob([str],{ type: EXCEL_CONTENTTYPE }); saveAs(blob, fileName || "Download.xls"); } } } window.ExportUtil = Export; })();

演示示例:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title>demo</title>
     <style type="text/css">
          ul{ list-style:none; padding:0px; margin:0px; width:590px;
          height:20px; line-height:20px; border:1px solid #99CC00;
          border-top:0px; font-size:12px;}
          ul li{ display:block; width:33%; float:left;text-indent:2em}
          .th{ background:#F1FADE; font-weight:bold; border-top:1px }
     </style>
</head>
<body>
<div>
     <table id="tb" border=4 width=250 align=center>
          <caption>【表格举例】</caption>
          <tr bgcolor="#cccccc">
               <th><br></th>
               <th>列-A</th>
               <th>列-B</th>
               <th>列-C</th>
          </tr>
          <tr align=center>
               <td>行-1</td>
               <td>A1</td>
               <td>B1</td>
               <td rowspan=2>C1-C2</td>
          </tr>
          <tr align=center>
               <td>行-2</td>
               <td>A2</td>
               <td>B2</td>
          </tr>
          <tr align=center>
               <td>行-3</td>
               <td>A3</td>
               <td colspan=2>A3-B3</td>
          </tr>
     </table>
    
     <div id="tul">
          <h1><a href="http://www.66css.com">www.66css.com</a></h1>
          <ul class="th">
               <li>姓名</li>
               <li>班级</li>
               <li>年龄</li>
          </ul>
          <ul>
               <li>阿三</li>
               <li>3-1</li>
               <li>13</li>
          </ul>
          <ul>
               <li>小龙</li>
               <li>2-4</li>
               <li>16</li>
          </ul>
          <ul>
               <li>大马</li>
               <li>5-3</li>
               <li>17</li>
          </ul>
     </div>
    <script src="Blob.js"></script>
    <script src="FileSaver.min.js"></script>
    <script src="ExportUtil.js"></script><!--工具类-->
    <script>
          //demo 1
          ExportUtil.toExcel([
               ["学号", "姓名", "年龄"],
               ["001", "张学友", "40"],
               ["002", "张信哲", "38"],
               ["003", "林志炫", "41"],
               ["004", "刘亦菲", "24"],
               ["005", "贾玲", "30"],
               ["006", "陈一发", "23"]
          ],"hello.xls"); 
         
          //demo2
          ExportUtil.toExcel("tb");    
         
          //demo3
          ExportUtil.toExcel("tul");    
          //ie的有样式,但某些样式会丢失。
     </script>
</body>
</html>

代码下载

我将完整代码放这:https://github.com/codingforme/code-learn/tree/master/export-excel

 

总结

这个导出Excel工具类兼容了Chrome、Firefox、Safari(不完美)、IE6-11,针对两种数据源都做了处理。一般来说,纯数据导出的效果是最好的,所以如果HTML内容导出方式不满意,可以将数据抽出,用回纯数据导出。最后,这个工具缺失的是对大数据量导出的测试,不过这个后面有空再进行验证。 


本文为原创文章,转载请保留原出处,方便溯源,如有错误地方,谢谢指正。

本文地址 :http://www.cnblogs.com/lovesong/p/6045405.html

 

相关文章:

  • 洛谷 P1529 回家 Bessie Come Home Label:Dijkstra最短路 乱搞
  • zookeeper适用场景:zookeeper解决了哪些问题
  • Linux打补丁的一些问题
  • 服务器日志追踪
  • bootstrapValidator.js,最好用的bootstrap表单验证插件
  • 搭建简单FTP服务器以及过程中容易遇到的几个问题(一)
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • vs2015密钥 企业版 专业版 (vs.net)
  • MySQL管理与优化(20):备份与恢复
  • mysqldump 备份命令使用中的一些经验总结
  • Mysql开启慢查询日志
  • 全国信息学奥林匹克联赛 ( NOIP2014) 复赛 模拟题 Day1 长乐一中
  • 一套后台管理html模版
  • 关于CXF的FrontEnd和数据绑定方案
  • Android开发之计算器(一)界面设计之activity_main布局文件
  • #Java异常处理
  • (ckeditor+ckfinder用法)Jquery,js获取ckeditor值
  • 【知识碎片】第三方登录弹窗效果
  • 0x05 Python数据分析,Anaconda八斩刀
  • 4. 路由到控制器 - Laravel从零开始教程
  • Cumulo 的 ClojureScript 模块已经成型
  • JavaScript标准库系列——Math对象和Date对象(二)
  • node 版本过低
  • 从0搭建SpringBoot的HelloWorld -- Java版本
  • 你不可错过的前端面试题(一)
  • 前端技术周刊 2019-02-11 Serverless
  • 白色的风信子
  • 1.Ext JS 建立web开发工程
  • 国内唯一,阿里云入选全球区块链云服务报告,领先AWS、Google ...
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • #FPGA(基础知识)
  • #pragam once 和 #ifndef 预编译头
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • $(function(){})与(function($){....})(jQuery)的区别
  • (AngularJS)Angular 控制器之间通信初探
  • (C语言)fread与fwrite详解
  • (C语言)二分查找 超详细
  • (Java岗)秋招打卡!一本学历拿下美团、阿里、快手、米哈游offer
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (附源码)基于SSM多源异构数据关联技术构建智能校园-计算机毕设 64366
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (七)Java对象在Hibernate持久化层的状态
  • (转) Face-Resources
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • (轉貼) 資訊相關科系畢業的學生,未來會是什麼樣子?(Misc)
  • *上位机的定义
  • 、写入Shellcode到注册表上线
  • .helper勒索病毒的最新威胁:如何恢复您的数据?
  • .NET 中创建支持集合初始化器的类型
  • .Net转Java自学之路—基础巩固篇十三(集合)
  • @column注解_MyBatis注解开发 -MyBatis(15)
  • @vue/cli 3.x+引入jQuery
  • [ element-ui:table ] 设置table中某些行数据禁止被选中,通过selectable 定义方法解决