zoukankan      html  css  js  c++  java
  • node.js生成excel下载各种方法分析对比--附excel-export方法

    引言:日常工作中已经有许多应用功能块使用了nodejs作为web服务器,而生成报表下载也是我们在传统应用。

    java中提供了2套类库实现(jxl 和POI),.NET 作为微软的亲儿子更加不用说,各种com组件贴心使用。

    nodejs作为一门新的语言,报表功能也不是十分完善。

    (1).js-xlsx : 目前 Github 上 star 数量最多的处理 Excel 的库,支持解析多种格式表格XLSX / XLSM / XLSB / XLS / CSV,解析采用纯js实现,写入需要依赖nodejs或者FileSaver .js实现生成写入Excel,可以生成子表Excel,功能强大,但上手难度稍大。不提供基础设置Excel表格api例单元格宽度,文档有些乱,不适合快速上手;

    https://github.com/SheetJS/js-xlsx

    (2).node-xlsx : 基于Node.js解析excel文件数据及生成excel文件,仅支持xlsx格式文件;

    https://github.com/mgcrea/node-xlsx

    (3).excel-parser : 基于Node.js解析excel文件数据,支持xls及xlsx格式文件,需要依赖python,太重不太实用;

    https://github.com/leftshifters/excel-parser

    (4).excel-export : 基于Node.js将数据生成导出excel文件,生成文件格式为xlsx,可以设置单元格宽度,API容易上手,无法生成worksheet字表,比较单一,基本功能可以基本满足;

    https://github.com/functionscope/Node-Excel-Export

    (5).node-xlrd : 基于node.js从excel文件中提取数据,仅支持xls格式文件,不支持xlsx,有点过时,常用的都是XLSX 格式。

    nodejs刚出来那几年开发人员写了很多node依赖库,但是大部分现在处于不维护状态。

    现在还在持续更新的只有node-xlsx excel-export推荐使用,js-xlsx作为一个大而全的基础库(虽然现在也不在更行了,此库最大的问题是api十分不友好,学习曲线高)有能力的项目组可以进一步封装,。

    本篇为一个简单的下载的DEMO ,就简单使用excel-export,后面有分析下他的缺点。

    安装 npm install excel-export

    1.html 点击一个按钮下载一个excel

    <!DOCTYPE html>
    <html>
    <head>
        <!-- 声明文档使用的字符编码 -->
        <meta charset='utf-8'>
        <!-- 优先使用 IE 最新版本和 Chrome -->
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
        <!-- 启用360浏览器的极速模式(webkit) -->
        <meta name="renderer" content="webkit">
        <!-- 页面描述 -->
        <meta name="description" content="chart demo"/>
        <!-- 页面关键词 -->
        <meta name="keywords" content="chart demo"/>
        <!-- 网页作者 -->
        <meta name="author" content="name, email@gmail.com"/>
        <!-- 搜索引擎抓取 -->
        <meta name="robots" content="index,follow"/>
        <!-- 为移动设备添加 viewport -->
        <meta name="viewport" content="initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no">
        <title>{{title}}</title>
        <link rel='stylesheet' href='/css/style.css'/>
        <script type="text/javascript" src="/js/library/jquery/3.3.1/jquery-3.1.1.min.js"></script>
     
    </head>
    <body>
    <button id="exportExcel" class="btn btn-warning">测试下载excel</button>
    <button id="exportExcel2" class="btn btn-warning">测试下载多个sheet的excel</button>
    <script type="text/javascript">
        $("#exportExcel").click(function(){
            console.info("exportExcel");
            var url =  "/api/exportExcel/" + 1;
            console.info(url);
            window.location = url;//这里不能使用get方法跳转,否则下载不成功
     
        });
        $("#exportExcel2").click(function(){
            console.info("exportExcel2");
            var url =  "/api/exportmultisheetExcel/" + 1;
            console.info(url);
            window.location = url;//这里不能使用get方法跳转,否则下载不成功
     
        });
    </script>
    </body>
    </html>

    2.router,提供2个请求,单sheet下载和多sheet下载

    var express = require('express');
    var router = express.Router();
    var server =  express();
    server.use('/api', router);
     
    var nodeExcel = require('excel-export');
     
    const disableLayout ={layout: false};
     
    // disable interface layout.hbs  user config layout: false
    router.get('/exportExcel/:id', function(req, res, next) {
        var conf ={};
        conf.stylesXmlFile = "styles.xml";
        conf.name = "mysheet";
        conf.cols = [{
            caption:'string',
            type:'string',
            beforeCellWrite:function(row, cellData){
                return cellData.toUpperCase();
            },
            28.7109375
        },{
            caption:'date',
            type:'date',
            beforeCellWrite:function(){
                var originDate = new Date(Date.UTC(1899,11,30));
                return function(row, cellData, eOpt){
                    if (eOpt.rowNum%2){
                        eOpt.styleIndex = 1;
                    }
                    else{
                        eOpt.styleIndex = 2;
                    }
                    if (cellData === null){
                        eOpt.cellType = 'string';
                        return 'N/A';
                    } else
                        return (cellData - originDate) / (24 * 60 * 60 * 1000);
                }
            }()
        },{
            caption:'bool',
            type:'bool'
        },{
            caption:'number',
            type:'number'
        }];
        conf.rows = [
            ['pi', new Date(Date.UTC(2013, 4, 1)), true, 3.14],
            ["e", new Date(2012, 4, 1), false, 2.7182],
            ["M&M<>'", new Date(Date.UTC(2013, 6, 9)), false, 1.61803],
            ["null date", null, true, 1.414]
        ];
        var result = nodeExcel.execute(conf);
        res.setHeader('Content-Type', 'application/vnd.openxmlformats');
        res.setHeader("Content-Disposition", "attachment; filename=" + "Report.xlsx");
        res.end(result, 'binary');
    });
     
    router.get('/exportmultisheetExcel/:id', function(req, res, next) {
        var confs = [];
        var conf = {};
        conf.cols = [{
            caption: 'string',
            type: 'string'
        },
            {
                caption: 'date',
                type: 'date'
            },
            {
                caption: 'bool',
                type: 'bool'
            },
            {
                caption: 'number 2',
                type: 'number'
            }];
        conf.rows = [['hahai', (new Date(Date.UTC(2013, 4, 1))).oaDate(), true, 3.14], ["e", (new Date(2012, 4, 1)).oaDate(), false, 2.7182], ["M&M<>'", (new Date(Date.UTC(2013, 6, 9))).oaDate(), false, 1.2], ["null", null, null, null]];
        for (var i = 0; i < 3; i++) {
            conf = JSON.parse(JSON.stringify(conf));   //clone
            conf.name = 'sheet'+i;
            confs.push(conf);
        }
        var result = nodeExcel.execute(confs);
        res.setHeader('Content-Type', 'application/vnd.openxmlformats');
        res.setHeader("Content-Disposition", "attachment; filename=" + "Report.xlsx");
        res.end(result, 'binary');
    });
    

    3.excel-export 提供了4种类型的数据格式,数字,时间,真假,默认字符串

    cols可以为设置列类型的 caption为列名(会填充第一行的内容),type为列数据类型,beforeCellWrite可以在填充之前对数据进行逻辑处理,width可以定义宽带

    rows为一个二位数组,直接按照行列方式填充excel的内容

    name定义sheet的名字

    值得注意的时候excel-export如果需要定义excel的默认格式,需要引用一个excel的格式头,这个头定义在styles.xml中,这个文件可以在node_modules/example/styles.xml中拷贝的项目对应目录

    例子用的是根目录,所以我们需放在根目录,不然就会报找不到这个文件。

    如何定于excel的xml格式,具体多看下微软的文档吧,我也了解太少

    https://blogs.msdn.microsoft.com/brian_jones/2005/06/27/introduction-to-excel-xml-part-1-creating-a-simple-table/

    https://blogs.msdn.microsoft.com/brian_jones/2005/06/30/intro-to-excel-xml-part-2-displaying-your-data/

    https://blogs.msdn.microsoft.com/brian_jones/2005/08/25/intro-to-excel-xml-part-3-displaying-your-data/

    4.关于excel-export的缺陷,因为是个开源的,所以只是实现了最基本的生成流功能。希望作者可以继续努力更新。

    excel的高级功能字体,颜色,合并单元格,公式当然是统统没有实现,具体可以看到sheet.js中的中的实现。

    5.结果

     导出多个sheets的时候的结果

     

    数据中最后为null一行,所以为null,不要说这个报错了。

    总结,如果要求不是太高的excel导出,可以使用此包,如果十分复杂的,建议还是研究下js-xlsx,对他进行封装

    最近实际开发中用到,有时候excel的文件导出时要用中文,这时候要设置下header和格式化中文即可

    res.setHeader('Content-Type', 'application/vnd.openxmlformats;charset=utf-8');
    res.setHeader("Content-Disposition", "attachment; filename=" +encodeURIComponent("导出列表")+".xlsx");

    转自:https://www.cnblogs.com/xiashan17/p/6214817.html

  • 相关阅读:
    进度条
    html5 表单新增事件
    html5 表单的新增type属性
    html5 表单的新增元素
    html5 语义化标签
    jq 手风琴案例
    codeforces 702D D. Road to Post Office(数学)
    codeforces 702C C. Cellular Network(水题)
    codeforces 702B B. Powers of Two(水题)
    codeforces 702A A. Maximum Increase(水题)
  • 原文地址:https://www.cnblogs.com/sky6699/p/12738930.html
Copyright © 2011-2022 走看看