node.js读写excel文件

ygfb 8年前

需求

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

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不断....