Mar1009
Mar1009

Reputation: 811

How to add header to csv file in more efficient way

I have a function which writes values to a csv file from an array in some response, but before that I need to provide headers with the field name in the first line for each tab so I have written the headers in using csv += '/t header 1',csv += '/t header 2' and so on.

Here is my block of code

function exportToCsv(fName, rows) {
    var csv = 'branch';
    csv += '\t customerId';
    csv += '\t customerName';
    csv += '\t LOAN ID/UT unique ID';
    csv += '\n';
    for (var i = 0; i < rows.length; i++) {
        var row = Object.values(rows[i]);
        for (var j = 0; j < row.length; j++) {
            var val = '';
            val = row[j] === null ? '' : row[j].toString();
            if (j > 0)
                csv += '\t';
            csv += val;
        }
        csv += '\n';
    }
}

Is there any efficient way to write those five lines in above function? The current code is working but I'm looking for a more efficient way to replace these lines.

Also note I have just mentioned a few header names here but I actually have 20 - 30 headers fields.

Please share your thoughts.

Upvotes: 2

Views: 8495

Answers (2)

Don F.
Don F.

Reputation: 123

I'm not sure with what you mean by efficient (can be processing time, or less lines of code, readability, etc.)

For reference, here's a library that is usually used as a convenience method for processing/generating CSV files. I think this can also be imported to be used in javascript, not just node.js.

https://csv.js.org/stringify/api/

They have options that can be used like putting some headers or even delimiters.

Sample code from their site

const stringify = require('csv-stringify')
const assert = require('assert')

stringify([
  [ '1', '2', '3', '4' ],
  [ 'a', 'b', 'c', 'd' ]
], function(err, output){
  assert.equal(output, '1,2,3,4\na,b,c,d\n')
});

with the headers option: (source: https://csv.js.org/stringify/options/columns/)

stringify( [
  { a: '1', b: '2' }
], {
  columns: [ { key: 'a' }, { key: 'b' } ]
}, function(err, data){
  assert.equal(data, '1,2\n')
})

Upvotes: 0

Nick
Nick

Reputation: 147166

If the keys in your row object are the same as the headers you can just use .join to string them into a csvheader. Otherwise, you could use a mapping array to convert a row key into the appropriate header for the CSV. For example:

const row = {
  branch: 'Main',
  customerId: 45,
  customerName: 'Bill',
  'LOAN ID/UT unique ID': 'X456Y01'
}

let csvheader = Object.keys(row).join('\t');
console.log(csvheader);

const row2 = {
  branch: 'Main',
  Id: 45,
  Name: 'Bill',
  LoanId: 'X456Y01'
};
const map = {
  branch: 'branch',
  Id: 'customerId',
  Name: 'customerName',
  LoanId: 'LOAN ID/UT unique ID'
}

csvheader = Object.keys(row2).map(v => map[v]).join('\t');
console.log(csvheader);

Upvotes: 1

Related Questions