69

I am trying to convert a JavaScript object set in to CSV format

You can get the idea about my Javascript object, if you put it in online JSON parser https://jsonformatter.org/json-parser

This is how I tried to work it out... but it flopped.. http://jsfiddle.net/fHQzC/11/

I am trying to take the whole values corresponding to the value "term" and corresponding title in to CSV format

The expected output for is like

Time,Dec 9, 2012 
News,Germany,election, Egypt,Revolution, Japan, Earthquake
Person,Obama, Beckham
Title,Pearce Snubs Beckham                                
Time,Dec 5, Birthday
Person, Lebron James
News,Italy,Euro 2012 Final
Title-Heats National Champions
                              

and is it possible to download the csv file in excel sheet the one I found in Stackoverflow was not really useful me...

1

13 Answers 13

56

Probably more elegant and the simplest solution

function convertToCSV(arr) {
  const array = [Object.keys(arr[0])].concat(arr)

  return array.map(it => {
    return Object.values(it).toString()
  }).join('\n')
}


console.log(
  convertToCSV(
    [
      {
        id: 1,
        name: 'Foo',
        timestamp: new Date()
      },
      {
        id: 2,
        name: 'Bar',
        timestamp: new Date()
      },
      {
        id: 3,
        name: 'Baz',
        timestamp: new Date()
      }
    ]
  )
)

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

6 Comments

Thank you, this is exactly the solution I need. I believe this to be the best answer.
This is exactly what I was looking for
perfect solution!
Unfortunately this does not work if objects are improperly sorted and filled, because it assumes first object contains all fields and that their order will remain the same.
A bit shorter: [Object.keys(arr[0]),...arr.map(it => Object.values(it))].join('\n')
|
30

you can try as

$(document).ready(function () {

        // Create Object
        var items = [
              { name: "Item 1", color: "Green", size: "X-Large" },
              { name: "Item 2", color: "Green", size: "X-Large" },
              { name: "Item 3", color: "Green", size: "X-Large" }];

        // Convert Object to JSON
        var jsonObject = JSON.stringify(items);

        // Display JSON
        $('#json').text(jsonObject);

        // Convert JSON to CSV & Display CSV
        $('#csv').text(ConvertToCSV(jsonObject));
    });

and a function ConvertToCSV

// JSON to CSV Converter
        function ConvertToCSV(objArray) {
            var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
            var str = '';

            for (var i = 0; i < array.length; i++) {
                var line = '';
                for (var index in array[i]) {
                    if (line != '') line += ','

                    line += array[i][index];
                }

                str += line + '\r\n';
            }

            return str;
        }

Source

6 Comments

complexity does not affect this as the format of the csv will always remain same..
Will this include a comma in a value?
json is comma separated value it will not consider comma as value. you need to use some trick for that.
This should be extended to be RFC4180 compliant, specifically to enclose in double quotes strings that may contain commas or line breaks, and escape any embedded double quotes. See json2csv
|
28

Here is my solution

function arrayToCSV(objArray) {
     const array = typeof objArray !== 'object' ? JSON.parse(objArray) : objArray;
     let str = `${Object.keys(array[0]).map(value => `"${value}"`).join(",")}` + '\r\n';

     return array.reduce((str, next) => {
         str += `${Object.values(next).map(value => `"${value}"`).join(",")}` + '\r\n';
         return str;
        }, str);
 }

Example:

let arr = [{name: "Essa", age: 25}];
console.log(arrayToCSV(arr));

2 Comments

this escapes comma separated values inside columns
@RisingSun no it doesn't
17

Here's a solution similar to mightybruno's answer that handles strings containing commas. None of the other answers seem to take this in to consideration.

function objectsToCSV(arr) {
    const array = [Object.keys(arr[0])].concat(arr)
    return array.map(row => {
        return Object.values(row).map(value => {
            return typeof value === 'string' ? JSON.stringify(value) : value
        }).toString()
    }).join('\n')
}

1 Comment

thanks very much, I also see lots of answer not taking strings containing commas into consideration.
11

Below code will convert and download JSON array to csv as a file.

 function exportJSONToCSV(objArray) {
    var arr = typeof objArray !== 'object' ? JSON.parse(objArray) : objArray;
    var str =
      `${Object.keys(arr[0])
        .map((value) => `"${value}"`)
        .join(',')}` + '\r\n';
    var csvContent = arr.reduce((st, next) => {
      st +=
        `${Object.values(next)
          .map((value) => `"${value}"`)
          .join(',')}` + '\r\n';
      return st;
    }, str);
    var element = document.createElement('a');
    element.href = 'data:text/csv;charset=utf-8,' + encodeURI(csvContent);
    element.target = '_blank';
    element.download = 'export.csv';
    element.click();
  }

2 Comments

perfect solution
Appreciate the code to prompt the user to download aswell. Thanks!
2

This is a quick & dirty, but probably works for most cases:

const headers = Object.keys(objAry[0])
console.log(headers.join())

objAry.forEach(r => console.log(
   Object.values(r)
   .map(c => Array.isArray(c)? `"${c.join()}"` : c)
   .join())
)

Comments

1

This is my solution

https://jsfiddle.net/dhou6y3o/

