Node实现数据库数据导入Excel

来源:互联网 发布:psvita 电池 淘宝 编辑:程序博客网 时间:2024/04/30 12:08

哎,好不容易写好了Python版本,为了以后便于集成到系统里又被要求用node实现一遍,任务要求还是没有变化,只是变了变语言,加了点额外小需求。这篇博客,就记录一下用node实现的过程。

1 用到的工具

要把数据从数据库导入Excel,需要和数据库搭配的库,和Excel搭配的库,再来一个查数据库的库就够了。所以我使用了如下modules:

  • pg,用于和PostgreSql搭配
  • node-xlsx,用于和Excel搭配
  • knex,当做query builder,这个是老朋友了,不会用的同学可以参考我之前写的《knex.js笔记》

node-xlsx可以读取Excel文件以及构造Excel文件格式的buffer。
模块的原理都是把Excel文件和数组之间的转换:
举个例子:

var data = [    ['name',age','gender'],    ['Alice','20','female'],    ['Bob','21','male'],     ['Error','-1','unknown'] ];var buffer = xlsx.build([{name: "data", data: data}]); fs.writeFile('result.xlsx',buffer);

因为node-xlsx没有写文件的功能,构造好buffer之后需要使用node自带的fs模块写文件。

上面这个数组转换得到的Excel就类似与下面这样:

name age gender Alice 20 female Bob 21 male Error -1 unknown

2 代码

“Talking is cheap,and code goes here.”


2.1 关键点1

因为是五张表联合查询,所以用到了join,knex对join的支持还是很全面的,我就选择inner join就可以了。

这里要注意!
Python的join,会将所有信息全部拼接在一起,所以会看到合并之后的表中有多个id字段,通过表名.id可以访问不同的id字段;
但是,knex会自己优化查询到的结果集,对于自身join的情况,重复的列名会被全部丢弃掉,所以涉及到自身join时,给要查询的列起个别名是很有必要的。


2.2 关键点2

因为这次是写命令行脚本而不是web应用,所以需要自己加上脚本退出的条件。
但是需要注意node异步的特点,加之这次的任务还涉及到文件写入,所以要考虑进程退出时,文件是否已经写完。
因此,我把process.exit()写在了fs.writeFile()的callback里面。


2.3 真正的代码

因为涉及内部数据,不可能把数据库公开,下列代码仅供参考:

var xlsx = require('node-xlsx');  var fs = require('fs');var config = require('./config');var knex = require('knex')({    client: 'pg',    connection: {        host: config.host,        user: config.username,        password : config.password,        database : config.database,        port: config.port    }});knex.select(    'site.name as site_name',                'study.name as study_name',                'sheets.id',                'sheets.patient_name',                'crf.label as crf_name',                'section.label as section_name',                'form_rows.uid',                'form_rows.label',                'sheet_row_values.value',                'form_rows.meta')    .from('sheet_row_values')    .join('form_rows','form_rows.uid','=','sheet_row_values.uid')    .join('form_groups as section','section.id','=','form_rows.group_id')    .join('form_groups as crf','section.parent_id','=','crf.id')    .join('sheets','sheets.id','=','sheet_row_values.sheet_id')    .join('departments as site','sheets.center_id','=','site.id')    .join('departments as study', 'site.parent_id','=', 'study.id')    .then(        function(results) {            var data = [                ['id','site_name','study_name','sheets.id','patient_name','crf_name','section_name','uid','label','value','name'],            ];            var len_row = results.length;            for(var i = 0;i<len_row;i++) {                var type = results[i].meta.type;                if(type == 'Radio' || type == 'Checkbox') {                    var options = results[i].meta.options;                    for(var j = 0;j<options.length;j++) {                        if(options[j].value == results[i].value) {                            var name = options[j].name;                        }                    }                } else {                    var name = null;                }                data.push([                    i+1,                    results[i].site_name,                    results[i].study_name,                    results[i].id,                    results[i].patient_name,                    results[i].crf_name,                    results[i].section_name,                    results[i].uid,                    results[i].label,                    results[i].value,                    name                ]);            }            var buffer = xlsx.build([{name: "data", data: data}]);             fs.writeFile('result.xlsx',buffer,function(){                process.exit();            });        }    );
1 0
原创粉丝点击