繁体   English   中英

Node.js和Express.js创建一个大CSV文件(1GB)并从ajax客户端下载

[英]Node.js and Express.js create a large CSV file (1GB) and download it from ajax client

用户界面允许用户选择几个查询参数并通过AJAX提交。 服务器将使用参数查询mongoDB并在服务器上创建一个很大的CSV文件(30列/1.5MM行/〜1GB)。 创建文件后,服​​务器将使用URL响应AJAX调用以下载文件。 第二次调用服务器以下载CSV文件。

我的问题是扩展此解决方案...尝试从mongoDB检索超过50,000个记录时,Node.js内存不足。 系统正在使用4GB内存运行。

AJAX调用以创建和下载文件:

 handleExport: function (){
        NProgress.done();
        NProgress.start();
        var data = {spMle: this.state.spMle, custMle: this.state.custMle};
        $.ajax({
            type: 'POST',
            url: '/api/aps/export',
            data: data,
            success: function (filename){
                NProgress.done();
                var url = '/api/aps/export/download/' + filename
                $('body').append("<iframe src='" + url + "' style='display: none;' ></iframe>");
                //window.open(url);
            }
        });
    },

服务器请求从MongoDB查询创建CSV文件,并发送URL将文件下载回客户端:

var spMle       = req.body.spMle;
var custMle     = req.body.custMle;
var limit       = 50000;
var filename    = 'export.csv';
var path        = './public/downloads/' + filename;
var query       = ApsModel.find();
if (spMle !== "0"){query.where('SP_MLE_ID').equals(spMle);}
if (custMle !== "0"){query.where('Cust_MLE_ID').equals(custMle);}
if (limit){query.limit(limit);}

var writeStream = fs.createWriteStream(path);
writeStream.on('finish', function () {
    console.log('CSV file completed!');
    res.send(filename);
});
var readStream = query.stream({ transform: JSON.stringify});
var json2CsvStream = new Json2CsvStream();
json2CsvStream.on('header', function(data) {
  // console.log(' ++ yeah header found ++');
  // return console.log(data);
})
json2CsvStream.on('line', function(data) {
  console.log('row streamed');
  // return console.log(data);
});

readStream.pipe(json2CsvStream).pipe(writeStream);

服务器请求下载文件:

router.get('/aps/export/download/:filename', function (req, res){
    var path = './public/downloads/' + req.params.filename;
    res.download(path, "export.csv")
});

使用端到端流将其重构为以下数据流:

1)管道mongo查询2)管道数据到json-to-csv解析器3)管道解析的数据到客户端

jQuery调用:

handleExport: function (){
        var url ="/api/aps/export/" + this.state.spMle + "/" + this.state.custMle;
        $('body').append("<iframe src='" + url + "' style='display: none;' ></iframe>");
        //window.open(url);
    },

服务器响应:

/* GET aps export */
router.get('/aps/export/:spMle/:custMle', function (req, res){
    var spMle       = req.params.spMle;
    var custMle     = req.params.custMle;
    var limit       = 250000;
    var filename    = 'export.csv';
    var query       = ApsModel.find();
    if (spMle !== "0"){query.where('SP_MLE_ID').equals(spMle);}
    if (custMle !== "0"){query.where('Cust_MLE_ID').equals(custMle);}
    if (limit){query.limit(limit);} 
    var headers = {
        'Content-Type': 'text/csv',
        'Content-disposition': 'attachment;filename=' + filename
    }
    res.writeHead(200, headers)

    var mongoStream = query.stream({transform: JSON.stringify});
    var parser = new Json2CsvStream();

    //run streams
    mongoStream.pipe(parser).pipe(res)

});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM