source

csv nodejs를 내보내는 방법

manycodes 2023. 5. 11. 21:34
반응형

csv nodejs를 내보내는 방법

안녕하세요. 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'));
        });
    });     
};

제가 한 일은 다음과 같습니다.

  1. json2csv를 사용하여 mongodb 데이터에서 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 });
  1. 클라이언트에 CSV 데이터 전송

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

콘텐츠 유형을 "응용 프로그램/옥텟 스트림"으로 지정하여 이와 같은 작업을 해본 적이 있습니까?

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

아니면 간단히

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

빠른 전송() 문서입니다.

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

res.confection은 함수이며 속성이 아닙니다.이 작업을 수행하려면 등호를 제거해야 합니다.

@Vier 기준TD 답변, mongodb 데이터에서 csv 데이터를 구축하려면 json2csv를 사용해야 합니다.

패키지 업데이트.종속 요소가 있는 json:

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

json2를 생성합니다.CSV 개체는 문서(db 테이블)를 매핑하는 것이므로 "필드"의 이름이 db 테이블과 일치해야 합니다. 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);

코드는 mongodb 문서(데이터베이스 테이블)를 기반으로 csv 파일을 내보내는 방법을 보여줍니다.

는 아이디어를 간단히 샘플링하는 github repo를 만들었고 Mongo Lab 웹사이트에서 더미 데이터로 데이터베이스를 만들어서 이 코드가 당신의 컴퓨터에서 즉시 실행될 수 있도록 했습니다.@Viet 기준TD 답변.

이 코드를 테스트하는 데 관심이 있는 경우 다음 행을 변경하는 것을 기억하십시오.

dburl 변경(사용자 자신의 db가 작동하지만 표시 목적으로만 사용됨).

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

대상 문서(또는 DB 표)를 변경합니다.

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';

질문하신 내용이 무엇인지는 잘 모르겠습니다만, 찾으시는 내용은 내용 정리 헤더를 설정하여 해결할 수 있을 것 같습니다.또 다른 SO 질문인 https://stackoverflow.com/a/7288883/2320243 에서 이 답변을 확인해 보십시오.

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(student, {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);
    }
})

실제 사례가 도움이 될 수 있습니다.

백엔드 - 노드J

router.js

var { Parser } = require('json2csv');
const dataService = require('../service');

router.get('/exportData', cors(), async (req, res) => {
    const list = await dataService.getData(req);
    const fields = [
        { label: 'Id', value: 'Id' },
        { label: 'Name', value: 'Name' },
        { label: 'Age', value: 'Age' },
        { label: 'Date', value: 'Date' },
    ];
    const json2csv = new Parser({ fields: fields });
    const csv = json2csv.parse(list);
    res.status(200).send(Buffer.from(csv));
});

서비스.제이에스

const sequelize = require('sequelize');
const moment = require('moment');
const { CallLogs } = require("../models");
const { Op } = sequelize;

exports.getData = async (req) => {
    let list = [];
    try {
        const { query: { Date_gte, Date_lt } } = req;
        const request = {
            where: {},
            order: [['Date', 'DESC']],
        };
        if (Date_gte && Date_lt) {
            request.where.Date = {
                [Op.between]: [Date_gte, Date_lt]
            }
        } else {
            if (Date_gte) {
                request.where.Date = {
                    [Op.gte]: Date_gte
                }
            }
            if (Date_lt) {
                request.where.Date = {
                    [Op.lt]: Date_lt
                }
            }
        }

        list = JSON.parse(JSON.stringify(await CallLogs.findAll(request)));

        list = list.map(c => {
            let obj = { ...c };
            obj.Date = moment(new Date(obj.Date)).format('DD.MM.YYYY');
            return obj;
        });
    } catch (error) {
        console.log(error);
    }
    return list;
}

프론트 엔드 - 반응

app.js

import download from "downloadjs";
import Axios from "axios";

async function exportResultToExcel() {
    try {
        let filters = { ...this.state.filter };
        const res = (await Axios.get(`api/exportData`, {
            params: filters,
            responseType: "blob"
        })).data;
        if (res) {
            download(res, new Date().toLocaleDateString() + '-data.csv');
        } else {
            alert("Data not found");
        }
    } catch (error) {
        console.log(error);
    }
}

<Button onClick={() => { this.exportResultToExcel() }}>Export to CSV</Button>

Express-csv는 node.js 서버에서 스트리밍할 CSV 콘텐츠를 작성하는 데 유용한 모듈로, 클라이언트에 대한 응답으로 전송되고 파일로 다운로드됩니다.매우 사용하기 쉽습니다.

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

모듈을 사용하지 않으려면 두 단계로 나눕니다.

1단계: JSON을 플랫 어레이로 변환

여기서 중요한 것은 JSON 키가 배열의 첫 번째 행이 된다는 것입니다.

/**
 * Convert JSON list of objects to 2D array
 * Headers from first list item create first row of array
 * @param Array JSON list of objects
 * @return Array 2D array with first row as the object keys from the first object in list
 */
function json2array (data) {
  let headers = []
  let output = new Array(data.length + 1)
  // get object keys for first item if one exists
  if (data.length > 0) headers = Object.keys(data[0])
  output[0] = headers
  data.forEach((dataRow, row) => {
    const outputRow = new Array(headers.length)
    // populate array
    headers.forEach((header, column) => {
      outputRow[column] = dataRow[header]
    })
    output[row + 1] = outputRow
  })
  return output
}

// jsonData = [{email: "user1@example.com", name: "John"}, {email: "user2@example.com", name: "Jane"}] 

const arr = json2array(jsonData)

// arr = [["email", "name"],["user1@example.comm", "John"],["user2@example.com", "Jane"]]

2단계: 2D 어레이를 CSV로 변환

그런 다음 파일에 저장하거나 브라우저에 출력할 수 있습니다.

/**
 * Convert a 2D array into CSV notation
 * @param Array a 2D array with the first row as headers
 * @return String CSV-formatted text
 */
function array2csv (arr) {
  let csvOut = ''
  arr.forEach((arrRow, rowNum) => {
    let csvRow = ''
    arrRow.forEach((value, colNum) => {
      if (colNum > 0) csvRow += ',' // comma-separate columns
      const valueType = typeof(value)
      if (valueType == 'number') csvRow += value
      else if (valueType == 'boolean') csvRow += value ? 'TRUE':'FALSE'
      // quote strings and handle existing quotes
      else csvRow += '"' + value.replace(/"/g, '""') + '"'
    })
    if (rowNum > 0) csvOut += "\n" // newline-split rows
    csvOut += csvRow
  })
  return csvOut
}

const csvOut = array2csv(arr)

/*
"email","name"
"user1@example.com","John"
"user2@example.com","Jane"
*/

이 방법들은O(n)복잡성

http://nikgrozev.com/2017/05/10/mongo-query-to-CSV-download-expressjs/ 에서 해결책을 찾았습니다.

키워드

출력을 HTTP 응답으로 스트리밍합니다.

다음은 CSV 파일을 생성하는 프로세스입니다.

설치하다

npm i fs-extra

다음과 같은 파일 만들기

const fse = require('fs-extra');
const fs = require('fs');
const csvInstant_save = exports.csvInstant_save = (data=[], filePath='') => {

    let csvContent = "";

    let header = Object.keys(data[0]);
    csvContent += header + "\r\n";
    
    data.forEach(function(rowArray) {
        let row_data = Object.values(rowArray)
        let row = row_data.join(",");
        csvContent += row + "\r\n";
    });
    
    fse.ensureFileSync(filePath)

    const writeStream = fs.createWriteStream(filePath, {encoding: 'utf8'});
    writeStream.write(csvContent);
}

함수를 다음과 같이 호출합니다.

const exceljshelper = require('../helpers/exceljshelper');

exceljshelper.excelInstant_save(data, './app/public/uploads/exports/user/excel/users-data-'+todayYMD+'.csv')

언급URL : https://stackoverflow.com/questions/18306013/how-to-export-csv-nodejs

반응형