function iterateObject(obj) {
  var value = '', header = '';
          for (name in obj) {
            if (obj.hasOwnProperty(name)) {
              if (isObject(obj[name])) {
                var out = iterateObject(obj[name]);
                value += out.value;
                header += out.header;
              } else {
                value += removeNewLine(obj[name]) + '; ';
                header += name + '; ';
              }
            }
          }
  return {
    "value":value,
    "header":header
  };
}
function isObject(obj) {
  return (typeof obj === 'object');
}
function removeNewLine(item) {
  return item.toString().replace(/(\r\n|\n|\r)/gm,"");
}

Comments

1

Use papaparse library to convert JSON to CSV and Vice Versa. Refer to this link - https://www.papaparse.com/

Comments

1

Similar to mightybruno's answer but this would allow separate access to the headers and content (by moving the join statements to later in the function) if desired.

function objToCsv(data) {
    const headers = Object.keys(data[0]).join();
    const content = data.map(r => Object.values(r).join());
    return [headers].concat(content).join("\n");
}

Comments

0
    function objToCsv(arr) {
        let claves = Object.keys(arr[0]).sort();
        let rows = claves.join(";") + "\r\n";
        arr.forEach((row) => {
          let nrow = [];
          claves.forEach((clave) => {
            let valor = JSON.stringify(row[clave]);
            nrow.push(valor.split(";").join(" ").split(",").join(" "));
          });
          rows = rows + nrow.join(";") + "\r\n";
        });
        return rows;
    }

1 Comment

Welcome to StackOverflow. While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value.
0

All the answers do not work for me, because I have a buggy object with unpredictable contents, so I had to implement my own solution which creates a "normalized" array before converting to CSV:

function objToCSV(originalArray) {
    header = [];
    result = [];
    finalCSV = "";

    originalArray.forEach(
        a => { /// Parse all rows of input ///
            row = []; // Create for each row of the input an enpty row for the output
            for (const [key, value] of Object.entries(a)) {
                /// Parse all elements of input row ///
console.log(`${key}: ${value}`);
                if (header.indexOf(`${key}`) < 0) {
                    // Add field to header if not already present
                    header.push(`${key}`);
                }
                // Put value in the right position in the array depending on field name:
                row[header.indexOf(`${key}`)]=`${value}`;
            };
            result.push(row); // Add finished line to output array
console.log("--- row separator ---");
        }
    )

    // Prepare header of CSV file:
    header.forEach(fieldName => {
        finalCSV += fieldName + "\t";
    }
    );
    finalCSV += "\n";

    // Add all rows to CSV file:
    result.forEach(row => {
        /// parse all rows of created array //
        row.forEach(col => {
            /// parse all elements of row ///
            finalCSV += col + "\t"; // Add element to output CSV row
        }
        );
        finalCSV += "\n";
    }
    );

    return finalCSV;
}

Comments

0

Crafted this, works fine into LibreOfice.

It does retrieve the key names to build the columns header.

let example = [
 ,,,,,
  {
    "Time": 1647672300000,
    "Open": 2937.37,
    "High": 2933.81,
    "Low": 2937.94,
    "Close": 2937.39,
    "Volume": 1547.5156
  },,,,,
]

const getCSV = (object) => {
  let csv = Object.entries(Object.entries(object)[0][1]).map((e) => e[0]).join(",");
  for (const [k,v] of Object.entries(object)) {
    csv += "\r\n" + Object.values(v).join(",") // \n is enough in linux to reduce the csv size
  }
  /* //Uncomment for file download
  let j = document.createElement("a")
  j.download = "example_"+Date.now()+".csv"
  j.href = URL.createObjectURL(new Blob([csv]))
  j.click() */
  return csv;
}

console.log(
  getCSV(example)
)

enter image description here

Comments

0

A simple solution when each object inside array can have different or overlapping keys.

function jsonToCsv(jsonArray) {
  // Collect all unique keys in the JSON array
  const keys = new Set();
  jsonArray.forEach((obj) => {
    for (const key in obj) {
      keys.add(key);
    }
  });

  // Convert the keys set to an array
  const keysArray = Array.from(keys);

  // Generate the CSV header
  const header = keysArray.join(",");

  // Generate the CSV rows
  const rows = jsonArray.map((obj) => {
    return keysArray.map((key) => (obj[key] !== undefined ? `"${obj[key]}"` : "")).join(",");
  });

  // Combine the header and rows
  const csv = [header, ...rows].join("\n");

  return csv;
}

// sample input object

const jsonArray = [
  {
    name: "John",
    age: 30,
    city: "New York",
  },
  {
    name: "Jane",
    age: 28,
    country: "USA",
  },
  {
    name: "Doe",
    city: "San Francisco",
    country: "USA",
  },
];

const csv = jsonToCsv(jsonArray);

console.log(csv);

Explaination

The function takes an array of JSON objects as input.

It iterates through each JSON object in the input array and collects all unique keys from these objects.

The unique keys are then converted into an array so that they can be easily manipulated.

A CSV header is generated by joining the keys array with commas.

The CSV rows are generated by iterating through each JSON object in the input array. For each object, the function maps the keys array to their corresponding values in the object. If a key is not present in the object, an empty string is used instead. The values are then joined with commas to create a CSV row.

The header and rows are combined, separated by newlines, to create the final CSV output string.

The function returns the final CSV string.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.