使用NodeJS将数据从xlsx文件移动到SQL Server

时间:2017-04-21 01:49:32

标签: node.js excel xlsx

我目前的任务是编写一个应用程序,使用带有xlsx包的NodeJS将数据从Excel工作表传输到SQL Server表。

首先,我对异步编程的概念非常陌生,而且我也是使用NodeJS的新手。如果你能够彻底解释它,那将非常有帮助。

问题: 我的Excel表有8个列标题,我应该从第2行到结尾获取数据(类似于A2到H2,A3到H3,依此类推,直到行结束)。

我打电话     节点服务 在我的git-bash中。它将读取文件excel文件,每行循环访问它,console.log()就像这样:

Data of index 2000 7/10/16 20161007142953_BP12350 COV_DEB_20161007142953_BP12350 0 50000 3896 51 A 0145 Takengon / 3986 UNIT SIMPANG BALIK TAKENGON
Data of index 2001 7/10/16 20161007142954_BP12350 FEE_DEB_20161007142953_BP12350 0 50000 3896 51 A 0145 Takengon / 3986 UNIT SIMPANG BALIK TAKENGON

,然后我使用INSERT INTO查询它,如下面的runner.js所示。我想要做的是每次读取1000行间隔15000ms(因为每个excel文件大约有40,000行数据)。

有时我会收到Connection Timeout或UnhandledPromiseRejectionWarning错误。我该如何处理?

这是我的service.js

var util = require('util');
var sql = require('mssql');
var db = require('./doSql');
var runner = require('./runner');

var timeInterval = 15000;

var readData = setInterval(runner.readDataXL, timeInterval);

这是我的runner.js

var util = require('util');
var fs = require('fs');
var sql = require('mssql');
var db = require('./doSql');
var settings = require('./settings')
var async = require('async');
if (typeof require !== 'undefined') XLSX = require('xlsx');

var add = 50;

var runner = {

    readDataXL: function () {
        var workbook = XLSX.readFile(__dirname + '/file/test2.xlsx');
        // var sheetname = workbook.Props.DocParts[0];
        var sheetname = workbook.Props.SheetNames[0];

        var length = (workbook.Sheets[sheetname]['!ref']).substr(4, workbook.Sheets[sheetname]['!ref'].length);
        var effdate, kodebatch, transdesc, debit, kredit, user, id, branch = "";

        // console.log(workbook);
        var index = 1;
        var indexj = 1;
        async.each(workbook.Sheets[sheetname], function (item, callback) {
            var dataAwal = item;

            if (index > 9) {
                switch (indexj) {
                    case 1:
                        effdate = dataAwal['w'];
                        indexj++;
                        break;
                    case 2:
                        kodebatch = dataAwal['w'];
                        indexj++;
                        break;
                    case 3:
                        transdesc = dataAwal['w'];
                        indexj++;
                        break;
                    case 4:
                        debit = dataAwal['w'];
                        indexj++;
                        break;
                    case 5:
                        kredit = dataAwal['w'];
                        indexj++;
                        break;
                    case 6:
                        user = dataAwal['w'];
                        indexj++;
                        break;
                    case 7:
                        id = dataAwal['w'];
                        indexj++;
                        break;
                    case 8:
                        branch = dataAwal['w'];
                        indexj++;
                        var all = util.format("Data of index " + parseInt(index / 8) + " " + effdate + " " + kodebatch + " " + transdesc + " " + debit + " " + kredit + " " + user + " " + id + " " + branch);
                        console.log(all);
                        var sqlgiropremi = "INSERT INTO [ownerList].dbo.Rekonsiliasi_Premi_Fahmi_Test values('" + effdate + "','" + kodebatch + "','" + transdesc + "','" + debit + "','" + kredit + "','" + user + "','" + id + "','" + branch + "','" + parseInt(index / 8) + "')";
                        db.executeSql(sqlgiropremi, function (data, err) {
                            if (err) {
                                console.log("sql : " + sqlgiropremi + "error : " + err)
                            } else {
                                console.log("success ");
                            }
                        });
                        indexj = 1;
                        break;
                }
            }
            index++;
        });
    }
}

module.exports = runner;

这是我的doSql.js

var sqlDB = require('mssql');
var util = require('util');
var settings = require('./settings');

module.exports.executeSql = function (sql, callback) {
    var conn = new sqlDB.ConnectionPool(settings.dbConfig);
    conn.connect()
        .then(function () {
            var transaction = new sqlDB.Transaction(conn);
            transaction.begin()
                .then(function () {
                    var rolledBack = false;

                    transaction.on('rollback', function (aborted) {
                        rolledBack = true;
                    });

                    var request = new sqlDB.Request(transaction);

                    request.query(sql)
                        .then(function (recordset) {
                            transaction.commit()
                                .then(function (err) {
                                    callback(recordset);
                                })
                                .catch(function (err) {
                                    console.log("transaction error : ", err);
                                });
                        })
                        .catch(function (err) {
                            if (!rolledBack) {
                                transaction.rollback()
                                    .then(function (err_) {
                                        console.log(err);
                                        callback(null, err);
                                    })
                                    .catch(function (err_) {
                                        console.log("request error : ", err);
                                        callback(null, err);
                                    })
                            }
                        })
                })
                .catch(function (err) {
                    console.log("begin error : ", err);
                    callback(null, err);
                });
        })
        .catch(function (err) {
            console.log("connect error : ", err);
            callback(null, err);
        })
    sqlDB.close();
}

