运用JavaScript将 table 转化成 excel文件格式导出

472 阅读3分钟

html 代码

<div class="tools">
        <button type="button" class="btn green" id="excell" onclick="method5('dataTable')">导出Excle</button>
    </div>
    <table border="1" id="dataTable">
        <tr>
            <th>姓名</th>
            <th>年龄</th>
        </tr>
        <tr>
            <td>王先生</td>
            <td>18</td>
        </tr>
        <tr>
            <td>jack</td>
            <td>20</td>
        </tr>
    </table>

javascript 代码

//打印表格
var idTmr;
function getExplorer() {
    var explorer = window.navigator.userAgent;
    //ie  
    if(explorer.indexOf("MSIE") >= 0) {
        return 'ie';
    }
    //firefox  
    else if(explorer.indexOf("Firefox") >= 0) {
        return 'Firefox';
    }
    //Chrome  
    else if(explorer.indexOf("Chrome") >= 0) {
        return 'Chrome';
    }
    //Opera  
    else if(explorer.indexOf("Opera") >= 0) {
        return 'Opera';
    }
    //Safari  
    else if(explorer.indexOf("Safari") >= 0) {
        return 'Safari';
    }
}

function method5(tableid) {
    if(getExplorer() == 'ie') {
        var curTbl = document.getElementById(tableid);
        var oXL = new ActiveXObject("Excel.Application");
        var oWB = oXL.Workbooks.Add();
        var xlsheet = oWB.Worksheets(1);
        var sel = document.body.createTextRange();
        sel.moveToElementText(curTbl);
        sel.select();
        sel.execCommand("Copy");
        xlsheet.Paste();
        oXL.Visible = true;

        try {
            var fname = oXL.Application.GetSaveAsFilename("Excel.xls",
                "Excel Spreadsheets (*.xls), *.xls");
        } catch(e) {
            print("Nested catch caught " + e);
        } finally {
            oWB.SaveAs(fname);
            oWB.Close(savechanges = false);
            oXL.Quit();
            oXL = null;
            idTmr = window.setInterval("Cleanup();", 1);
        }

    } else {
        tableToExcel(tableid)
    }
}

function Cleanup() {
    window.clearInterval(idTmr);
    CollectGarbage();
}
var tableToExcel = (function() {
    var uri = 'data:application/vnd.ms-excel;base64,',
        template = '<html><head><meta charset="UTF-8"></head><body><table  border="1">{table}</table></body></html>',
        base64 = function(
            s) {
            return window.btoa(unescape(encodeURIComponent(s)))
            //unescape() 函数可对通过 escape() 编码的字符串进行解码。
            //该函数的工作原理是这样的:通过找到形式为 %xx 和 %uxxxx 的字符序列(x 表示十六进制的数字),用 Unicode 字符 \u00xx 和 \uxxxx 替换这样的字符序列进行解码。
            //ECMAScript v3 已从标准中删除了 unescape() 函数,并反对使用它,因此应该用 decodeURI() 和 decodeURIComponent() 取而代之。

            //  encodeURI和encodeURIComponent都是对url的编码
            //  encodeURI方法不会对下列字符编码  ASCII字母、数字、~!@#$&*()=:/,;?+'  ,解码方法是  decodeURI
            //  encodeURIComponent方法不会对下列字符编码 ASCII字母、数字、~!*()' ,解码方法是  decodeURIComponent
            //  所以encodeURIComponent比encodeURI编码的范围更大。
            //  当你要编码整个URL,使用这个URL,那么用encodeURI。
            //  当你要编码URL中的参数的时候,那么encodeURIComponent是最好方法。
            //  let encodedData = window.btoa("Hello, world"); // base64 编码
            //  let decodedData = window.atob(encodedData); // 解码 成 ASCII
        },
        format = function(s, c) {
            return s.replace(/{(\w+)}/g, function(m, p) { //m = "{table}"  p = "table"
                return c[p];
            })
            // 对replace解释见下方的js
        }
    return function(table, name) {
        if(!table.nodeType)
            table = document.getElementById(table)
        var ctx = {
            worksheet: name || 'Worksheet',
            table: table.innerHTML
        }
        window.location.href = uri + base64(format(template, ctx))
    }
})()

对上方replace方法的讲解

//对replace的解释
//1.第一个参数直接用字符串匹配 第二个参数为文本
var str1 = 'GoodGoodStudy';
var result1 = str1.replace('Good','cctv');
console.log('result1======' + result1);//result1======cctvGoodStudy

//2.第一个参数直接用字符串匹配 第二个参数为返回替换文本的函数
var str2 = 'GoodGoodStudy';
var result2 = str2.replace('Good',function(str,key) {
    return 'cctv';
});
console.log('result2======' + result2);//result2======cctvGoodStudy

//3.第一个参数用RegExp 第二个参数为文本
var str3 = 'GoodGoodStudy';
var result3 = str3.replace(/Good/g,'cctv');
console.log('result3======' + result3);//result3======cctvcctvStudy

//4.第一个参数用RegExp 第二个参数为返回文本的函数
var str4 = 'i have 98 you have 66';
var fun = function(template,data) {
    return template.replace(/(\d)+/g,function(str,group,firstIndex,template) {
        var v = data[str];
        return v;
    });
};
var result4 = fun(str4,{98: '第一个',66: '第二个'});
console.log('result4======' + result4);//result4======i have 第一个 you have 第二个
//那么function(str,group,firstIndex,template)四个参数是什么意思?
//如果正则表达式中有分组(即有括号)那么有四个参数,第一个是匹配到的字符串,第二个是匹配到的最后一个分组
//第三个是匹配到的字符串第一个位置的索引,第四个是被匹配的字符串
//如果没有分组,那么只有三个参数,没有了分组这个参数。

//5.路径中参数替换。这是一个api路径中的{xxx}占位符替换成参数的方法。
var str = 'http://127.0.0.1/myapi/{personCode}/{followType}/find';
var nano = function (template, data) { //该方法摘自项目:)
    return template.replace(/\{([\w\.]*)\}/g, function (str, key) {
        var keys = key.split(".");
        var v = data[keys.shift()];
        for (var i = 0, l = keys.length; i < l; i++) {
            v = v[keys[i]];
        }
        return (typeof v !== "undefined" && v !== null) ? v : "";
    });
};
var strNew = nano(str,{personCode: '1654321',followType: 'C'});
console.log('strNew===' + strNew);//strNew===http://127.0.0.1/myapi/1654321/C/find
//上面的正则多匹配了\. 并且在funtion里面进行了处理,目的是可能会出现这样的{person.code}的占位,
//那么传入的参数为{person:{code:1654321},followType: 'C'}