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();
        },
        width: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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM