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 这些都是习惯的书写方式了~
我得表格大概就长这个样子:
node.js上传并解析Excel文件_第1张图片

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;
           }
        }]
    });

你可能感兴趣的:(Angular,js,node,js,mongoose,node.js,mongodb,excel,nodejs,前端)