0

I want to send the CSV file from Server to Client. I have JSON Objects which I am getting from MongoDB with ExpressJS Response.

Here is my Code for NodeJS Which is Accepting a Post Request from Client with Id's in the Body and with a Collection Name Parameter, and in Response, it fetches the data related to those Ids.

app.post('/api/v1/imagelist_data/raw-data/:db', function(req, res) {
    console.log("I received a NEW POST raw-data request");
    var dbname = req.params.db;

    var myarray = req.body._id;

    //  Setting Collection Name
    var mycollection = db.collection(dbname);

    // Convert the list of ids to mongo object ids
    var objectIds = myarray.map(function(item) {
        return mongojs.ObjectId(item);
    });

    console.log(objectIds);

    mycollection.find({
        _id: {
            $in: objectIds
        }
    }, function(err, docs) {

        res.json(docs);


    });

Now am getting the Array of Objects in Response at the Client Side. I want to make a CSV File with these Array of Objects.

Arrays of Objects looks like this.

[
{
    "_id": "58405524d70210dc299ca275",
    "pictureNumber": 1,
    "scAttitude": [
        0,
        0,
        0,
        1
    ],
    "scPosition": [
        1,
        0,
        0
    ],
    "integrationTime": 10,
    "time": "2016-12-01T16:51:57.000Z",
    "offset": 1,
    "gain": 2,
    "ledStatus": false,
    "imageType": "Image",
    "cameraType": "Mongo",
    "testPatternStatus": false,
    "temperatureCCD": 189,
    "temperatureLED1": 162,
    "temperatureLED2": 152,
    "temperatureVBG": 490,
    "temperatureGND": 0,
    "imageValid": true,
    "remarks": " Reception time: Thu Dec 01 17:51:47 CET 2016",
    "imageSize": 2271320
},
{
    "_id": "586bc534b31a89bb45b0083e",
    "pictureNumber": 2,
    "scAttitude": [
        1,
        0,
        0,
        1
    ],
    "scPosition": [
        1,
        0,
        0
    ],
    "integrationTime": 20,
    "time": "2016-12-02T16:51:57.000Z",
    "offset": 2,
    "gain": 0,
    "ledStatus": false,
    "imageType": "Image",
    "cameraType": "MOngo",
    "testPatternStatus": false,
    "temperatureCCD": 189,
    "temperatureLED1": 162,
    "temperatureLED2": 152,
    "temperatureVBG": 490,
    "temperatureGND": 0,
    "imageValid": true,
    "remarks": " Reception time: Thu Dec 01 17:51:47 CET 2016",
    "imageSize": 2271320
}]

Should I do this Processing at the Server Side or Client Side?

I want to download the CSV file with the data at the client side with the click of the button.

How can I achieve this?

2 Answers 2

1

My proposal is to generate the CSV file on server side and return it as an attachment on clients. This methodology guarantees that the CSV file will be the same on all the devices (Laptop/Phones/Tables/etc.). Additionally, you avoid the reimplementation of creating the CSV on each different client.

Response with a csv file in expressjs:

mycollection.find({
    _id: {
        $in: objectIds
    }
}, function(err, docs) {
    if (err) {
      res.status(400);
      res.send('Unexpected db error');
    }

    var csv = convertCollectionToCsv(docs);
    if (!csv) {
      res.status(400);
      res.send('Invalid csv format');
    }

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

You can either choose a third-party library for CSV converter/parser, or, if it is too simple, you can create your own. The following is a typical methodology in order to create a csv file:

var data = getData();
var csv = convertCollectionToCsv(data);
console.log(csv);

function convertCollectionToCsv(docs, seperator) {
  if (!(Array.isArray(docs) && docs.length > 0)) {
    return;
  }

  seperator = seperator || ',';

  var header = createHeader(docs);
  var body = docs.map(convertObjectsToCsv);
  var csv = []
    .concat([header])
    .concat(body)
    .join('\n');

  return csv;

  function createHeader(docs) {
    var headRow = docs[0];
    var header = Object.keys(headRow);
    return header.join(seperator);
  }

  function convertObjectsToCsv (doc) {
    // special treatment for dates, nested arrays or objects
    // for instance:
    doc['scAttitude'] = (doc['scAttitude'] || []).join('-');
    doc['scPosition'] = (doc['scPosition'] || []).join('-');

    var values = getValuesFromObject(doc);
    return values.join(seperator);
  }
}

function getValuesFromObject(obj) {
  if (typeof obj !== 'object' || obj === null) {
    return [];
  }

  var keys = Object.keys(obj);
  var values = [];
  for (var i = 0; i < keys.length; ++i) {
    values.push(obj[keys[i]]);
  }

  return values;
}

function getData() {
  return [{
      "_id": "58405524d70210dc299ca275",
      "pictureNumber": 1,
      "scAttitude": [
          0,
          0,
          0,
          1
      ],
      "scPosition": [
          1,
          0,
          0
      ],
      "integrationTime": 10,
      "time": "2016-12-01T16:51:57.000Z",
      "offset": 1,
      "gain": 2,
      "ledStatus": false,
      "imageType": "Image",
      "cameraType": "Mongo",
      "testPatternStatus": false,
      "temperatureCCD": 189,
      "temperatureLED1": 162,
      "temperatureLED2": 152,
      "temperatureVBG": 490,
      "temperatureGND": 0,
      "imageValid": true,
      "remarks": " Reception time: Thu Dec 01 17:51:47 CET 2016",
      "imageSize": 2271320
  },
  {
      "_id": "586bc534b31a89bb45b0083e",
      "pictureNumber": 2,
      "scAttitude": [
          1,
          0,
          0,
          1
      ],
      "scPosition": [
          1,
          0,
          0
      ],
      "integrationTime": 20,
      "time": "2016-12-02T16:51:57.000Z",
      "offset": 2,
      "gain": 0,
      "ledStatus": false,
      "imageType": "Image",
      "cameraType": "MOngo",
      "testPatternStatus": false,
      "temperatureCCD": 189,
      "temperatureLED1": 162,
      "temperatureLED2": 152,
      "temperatureVBG": 490,
      "temperatureGND": 0,
      "imageValid": true,
      "remarks": " Reception time: Thu Dec 01 17:51:47 CET 2016",
      "imageSize": 2271320
  }];
}

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks Alot.. I am newbie to JavaScript. these 2 lines are giving me the error when i tried to use your code in my app. doc['scAttitude'] = (doc['scAttitude'] || []).join('-'); doc['scPosition'] = (doc['scPosition'] || []).join('-'); Object.values is not a function at convertObjectsToCsv Can you please help.
Object.values is not working because of the browser compatibility, developer.mozilla.org/en/docs/Web/JavaScript/Reference/…. I suggest you to create your own getValuesFromObject function. I have update the example that uses the getValuesFromObject function
Its still not running.. Can you please take a look on JSFiddle here is the link : jsfiddle.net/1L3Lv4sv
0

You can use either of those modules:

(don't worry if it's CSV or TSV - just make sure that you use the correct delimiter which is comma in your case) or something else from those lists:

This is much easier and less error prone than manually composing the right output, especially when you have any special characters.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.