zoukankan      html  css  js  c++  java
  • 前端导出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(/(msies|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("","") + "" "; } //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

  • 相关阅读:
    MFC中L, _T(),TEXT,_TEXT区别以及含义
    Qt5完美解决 界面显示中文乱码
    TCP三次握手四次挥手详解
    TCP 长连接与短连接的区别
    Servlet 生命周期、工作原理
    Java反射的三种实现方式
    apache httpclient 4.5 兼容 http https
    mysql千万级大数据SQL查询优化
    Java String字符串补0或空格
    mysql存储过程
  • 原文地址:https://www.cnblogs.com/lovesong/p/6045405.html
Copyright © 2011-2022 走看看