如何导出csv nodejs

时间:2013-08-19 03:30:15

标签: node.js mongodb mongoose

嘿我正在尝试从node.js导出csv(从mongodb中提取数据)。我已经将数据拉动并用逗号分隔所有,但现在我想弄清楚如何实际发送它......我将这段代码粘贴在我的路径文件中。有关如何获取数据数据并根据要求直接发送给用户的任何建议。

这里是代码:(我尝试了代码的底部部分第二个函数)

exports.downloadContacts = function(req, res) {
    async.waterfall([
        function(callback) {
            var source = [];
            Friend.find({userId: req.signedCookies.userid}, function(err, friends) {
                if(err) {console.log('err with friends for download');
                } else {
                    var userMap = {};
                    var friendIds = friends.map(function (user) {
                        userMap[user.friend_id] = user;
                        return user.friend_id;
                    });
                    console.log(friends);
                    User.find({_id: {$in: friendIds}}, function(err, users) {
                        if(err) {console.log(err); 
                        } else {
                            for(var i = 0; i < users.length; i++) {
                                console.log('users')
                                //console.log(users[i]);
                                source.push(users[i].firstNameTrue, users[i].lastNameTrue, users[i].emailTrue, users[i].phone, users[i].emailList, users[i].phoneList)
                            }
                            console.log(source);
                            callback(null, source);
                        }


                    });
                }


            });

        }
    ],
    function(err, source) {
        var result = [];

        res.contentType('csv');

        csv()
        .from(source)
        .on('data', function(data){ 
            result.push(data.join());
        })
        .on('end', function(){
            res.send(result.join('\n'));
        });
    });     
};

9 个答案:

答案 0 :(得分:23)

您是否尝试过类似“内容类型为”application / octet-stream“

的内容
res.set('Content-Type', 'application/octet-stream');
res.send(<your data>);

或只是

res.send(Buffer.from(<your data>));

Express send() docs.

答案 1 :(得分:19)

这是我做的:

  1. 使用json2csv从mongodb数据构建csv数据
  2. var json2csv = require('json2csv');
    var fields = ['name', 'phone', 'mobile', 'email', 'address', 'notes'];
    var fieldNames = ['Name', 'Phone', 'Mobile', 'Email', 'Address', 'Notes'];
    var data = json2csv({ data: docs, fields: fields, fieldNames: fieldNames });
    
    1. 将csv数据发送到客户端
    2. res.attachment('filename.csv');
      res.status(200).send(data);
      

答案 2 :(得分:3)

大家好基于@VierTD回答你必须使用json2csv从mongodb数据构建csv数据

使用dependecies更新Package.json

  "dependencies": {
    "mongodb": "^2.2.10",
    "json2csv": "*",
    "express": "*"
  }

创建json2CSV对象,记住这是映射您的文档(db表),因此“fields”上的名称必须与db table匹配,fieldNames由您决定,但也很重要,因为这些是CSV文件列名

var json2csv = require('json2csv');
var fields = ['name', 'phone', 'mobile', 'email', 'address', 'notes'];
var fieldNames = ['Name', 'Phone', 'Mobile', 'Email', 'Address', 'Notes'];
var data = json2csv({ data: docs, fields: fields, fieldNames: fieldNames });

将csv数据发送到客户端

res.attachment('filename.csv');
res.status(200).send(data);

This code显示了如何基于mongo db文档(数据库表)导出csv文件

我创建了一个github repo非常简短的抽样概念,还在Mongo Lab Website创建了一个带有虚拟数据的数据库,因此这段代码将在您的计算机中立即运行。基于@VietTD回答!

如果您对测试此代码感兴趣,请记住更改以下行

更改数据库网址(用户自己的数据库,但这仅用于显示目的; D)

        var url = 'mongodb://admin:detroit123@ds063946.mlab.com:63946/misale_dev';

更改目标文档(或数据库表)

var collection = db.collection('_dummy');

更改文档列(或db表的列字段)

var fields = ['_id', 'JobID', 'LastApplied'];

最后设置CSV标题列名称以及CSV文件名

var fieldNames = ['ID_OR_PK', 'JOB_UNIQUE_ID_TITLE', 'APPLICATION_DATE'];

最后但并非最不重要

res.attachment('yourfilenamehere.csv');

请随意改进示例代码我会很感激!或者只是下载它并查看代码,它已经附带数据库,因此它很容易理解和运行,在这种情况下你不在乎这里是整个代码也许你看到一些有趣的东西:

//
// EXPRESS JS SERVER INITI
//
var express = require('express')
var app = express()

