Last active
June 7, 2018 04:04
-
-
Save Daniel-Hug/209a45a763d5b16101f7934f346c6a6b to your computer and use it in GitHub Desktop.
JS function: convert objects in an array or object to rows in a CSV file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
usage: | |
var csvString = toCSV({ | |
key1: { col1: 5, col2: 'hi' }, | |
key2: { col1: 7, col2: 'hello' } | |
}, { | |
// default config: | |
includeKeys: true, | |
delimiter: ',', | |
filterAndMap: { | |
// propToExclude: false, | |
// propToCustomize: function(val) { return customVal; } | |
} | |
}); | |
var csvString = toCSV([ | |
{ col1: 5, col2: 'hi' }, | |
{ col1: 7, col2: 'hello' } | |
]); | |
*/ | |
function toCSV(rows, config) { | |
var has = Function.prototype.call.bind(Object.prototype.hasOwnProperty); | |
var indexByColumnHeading = {}; | |
var columnHeadings = []; | |
var csv = ''; | |
config = config || {}; | |
var delimiter = config.delimiter === undefined ? ',' : config.delimiter; | |
var includeKeys = config.includeKeys === undefined ? true : config.includeKeys; | |
var filterAndMap = config.filterAndMap || {}; | |
// turn each object into a row | |
for (var key in rows) { | |
// skip properties of prototype | |
if (!has(rows, key)) continue; | |
// add row | |
var rowObject = rows[key]; | |
var cells = []; | |
if (includeKeys) { | |
columnHeadings[0] = 'key'; | |
cells[0] = key; | |
} | |
// turn each property into a cell | |
for (var columnHeading in rowObject) { | |
// skip excluded properties and those of prototype | |
if (filterAndMap[columnHeading] === false || !has(rowObject, columnHeading)) continue; | |
// store the column heading | |
if (indexByColumnHeading[columnHeading] === undefined) { | |
columnHeadings.push(columnHeading); | |
indexByColumnHeading[columnHeading] = columnHeadings.length - 1; | |
} | |
// add cell | |
var value = typeof filterAndMap[columnHeading] === 'function' ? | |
filterAndMap[columnHeading](rowObject[columnHeading]) : | |
rowObject[columnHeading]; | |
value = String.prototype.split.call(value, '"').join('""'); | |
if (String.prototype.indexOf.call(value, ',') >= 0) value = '"' + value + '"'; | |
cells[indexByColumnHeading[columnHeading]] = value; | |
} | |
csv += '\n' + cells.join(delimiter); | |
} | |
return columnHeadings.join(delimiter) + csv; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment