【转载】使用NODEJS生成Excel报表文件并下载
引言:日常工作中已经有许多应用功能块使用了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
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
<!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下载
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
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: falserouter.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
(6).ejsexcle使用ejs模版引擎
作者:IT小C
链接:https://www.jianshu.com/p/48dc84f391c0
來源:简书
这里采用的是ejsExcel,实现在Node.js端导出excel,采用的是模板+数据的形式,定义好模板,往里面放数据,简单易行好维护,使用的是Nodejs的ejsExcel导出excel插件
采用这种方法导出需要先定义好要导出的表的模板,然后数据部分采用ejs格式来实现
https://github.com/sail-sail/ejsExcel
1.安装
npm install ejsexcel
2.加载ejsExcel库和fs库
var ejsExcel=require("./ejsExcel");
var fs=require("fs");
3.创建excel模板
循环数据结果集
<%for RBegin rs1,i in _data_%>
<%for REnd(1)%>
渲染数据
<%=rs1.id%>
4.从数据库读取数据后渲染到excel模板中
//获得Excel模板的buffer对象
var exlBuf=fs.readFileSync("./public/excelop/template/finance_d.xlsx");
var excelname="~"+y+m+d+hh+mm+ss+".xlsx";//数据源
var sql1="select*frombookingwherebookingnolike'"+key+"%'";
mysql.query(sql1,function(error,obj){
if(error){console.log(error);returnfalse;}//用数据源(对象)data渲染Excel模板/
ejsExcel.renderExcelCb(exlBuf,obj,function(exlBuf2){
fs.writeFileSync("./public/excelop/temp/"+excelname,exlBuf2);
res.send(excelname);
});
});
官方模板
Excel表格中需要数据的单元格
<%=data[0].table_name%>
Nodejs服务器端代码
var ejsExcel = require("../ejsExcel");
var fs = require("fs");
//获得Excel模板的buffer对象
var exlBuf = fs.readFileSync("./template1.xlsx");
//数据源
var data = [{"table_name":"现金报表"}];
//用数据源(对象)data渲染Excel模板
ejsExcel.renderExcelCb(exlBuf, data, function(exlBuf2){
fs.writeFileSync("./report1.xlsx", exlBuf2);
console.log("生成report1.xlsx");
});
最后在服务器端返回生成的excel表路径到客户端就可以下载了
其他导出Excel方法可以参考

浙公网安备 33010602011771号