在上一篇推送,我提到了這樣一個需求:node
A上傳一份任務文件(文件類型不限)到網站上,B看到後下載文件,按照文件裏的要求完成任務以後,B要把任務完成狀況彙總到一個Excel文檔中,上傳到網站上(此時只能上傳xls格式的excel文檔),而後網站在後臺對這份Excel文檔的數據進行處理,生成一份新的Excel文檔。express
因此,我寫了一篇分享《node.js實現上傳與下載文件》。而此次,我想針對這個需求分享下:node.js讀寫excel文件。npm
有哪些外部模塊支持讀寫Exceljson
引入模塊app
編寫業務邏輯函數dom
上npm搜索過,發現支持讀寫excel文件的模塊有不少,可是都各有缺陷,有些僅支持xls/xlsx的一種格式,有些僅支持讀取數據,有些僅支持導出文件。例如:函數
node-xlsx: 基於Node.js解析excel文件數據及生成excel文件,僅支持xlsx格式文件;網站
excel-parser: 基於Node.js解析excel文件數據,支持xls及xlsx格式文件;ui
excel-export : 基於Node.js將數據生成導出excel文件,生成文件格式爲xlsx;excel
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不斷....