0

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
  • encodeURI(prepearedString)? Maybe encodeURI(csvContent) works better? Commented Jun 22, 2015 at 20:39
  • Please elaborate. What do you mean by "does not work"? People are usually happy to provide a solution, but usually do not find joy in having to figure out what the problem is first. Commented Jun 22, 2015 at 20:42

2 Answers 2

1

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
Sign up to request clarification or add additional context in comments.

Comments

1

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

A few notes: 1) 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.
agree.. should be used for loop, as for in loop also considers enumerable properties, but specific to this obj, seems no additional properties so used it.

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.