//
// MONGO DB INIT
//
var MongoClient = require('mongodb').MongoClient, assert = require('assert');
app.get('/', function (req, res) {
    var url = 'mongodb://admin:detroit123@ds063946.mlab.com:63946/misale_dev';
    //
    // This function should be used for migrating a db table to a TBD format
    //
    var migrateMongoDBTable = function(db, callback) {
        // Get the documents collection
        console.log("Reading database records");
        // Get the documents collection
        var collection = db.collection('_dummy');
        // Find some documents
        //collection.find({'a': 3}).toArray(function(err, docs) {
        collection.find({}).toArray(function(err, docs) {
          assert.equal(err, null);
          //console.log(docs);
          //console.log('docs.length ---> ', docs.length);
          console.log('Creating CSV...');
          //console.log('-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=');
          var json2csv = require('json2csv');
          var fields = ['_id', 'JobID', 'LastApplied'];
          var fieldNames = ['ID_OR_PK', 'JOB_UNIQUE_ID_TITLE', 'APPLICATION_DATE'];
          var data = json2csv({ data: docs, fields: fields, fieldNames: fieldNames });
          //console.log('-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=');
          // EXPORT FILE
          res.attachment('yourfilenamehere.csv');
          res.status(200).send(data);
          callback(docs);
        });
    };

    // Use connect method to connect to the server
    MongoClient.connect(url, function(err, db) {
      assert.equal(null, err);
      console.log("Connected successfully to server");
      //
      // migrate db table to some format TBD
      //
      migrateMongoDBTable(db, function() {
        db.close();
      });
    });

})

app.listen(3000, function () {
  console.log('Example app listening on port 3000!')
})
// Connection URL
//var url = 'mongodb://localhost:27017/myproject';

<强>谢谢!

答案 3 :(得分:2)

我不完全确定您的问题是什么,但我认为您正在寻找的内容可以通过设置Content Disposition标头来解决。看看另一个SO问题的回答:https://stackoverflow.com/a/7288883/2320243

答案 4 :(得分:1)

Express-csv是一个很好的模块,用于将csv内容写入来自node.js服务器的流,该服务器将作为响应发送到客户端(并作为文件下载)。非常容易使用。

app.get('/', function(req, res) {
  res.csv([
    ["a", "b", "c"]
  , ["d", "e", "f"]
  ]);
});

文档:https://www.npmjs.com/package/express-csv

传递对象时,需要明确地添加标题(如果需要)。这是我使用npm mysql

的示例
router.route('/api/report')
    .get(function(req, res) {
            query = connection.query('select * from table where table_id=1;', function(err, rows, fields) {
                if (err) {
                    res.send(err);
                }
                var headers = {};
                for (key in rows[0]) {
                    headers[key] = key;
                }
                rows.unshift(headers);
                res.csv(rows);
            });
    });

答案 5 :(得分:0)

我在此http://nikgrozev.com/2017/05/10/mongo-query-to-CSV-download-expressjs/

找到了解决方案

关键字

  

将输出流传输到HTTP响应

答案 6 :(得分:0)

使用json2csv库,您可以从mongodb数据中导出csv。

const json2csv = require('json2csv').parse;

//For unique file name
const dateTime = new Date().toISOString().slice(-24).replace(/\D/g, 
'').slice(0, 14); 

const filePath = path.join(__dirname, "../../../", "public", "exports", "csv-" 
+ dateTime + ".csv");

let csv; 

const student = await req.db.collection('Student').find({}).toArray();

// Logging student
// [{id:1,name:"John",country:"USA"},{id:1,name:"Ronny",country:"Germany"}]

const fields = ['id','name','country'];

 try {
    csv = json2csv(booking_info, {fields});
 } catch (err) {
    return res.status(500).json({err});
 }

 fs.writeFile(filePath, csv, function (err) {
    if (err) {
        return res.json(err).status(500);
    }
    else {
        setTimeout(function () {
            fs.unlink(filePath, function (err) { // delete file after 30 sec
            if (err) {
                console.error(err);
            }
            console.log('File has been Deleted');
        });

    }, 30000);
        res.download(filePath);
    }
})

答案 7 :(得分:0)

json2csv软件包自撰写最高投票答案以来已得到更新,新版本的语法略有不同:

        var { Parser } = require('json2csv')

        const fields = [{
            label: 'header 1',
            value: 'field1_name'
        }, {
            label: 'header 2',
            value: 'field2_name'
        }]

        const json2csv = new Parser({ fields: fields })

        try {
            const csv = json2csv.parse(data)
            res.attachment = ('data.csv')
            res.status(200).send(csv)
        } catch (error) {
            console.log('error:', error.message)
            res.status(500).send(error.message)
        }

答案 8 :(得分:0)

回答为时已晚,但对于那些需要在 2021 年优化、耗时更少的解决方案的人来说

以上所有解决方案都很好,但有

  1. 时间复杂度 O(n)

  2. 存储复杂性或高内存使用问题有时会因为请求过多而导致应用程序崩溃

解决办法: 当用户对 DB 进行 CRUD 操作时维护一个同步的 CSV 文件 例如在放置请求中

app.put('/product/:id', (res,req)=>{
    // step 1 do update operation in db
    // step 2 do update operation in CSV file

    return res.send('OK 200')

})

这样下次当用户请求 CSV 用户可以立即获取 CSV 文件

快乐编码:)