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