node.js上傳並解析Excel文件

2016-09-21
今天寫的 這個小實例,一般是用在有很多數據進行添加 的時候。

還是一個小前端,但是無奈於boss的壓力,只能自己寫接口,學nodejs mongodb 各種不懂[ 微笑臉 ]
因爲今天的內容中用到了-xlsx moment csv 等
下載一般就是用bower/npm來的
so …寫之前要先添加依賴文件

  , XLSX = require('xlsx')
  , moment = require('moment')
  , parse = require('csv-parse');

大致是分爲三個步驟:上傳文件、格式轉換、解析文件。我一個個來說~~
首先:
定義一個文件上傳的接口,像醬紫的一個POST接口:

app.post('/news/Import', function(req, res) {
    //添加內容
})

然後設置一些參數,差不多就這種:

form.encoding = 'utf-8';        //設置編碼
form.uploadDir = './upload/'; //設置上傳目錄
form.keepExtensions = true; //保留後綴
form.maxFieldsSize = 2 * 1024 * 1024;   //文件大小

好了,現在開始厲害了
做好準備工作之後,開始敲上傳代碼,在上傳中,就要進行轉換解析什麼的

form.parse(req, function(err, fields, files) {
        if (err) {
            res.statusCode = 400;
            res.send({
                error: '上傳文件錯誤。'
            });
            return;
        }

       //...添加轉換解析代碼
})

這裏的內容比較多,大概的內容就是說,在上傳完成之後,要先將excel文件轉換成.csv文件,然後再對應的單元格內讀取出對應的字段名稱,然後push出來就ok
聽起來 好…像…很…簡…單…然…而…
(先來解釋爲什麼要轉換爲.csv文件:百度中是這樣的:
csv是最早用在簡單的數據庫裏的….格式簡單開放性強,什麼什麼的。總之就是說非常容易被導入pc表格和數據庫中,此文件用記事本打開後,一行即爲數據表中的一行,數據之間半角逗號隔開)
還有代碼裏面的像什麼workbook、SheetNames 這些都是習慣的書寫方式了~
我得表格大概就長這個樣子:
這裏寫圖片描述

var result = [];
    var workbook = XLSX.readFile(files.file.path);
    workbook.SheetNames.forEach(function (sheetName) {
        var csvdatas = XLSX.utils.sheet_to_csv(workbook.Sheets[sheetName]);//獲取到行數據
        parse(csvdatas, function (err, output) {
            if (err || output.length < 4){//在csv文件中從第四行開始的有效數據
                return;
            }
            var yearStr = output[0][0];// yearStr取的是標題(也就是第一行第一列用下標表示爲[0][0]),output爲所有數據
            var index = yearStr.indexOf('年');  //返回"年"在字符串中首次出現的位置
            if (index == -1){
                return;
            }
            var year = yearStr.substr(0, index);   //substr方法截取字符串(0-“年”字一位)
            var array = [];
            for (var i = 3; i < output.length; i++) {//開始循環遍歷每一行數據判斷,如果月份爲空時(我這裏的固定的給出的表有可能月份爲空所以需判斷),則跳出
                var row = output[i];   //此處聲明瞭row爲行,row[i] 即表示每一行的數據
                    var month = row[0];
                    if (!month){//月份爲空則跳出
                        continue;
                    }
                    var month = month < 10 ? '0' + month : month;   //此處爲條件表達式 如果小於十月份則輸出:如01 02月 等 ,大於10月份直接輸出 如:11,12 月
                    var m = {
                        time: year+month,
                        name: row[2],//name是第二列
                        place: row[3],//place第三列
                        phone: row[4],//phone第四列    依次...

                    };
                    array.push(m);
                }
                news.create(array, function (err) {//create一個新的數組用來放重組好的數據
                    if (err){return;}
                })
            });
        });

….這樣就行了,一寫出來發現自己 還有好多邏輯上的不理解,明天問問老大去。
還有一種是在excel表中,不一定全部都是平行數據結構,也有一些要寫成obj對象的

 parse(csvdatas, function (err, output) {
                if (output.length < 4){
                    return;
                }
                var yearStr = output[0][0];//year
                var index = yearStr.indexOf('年');
                var mt = moment('2016年9月XXXX', 'YYYY年MM月XXXX');
                var result = [];
                for (var i = 3; i < output.length; i++) {
                    var row = output[i];
                    var obj = {//構建一個對象
                        index: '',
                        months: []
                    };
                    var lastIndex = 3 + mt.months() + 1;
                    if (row.length != lastIndex) continue;
                    obj.index = row[row.length - 1];
                    for (var j = 3; j < row.length - 1; ++j){
                        obj.months.push(row[j]);
                    }
                    var m = {
                        name: row[2],
                        place: row[3],
                        phone: row[4],
                        index: obj,
                        time: mt.format('YYYYMM')
                    };
                    result.push(m);
                }
                // console.log(result);
                Budget.create(result, function (err) {
                    if (err){return;}
                })
            });

看起來好暈,感覺天天知識爆炸,哈哈,也不錯~~

此處爲一條開心的分割線————————————————————————

2017/3/21

看到 有人 私信 說這個 我就看了之前的項目 再理清一下之前寫東西的邏輯
前端是用angular1 寫的

    $scope.uploaderCtl = new FileUploader({   //需要依賴注入FileUploader
        queueLimit: 1,
        autoUpload: true,
        url: 'http:....地址',
        filters: [{
           name: 'xlsefilter',
           fn: function(item) {
               var ext = item.name.substr(item.name.lastIndexOf(".")).toLowerCase(); //獲得文件後綴名
               if (ext == '.xlsx') return true;
               return false;
           }
        }]
    });
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章