Suppose I have the following structure:
var obj = [{one: 1, two: 2, three: 3}, {one: 1, two: 2, three: 3}];
But I need to export this data to csv with the following output:
"1", "2", "3"
"1", "2", "3"
I've tried the following code, but it does not work:
var csvContent = "data:text/csv;charset=utf-8,";
Object.values = function (obj) {
var vals = [];
for( var key in obj ) {
if ( obj.hasOwnProperty(key) ) {
vals.push(obj[key]);
}
}
return vals;
}
Object.values(obj).forEach(function(infoArray, index) {
dataString = infoArray.join(",");
csvContent += index < obj.length ? dataString + "\n" : dataString;
});
var encodedUri = encodeURI(prepearedString);
var link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "my_data.csv");
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
Could you please help me with this issue.
2 Answers 2
It looks as if you're converting objects to a CSV file. It's important to note that objects are basically hash maps which means that the keys are not accessed in a predictable order. Also, some of your rows may be missing a value, which would cause holes in your resulting data.
What I would do is to first transform all the rows into columns (and default to null wherever a value is missing) so that you can predictably access the values for all known columns. Then you can output a CSV header with all known headers, followed by the values.
Here's an example:
var rows = [{one: 1, two: 2, three: 3}, {one: 1, two: 2, three: 3}];
var columns = {};
rows.forEach(function (row, index) {
for (var key in row) {
if (!columns[key]) {
// Set up nullified column.
var values = [];
for (var i = 0; i < rows.length; i++) {
values.push(null);
}
columns[key] = values;
}
// Store the value in the column.
columns[key][index] = row[key];
}
});
// Print the header.
var header = Object.keys(columns);
console.log(header.join(','));
// Print the rows.
for (var i = 0; i < rows.length; i++) {
var values = header.map(function (key) { return columns[key][i]; });
console.log(values.join(','));
}
This is the output you get in the console from the above code:
one,two,three
1,2,3
1,2,3
Comments
Below is the code to extract values and have multilined them, CSV format can be managed.
var obj = [{one: 1, two: 2, three: 3}, {one: 1, two: 2, three: 3}];
var output = [];
for( var key in obj ) {
for( var k in obj[key]){
output.push(obj[key][k])
}
output.push('\n')
}
alert(output.join(''))
2 Comments
for ... in on an array isn't really safe – use forEach or iterate indexes 0..length and 2) for ... in doesn't have to run in a predictable order since objects are hashmaps, and shouldn't be relied upon, especially if the objects in the array are even slightly different.for loop, as for in loop also considers enumerable properties, but specific to this obj, seems no additional properties so used it.
encodeURI(prepearedString)? MaybeencodeURI(csvContent)works better?