转载

node.js读写excel文件

需求

在上一篇推送,我提到了这样一个需求:

A上传一份任务文件(文件类型不限)到网站上,B看到后下载文件,按照文件里的要求完成任务之后,B要把任务完成情况汇总到一个Excel文档中,上传到网站上(此时只能上传xls格式的excel文档),然后网站在后台对这份Excel文档的数据进行处理,生成一份新的Excel文档。

所以,我写了一篇分享《node.js实现上传与下载文件》。而这次,我想针对这个需求分享下:node.js读写excel文件。

实现

思路

  • 有哪些外部模块支持读写Excel

  • 引入模块

  • 编写业务逻辑函数

支持读写Excel的node.js模块

上npm搜索过,发现支持读写excel文件的模块有很多,但是都各有缺陷,有些仅支持xls/xlsx的一种格式,有些仅支持读取数据,有些仅支持导出文件。例如:

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

  • excel-parser: 基于Node.js解析excel文件数据,支持xls及xlsx格式文件;

  • excel-export : 基于Node.js将数据生成导出excel文件,生成文件格式为xlsx;

  • node-xlrd: 基于node.js从excel文件中提取数据,仅支持xls格式文件。

在我的项目中,我使用的是noe-xlrd模块及excel-export模块,用于提取上传上来的excel文件里的数据,以及生成新的excel文件。

引入模块

编辑项目工程里的package.json文件:

{   "name": "appname",   "virsion": "0.0.1",   "dependencies": {     "express": "~4.8.8",     "node-xlrd": "0.2.4",     "excel-export": "0.4.1"   } }

执行node命令安装模块

npm install

编写业务逻辑函数

1.解析excel文件数据

var xl = require('node-xlrd'); exports.read = function(req, res, next){  var path = 'test.xls';  var datas = [];  xl.open(path, function(err,bk){   if(err) {console.log(err.name, err.message); return;}   var shtCount = bk.sheet.count;   for(var sIdx = 0; sIdx < shtCount; sIdx++ ){    console.log('sheet "%d" ', sIdx);    console.log('  check loaded : %s', bk.sheet.loaded(sIdx) );    var sht = bk.sheets[sIdx],     rCount = sht.row.count,     cCount = sht.column.count;    console.log('  name = %s; index = %d; rowCount = %d; columnCount = %d', sht.name, sIdx, rCount, cCount);    for(var rIdx = 0; rIdx < rCount; rIdx++){ // rIdx:行数;cIdx:列数     var data = [];     for(var cIdx = 0; cIdx < cCount; cIdx++){      try{       data[cIdx] = sht.cell(rIdx,cIdx);       console.log('  cell : row = %d, col = %d, value = "%s"', rIdx, cIdx, sht.cell(rIdx,cIdx));      }catch(e){       console.log(e.message);      }     }     datas[rIdx] = data;    }   }   req.datas = datas;  }); }; 

解析出来的数据有不同的数据类型:string、number。可以用 typeof sht.cell(rIdx,cIdx) 检测数据类型。

2.将处理后的数据生成新的excel文件

var excelPort = require('excel-export'); exports.write = function(req, res, next){  var datas = req.datas;  var conf = {};  var filename = 'filename';  //只支持字母和数字命名  conf.cols = [     {caption:'名称', type:'string', width:20},     {caption:'简介', type:'string', width:40},     {caption:'报酬', type:'string', width:20},     {caption:'时间', type:'date', width:40},     {caption:'人员', type:'string', width:30},     {caption:'编号', type:'string', width:30},     {caption:'金额', type:'number', width:30},     {caption:'手机号', type:'string', width:30}  ];  var array = [];  array[0] = [   datas[0][0],     datas[0][1],     datas[0][2],     datas[0][3],     datas[0][4],     datas[0][5],     datas[0][6],     datas[0][7]  ];  conf.rows = array[0];  var result = excelPort.execute(conf);  var random = Math.floor(Math.random()*10000+0);  var uploadDir = 'public/upload/pay/';  var filePath = uploadDir + filename + random + ".xlsx";  fs.writeFile(filePath, result, 'binary',function(err){   if(err){    console.log(err);   }  }); } 

caption设置首行各单元格内容,type设置的是每一列的数据类型,width设置单元格大小。

rows 赋值的是每一行的数据,每个数据都要与所在列所设置的数据格式一致,否则会报错,生成后的表格该单元格会显示NaN。

总结

在读取解析完excel文件里的数据后,一般要根据项目需求对数据进行处理。进行数据处理时,要格外注意所解析到的数据的数据类型,以及要生成新的表格时,处理后的数据的数据类型是否符合所设置的数据类型。否则,bug不断....

正文到此结束
Loading...