javascript生成.xls文件(兼容IE&Chrome&Firefox)

贴代码,一切尽在注释中

<html>
<head>
    <meta charset="utf-8">
</head>

<body>
    <input type="button" value="下载设备模板" onclick="foo();" />


<script type="text/javascript" language="javascript">

var downloadTemplate = function() {
    /**
     * 根据所给数据创建并返回单行 tr节点
     * data (必选), tag (可选, 标识创建的节点类型)
     **/
    var getTr=function(data,tag){
        var tr=document.createElement("tr");
        for(var i=0;i<data.length;i++){
            var item=document.createElement(tag||"td");
            item.innerHTML=data[i];
            tr.appendChild(item);
        }
        return tr;
    };

    /**
     * 根据所给数据创建并返回 table节点
     * data (可选,无则返回空的table节点), head(可选, 标识是否存在表头)
     **/
    var getTable=function(data,head){
        var table=document.createElement("table");
        var head=head||false;

        //存在表头设标识为th,否则为td
        var tag=head?"th":"td";

        //判断是一维||二维,执行不同逻辑
        if(data[0] instanceof Array){
            for(var i=0;i<data.length;i++){
                //第一行数据根据tag创建节点类型
                (i==0)?table.appendChild(getTr(data[i],tag)):table.appendChild(getTr(data[i]));
            }
        }else if(data instanceof Array)
            table.appendChild(getTr(data,tag));
        return table;
    };

    /**
     * table (必选, table节点)
     * uri   为生成excel的头部标签
     * xmlns xml命名空间
     * 返回xls资源
     **/
    var getXls=function(table){  
        var uri = 'data:application/vnd.ms-excel;base64,';
        var template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" '+
        'xmlns:x="urn:schemas-microsoft-com:office:excel" '+
        'xmlns="http://www.w3.org/TR/REC-html40">'+
        '<head>'+
            '<meta http-equiv="Content-type" content="text/html;charset=UTF-8" /> '+
            '<!--[if gte mso 9]>'+
            '<xml>'+
                '<x:ExcelWorkbook>'+
                    '<x:ExcelWorksheets>'+
                        '<x:ExcelWorksheet>'+
                            '<x:WorksheetOptions>'+
                                '<x:DisplayGridlines/>'+
                            '</x:WorksheetOptions>'+
                        '</x:ExcelWorksheet>'+
                    '</x:ExcelWorksheets>'+
                '</x:ExcelWorkbook>'+
            '</xml>'+
            '<![endif]-->'+
        '</head>'+
        '<body>'+
            '<table>{table}</table>'+
        '</body>'+
        '</html>';
    
        /**
         * 转码 base 64
         * window.btoa能从ascii/二进制流中创建一个base64编码的字符串
         * escape编码  unescape 解码字符串
         * encodeURIComponent编码  DecodeURIComponent 解码字符串
         **/
        var base64 = function(s) {
            return window.btoa(unescape(encodeURIComponent(s)));
        };

        //返回替换完具体数据的xls模板
        var getXlsXml = function(template,data) {
            return template.replace(/{(\w+)}/g,data);
        };

        //返回资源链接
        return uri+base64(getXlsXml(template, table.innerHTML));
    };

    /**
     * IE浏览器
     * 使用Microsoft ActiveXObject组件生成xls ( 只兼容IE浏览器,选择允许加载组件 )
     * table(必选, table节点)
     **/
    var msDownload=function(data){
        var xls = new ActiveXObject("Excel.Application");
        xls.visible = true;  
        var xlsBook = xls.Workbooks.Add;
        var xlsheet = xlsBook.Worksheets(1);

        for(var i=0;i<data.length;i++)
            if(data[0] instanceof Array)
                for(var j=0;j<data[0].length;j++)
                    xlsheet.Cells(i+1,j+1).Value=data[i][j];
            else xlsheet.Cells(1,i+1).Value=data[i];
        //用完释放
        xls=null;
    };
    
    //参数: data(必选,一维||二维 数组), head(可选, 标识是否存在表头)
    var download=function(data , head){
        if(window.navigator.userAgent.indexOf("MSIE") >= 0)
            msDownload(data);
        else 
            //下载(RestFul:资源下载置于超链接,地址为资源定位地址)
            window.location.href =getXls(getTable(data,head));
    };

    return {
        getXls:getXls,
        msDownload:msDownload,
        download:download
    };
};

//测试数据
var od=['aid','pwd','设备名称','网关DK','区域'];

var td=[
    ['aid','pwd','设备名称','网关DK','区域'],
    ['10086','root','松下R-399','208564165456542','2 #201'],
    ['10001','root','索尼SUV 09','456542895564165','2 #201']
];

var foo=function(){
    // new downloadTemplate().download(od,true);
    new downloadTemplate().download(td,true);
};

</script>
</body>
</html>

测试结果:

在IE浏览器上需要允许加载ActiveX控件,之后在弹出的对话框中点击"是"

下载下来的表格如下:

chrome:

打开表格:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏CSDN技术头条

前端知识点总结——Vue

作用:将表达式执行的结果 输出当调用元素的 innerHTML 中;还可以将数据绑定到视图。

14420
来自专栏不知的专栏

反-反爬虫:用几行代码写出和人类一样的动态爬虫

本文将从 Phantomjs 动态爬虫介绍起,用3行代码傻瓜式完成基于 Casper 的动态爬虫来绕过对抗策略获取页面数据。

1.4K20
来自专栏北京马哥教育

Linux cat命令

豌豆贴心提醒,本文阅读时间3分钟,文末有秘密! ? 文 | 豌豆 图 | 来源网络 ? Linux cat命令 命令:cat cat 命令用...

41740
来自专栏游戏杂谈

【hta版】获取AppStore上架后的应用版本号

之前写过一篇文章:获取AppStore上架后的应用版本号,那一篇文章使用node.js实现,存在的问题就是如果在没有安装node.js运行环境下是无法运行的,而...

13720
来自专栏Jackson0714

【博客美化】04.自定义地址栏logo

444110
来自专栏挖掘大数据

Cobub无码埋点关键技术实现流程(附图)

随着大数据时代的到来,数据采集也已经变的越来越重要。前端埋点作为一个比较成熟的数据接入手段被广泛应用着。目前埋点分为两种方式,有码与无码埋点。有码埋点比较容易理...

27460
来自专栏源哥的专栏

如何在js文件中写加载Applet控件(js与jsp分离技术)

                        如何在js文件中写加载Applet控件(js与jsp分离技术)

11940
来自专栏移动开发之家

GSYVideoPlayer项目说明

项目目前UI层大部分方法和变量都是protect,虽然就封装性而言这并不是很好,但你可以继承后快捷实现你的自定义。

12830
来自专栏彭湖湾的编程世界

【javascript】原生js更改css样式的两种方式

下面我给大家介绍的是原生js更改CSS样式的两种方式: 1通过在javascript代码中的node.style.cssText="css表达式1;css表达式...

28580
来自专栏码生

ReactNative 面试题

今天有一个 ReactNative 的面试。 时间紧迫,临时写了几个问题,初级面试问题。 都是关键字

1.1K30

扫码关注云+社区

领取腾讯云代金券