有时我会获得成功条目,有时会出现这样的错误:

sql : INSERT INTO [ownerList].dbo.Rekonsiliasi_Premi_Fahmi_Test values('7/10/16','20161007142953_BP12350','COV_DEB_20161007142953_BP12350','0','50000','3896','51','A 0145 Takengon / 3986 UNIT
    SIMPANG BALIK TAKENGON','2000')error : ConnectionError: Failed to connect to 192.168.43.179:1433 - connect EADDRINUSE 192.168.43.179:1433
    connect error :  { ConnectionError: Failed to connect to 192.168.43.179:1433 - connect EADDRINUSE 192.168.43.179:1433
        at Connection.tedious.once.err (C:\Users\DELL\Node JS\XLSX\node_modules\mssql\lib\tedious.js:216:17)
        at Connection.g (events.js:291:16)
        at emitOne (events.js:96:13)
        at Connection.emit (events.js:188:7)
        at Connection.socketError (C:\Users\DELL\Node JS\XLSX\node_modules\tedious\lib\connection.js:699:14)
        at C:\Users\DELL\Node JS\XLSX\node_modules\tedious\lib\connection.js:590:25
        at Socket.onError (C:\Users\DELL\Node JS\XLSX\node_modules\tedious\lib\connector.js:48:9)
        at emitOne (events.js:96:13)
        at Socket.emit (events.js:188:7)
        at emitErrorNT (net.js:1276:8)
      code: 'ESOCKET',
      originalError:
       { ConnectionError: Failed to connect to 192.168.43.179:1433 - connect EADDRINUSE 192.168.43.179:1433
           at ConnectionError (C:\Users\DELL\Node JS\XLSX\node_modules\tedious\lib\errors.js:12:12)
           at Connection.socketError (C:\Users\DELL\Node JS\XLSX\node_modules\tedious\lib\connection.js:699:30)
           at C:\Users\DELL\Node JS\XLSX\node_modules\tedious\lib\connection.js:590:25
           at Socket.onError (C:\Users\DELL\Node JS\XLSX\node_modules\tedious\lib\connector.js:48:9)
           at emitOne (events.js:96:13)
           at Socket.emit (events.js:188:7)
           at emitErrorNT (net.js:1276:8)
           at _combinedTickCallback (internal/process/next_tick.js:74:11)
           at process._tickCallback (internal/process/next_tick.js:98:9)
         message: 'Failed to connect to 192.168.43.179:1433 - connect EADDRINUSE 192.168.43.179:1433',
         code: 'ESOCKET' },
      name: 'ConnectionError' }
    sql : INSERT INTO [ownerList].dbo.Rekonsiliasi_Premi_Fahmi_Test values('7/10/16','20161007142954_BP12350','FEE_DEB_20161007142953_BP12350','0','50000','3896','51','A 0145 Takengon / 3986 UNIT
    SIMPANG BALIK TAKENGON','2001')error : ConnectionError: Failed to connect to 192.168.43.179:1433 - connect EADDRINUSE 192.168.43.179:1433
    (node:3576) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): ConnectionError: Failed to connect to 192.168.43.179:1433 - connect EADDRINUSE 192.168.43.179:1433
    (node:3576) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 4): ConnectionError: Failed to connect to 192.168.43.179:1433 - connect EADDRINUSE 192.168.43.179:1433
    (node:3576) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 6): ConnectionError: Failed to connect to 192.168.43.179:1433 - connect EADDRINUSE 192.168.43.179:1433
    (node:3576) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 8): ConnectionError: Failed to connect to 192.168.43.179:1433 - connect EADDRINUSE 192.168.43.179:1433
    (node:3576) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 10): ConnectionError: Failed to connect to 192.168.43.179:1433 - connect EADDRINUSE 192.168.43.179:1433

如果有更好的方法来循环或如何实现它,请指导我。

1 个答案:

答案 0 :(得分:0)

我意识到我正在回答一个非常老的问题,但是由于发现该问题的代码很有帮助,所以我认为我也应该指出我看到的问题。

executeSql是从异步循环调用的,它本身也调用异步函数。我认为连接错误是由connect()调用引起的,该调用是在每次executeSql调用时产生的,这意味着当某些先前调用的连接仍在进行时,它可能会尝试连接。您可以通过将connect()调用移到executeSql函数之外来解决问题(但它仍可以位于doSql.js的顶部)。因此,连接仅建立一次,然后可用于多个查询。