Converting JSON data into CSV format and saving it in a variable: A guide

How can I convert JSON data to CSV format using JavaScript and save it in a JavaScript file? The data includes information about Apple iPhone 4S sales being cancelled in Beijing. Here is a sample of the JSON data:

{
  "count": 2,
  "items": [{
    "title": "Apple iPhone 4S Sale Cancelled in Beijing Amid Chaos (Design You Trust)",
    "description": "Advertise here with BSA Apple cancelled its scheduled sale of iPhone 4S in one of its stores in China's capital Beijing on January 13. Crowds outside the store in the Sanlitun district were waiting on queues overnight...",
    "link": "http:\/\/wik.io\/info\/US\/309201303",
    "timestamp": 1326439500,
    "image": null,
    ...
  }, {
    "title": "Apple to halt sales of iPhone 4S in China (Fame Dubai Blog)",
    "description": "SHANGHAI - Apple Inc said on Friday it will stop selling its latest iPhone in its retail stores in Beijing and Shanghai to ensure the safety of its customers and employees. Go to SourceSource : Fame Dubai BlogExplore : iPhone, iPhone 4, Phone",
    "link": "http:\/\/wik.io\/info\/US\/309198933",
    "timestamp": 1326439320,
    ...
  }]
}

I found a solution for converting JSON data to CSV format but it downloads as a file. How do I store the converted data in a variable instead?

Additionally, I need help changing escape characters like '\u2019' back to normal.


I attempted to use the following code snippet:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
  <title>JSON to CSV</title>
  <script src="http://code.jquery.com/jquery-1.7.1.js" type="text/javascript"></script>
  <script type="text/javascript">
    var json3 = {
      "count": 2,
      "items": [{
          "title": "Apple iPhone 4S Sale Cancelled in Beijing Amid Chaos (Design You Trust)",
          "description": "Advertise here with BSA Apple cancelled its scheduled sale of iPhone 4S in one of its stores in China’s capital Beijing on January 13. Crowds outside the store in the Sanlitun district were waiting on queues overnight...",
          "link": "http://wik.io/info/US/309201303",
          ...
        },
        {
          "title": "Apple to halt sales of iPhone 4S in China (Fame Dubai Blog)",
          "description": "SHANGHAI – Apple Inc said on Friday it will stop selling its latest iPhone in its retail stores in Beijing and Shanghai to ensure the safety of its customers and employees. Go to SourceSource : Fame Dubai BlogExplore : iPhone, iPhone 4, Phone",
          "link": "http://wik.io/info/US/309198933",
          ...
        }
      ]
    }
    
    DownloadJSON2CSV(json3.items);

    function DownloadJSON2CSV(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]) {
          line += array[i][index] + ',';
        }

        line.slice(0, line.Length - 1);

        str += line + '\r\n';
      }
      $('div').html(str);
    }
  </script>

</head>

<body>
  <div></div>
</body>

</html>

However, this code doesn't appear to be functioning properly. Any assistance would be greatly appreciated.

Answer №1

An efficient method for converting JSON to CSV involves utilizing the map function without relying on any external framework:

var json = json3.items
var fields = Object.keys(json[0])
var replacer = function(key, value) { return value === null ? '' : value } 
var csv = json.map(function(row){
  return fields.map(function(fieldName){
    return JSON.stringify(row[fieldName], replacer)
  }).join(',')
})
csv.unshift(fields.join(',')) // add header column
 csv = csv.join('\r\n');
console.log(csv)

Output:

title,description,link,timestamp,image,embed,language,user,user_image,user_link,user_id,geo,source,favicon,type,domain,id
"Apple iPhone 4S Sale Cancelled in Beijing Amid Chaos (Design You Trust)","Advertise here with BSA Apple cancelled its scheduled sale of iPhone 4S in one of its stores in China’s capital Beijing on January 13. Crowds outside the store in the Sanlitun district were waiting on queues overnight. There were incidents of scuffle between shoppers and the store’s security staff when shoppers, hundreds of them, were told that the sales [...]Source : Design You TrustExplore : iPhone, iPhone 4, Phone","http://wik.io/info/US/309201303","1326439500","","","","","","","","","wikio","http://wikio.com/favicon.ico","blogs","wik.io","2388575404943858468"
"Apple to halt sales of iPhone 4S in China (Fame Dubai Blog)","SHANGHAI – Apple Inc said on Friday it will stop selling its latest iPhone in its retail stores in Beijing and Shanghai to ensure the safety of its customers and employees. Go to SourceSource : Fame Dubai BlogExplore : iPhone, iPhone 4, Phone","http://wik.io/info/US/309198933","1326439320","","","","","","","","","wikio","http://wikio.com/favicon.ico","blogs","wik.io","16209851193593872066"

Update ES6 (2016)

This concise syntax enhances readability while ensuring strict data formatting by using JSON.stringify to properly quote strings but leave numbers unquoted:

const items = json3.items
const replacer = (key, value) => value === null ? '' : value // specify how you want to handle null values here
const header = Object.keys(items[0])
const csv = [
  header.join(','), // include header row as the first entry
  ...items.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','))
].join('\r\n')

console.log(csv)

Answer №2

Finally, after some tweaking, I managed to get this code up and running:

<html>
<head>
    <title>Demo - Convert JSON to CSV</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
    <script type="text/javascript" src="https://github.com/douglascrockford/JSON-js/raw/master/json2.js"></script>

    <script type="text/javascript">
        // A function to convert JSON to CSV
        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;
        }

        // Example usage
        $(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));
        });
    </script>
</head>
<body>
    <h1>
        JSON</h1>
    <pre id="json"></pre>
    <h1>
        CSV</h1>
    <pre id="csv"></pre>
</body>
</html>

Big thanks to all the contributors for their support and assistance.

Praney

Answer №3

Great solution provided by praneybehl, for those interested in saving data as a csv file using the blob method, here's a helpful guide:

function ConvertJSONToCSV(JSONData, Title, DisplayLabel) {

    //If JSONData is not an object, parse it into an Object
    var dataArray = typeof JSONData != 'object' ? JSON.parse(JSONData) : JSONData;
    var CSV = '';
    
    //Generating the Label/Header
    if (DisplayLabel) {
        var labelRow = "";
        
        //Extracting labels from the first index of the array
        for (var i in dataArray[0]) {
            //Converting each value to string and comma-separated
            labelRow += i + ',';
        }
        labelRow = labelRow.slice(0, -1);
        //Appending Label row with line break
        CSV += labelRow + '\r\n';
    }
    
    //Loop to extract each row
    for (var j = 0; j < dataArray.length; j++) {
        var dataRow = "";
        
        //Loop to extract each column and convert it to a comma-separated string
        for (var k in dataArray[j]) {
            dataRow += '"' + dataArray[j][k] + '",';
        }
        dataRow.slice(0, dataRow.length - 1);
        //Adding a line break after each row
        CSV += dataRow + '\r\n';
    }
    
    if (CSV == '') {
        alert("Invalid data");
        return;
    }

    //Creating a temporary "a" tag
    var link = document.createElement("a");
    link.id = "downloadLink";
    
    //Appending the anchor tag and removing it after automatic click
    document.body.appendChild(link);

    var csvData = CSV;
    blobData = new Blob([csvData], { type: 'text/csv' });
    var csvUrl = window.webkitURL.createObjectURL(blobData);
    var fileName = (Title || 'ExportedData') + '.csv';
    $("#downloadLink")
        .attr({
            'download': fileName,
            'href': csvUrl
        });

    $('#downloadLink')[0].click();
    document.body.removeChild(link);
}

Answer №4

If you're looking to easily convert an array of JSON objects into a CSV file for downloading, check out this handy function below:

convertJSONtoCSV = (filename, arrayOfJson) => {
  // Convert JSON to CSV
  const replacer = (key, value) => value === null ? '' : value;
  const header = Object.keys(arrayOfJson[0]);
  let csv = arrayOfJson.map(row => header.map(fieldName => 
    JSON.stringify(row[fieldName], replacer)).join(','));
  csv.unshift(header.join(','));
  csv = csv.join('\r\n');

  // Create link and trigger download
  var link = document.createElement('a');
  link.setAttribute('href', 'data:text/csv;charset=utf-8,%EF%BB%BF' + encodeURIComponent(csv));
  link.setAttribute('download', filename);
  link.style.visibility = 'hidden';
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
};

To use this function, simply call it like so:

this.convertJSONtoCSV(`customFileName.csv`, this.state.jsonArray)

Answer №5

For those looking to export JSON data to a CSV file and download it, I wanted to share some helpful code.

If you are working with a basic array, you can skip using $.getJSON to fetch data from an external source.

The following code snippet utilizes Christian Landgren's solution to generate the csv data:

$(document).ready(function() {
    var JSONData = $.getJSON("GetJsonData.php", function(data) {
        var items = data;
        const replacer = (key, value) => value === null ? '' : value; 
        const header = Object.keys(items[0]);
        let csv = items.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','));
        csv.unshift(header.join(','));
        csv = csv.join('\r\n');

        //Download the file as CSV
        var downloadLink = document.createElement("a");
        var blob = new Blob(["\ufeff", csv]);
        var url = URL.createObjectURL(blob);
        downloadLink.href = url;
        downloadLink.download = "DataDump.csv";  
        document.body.appendChild(downloadLink);
        downloadLink.click();
        document.body.removeChild(downloadLink);
    });
});

Additionally, keep in mind that JSON.stringify may escape quotes by adding \", causing issues in Excel. To resolve this, include .replace(/\\"/g, '""') at the end of

JSON.stringify(row[fieldName], replacer)
to properly display the content in Excel.

Complete line:

let csv = items.map(row => header.map(fieldName => (JSON.stringify(row[fieldName], replacer).replace(/\\"/g, '""'))).join(','));

Answer №6

One of the options available for utilizing existing robust libraries that adhere to standards is by leveraging them effectively.

If you are using D3 in your project, you can easily utilize:

    d3.csv.format or d3.csv.formatRows functions to convert an array of objects into a csv string.

    d3.csv.formatRows gives more flexibility in selecting properties that are converted to csv format.

    For detailed information, please visit d3.csv.format and d3.csv.formatRows wiki pages.

In addition to these, there are other useful libraries like jquery-csv and PapaParse. Papa Parse, in particular, does not rely on any dependencies such as jQuery.

For plugins based on jquery, you can explore more options by visiting this link.

Answer №7

Check out these Examples

Example 1:

JsonArray = [{
    "ID": "001",
    "Name": "John",
    "Role": "Admin",
    "Location": "NYC"

}, {
    "ID": "002",
    "Name": "Jane",
    "Role": "Manager",
    "Location": "LA"
}]

JsonFields = ["ID", "Name", "Role", "Location"]

function JsonToCSV(){
    var csvStr = JsonFields.join(",") + "\n";

    JsonArray.forEach(element => {
        ID = element.ID;
        Name = element.Name;
        Role = element.Role
        Location = element.Location

        csvStr += ID + ',' + Name + ','  + Role + ',' + Location + "\n";
        })
        return csvStr;
}

Example2 :

JsonArray = [{
    "ID": "003",
    "Name": "Mike",
    "Team": [{
        "Role": "Developer",
        "Location": "Seattle"
    },
    {
        "Role": "Designer",
        "Location": "SF"
    }]
}]
  
JsonFields = ["ID", "Name", "Role", "Location"]

function JsonToCSV() {
    var csvStr = JsonFields.join(",") + "\n";

    JsonArray.forEach(element => {
        ID = element.ID;
        Name = element.Name;
        
        element.Team.forEach(teamELe => {
            Role = teamELe.Role
            Location = teamELe.Location
            csvStr += ID + ',' + Name + ',' + Role + ',' + Location + "\n";
        })
    })
    return csvStr;
}

You have the option to download the CSV file using this code :

function downloadCSV(csvStr) {

    var hiddenElement = document.createElement('a');
    hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csvStr);
    hiddenElement.target = '_blank';
    hiddenElement.download = 'output.csv';
    hiddenElement.click();
}

Answer №8

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Convert JSON to CSV</title>
    <script src="http://code.jquery.com/jquery-1.7.1.js" type="text/javascript"></script>
</head>
<body>
    <h1>This page serves the purpose of converting JSON data to CSV format.</h1>

    <script type="text/javascript">
        var json3 = {
          "count": 2,
          "items": [{
              "title": "Apple iPhone 4S Sale Cancelled in Beijing Amid Chaos (Design You Trust)",
              "description": "Advertise here with BSA Apple cancelled its scheduled sale of iPhone 4S in one of its stores in China’s capital Beijing on January 13. Crowds outside the store in the Sanlitun district were waiting on queues overnight. There were incidents of scuffle between shoppers and the store’s security staff when shoppers, hundreds of them, were told that the sales [...]Source : Design You TrustExplore : iPhone, iPhone 4, Phone",
              "link": "http://wik.io/info/US/309201303",
              "timestamp": 1326439500,
              "image": null,
              "embed": null,
              "language": null,
              "user": null,
              "user_image": null,
              "user_link": null,
              "user_id": null,
              "geo": null,
              "source": "wikio",
              "favicon": "http://wikio.com/favicon.ico",
              "type": "blogs",
              "domain": "wik.io",
              "id": "2388575404943858468"
            },
            {
              "title": "Apple to halt sales of iPhone 4S in China (Fame Dubai Blog)",
              "description": "SHANGHAI – Apple Inc said on Friday it will stop selling its latest iPhone in its retail stores in Beijing and Shanghai to ensure the safety of its customers and employees. Go to SourceSource : Fame Dubai BlogExplore : iPhone, iPhone 4, Phone",
              "link": "http://wik.io/info/US/309198933",
              "timestamp": 1326439320,
              "image": null,
              "embed": null,
              "language": null,
              "user": null,
              "user_image": null,
              "user_link": null,
              "user_id": null,
              "geo": null,
              "source": "wikio",
              "favicon": "http://wikio.com/favicon.ico",
              "type": "blogs",
              "domain": "wik.io",
              "id": "16209851193593872066"
            }
          ]
        };

        const items = json3.items
        const replacer = (key, value) => value === null ? '' : value // specify how you want to handle null values here
        const header = Object.keys(items[0])
        let csv = items.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','))
        csv.unshift(header.join(','))
        csv = csv.join('\r\n')

        var link = document.createElement("a");    
        link.id="lnkDwnldLnk";
        document.body.appendChild(link);
        blob = new Blob([csv], { type: 'text/csv' }); 
        var csvUrl = window.webkitURL.createObjectURL(blob);
        var filename = 'ExportedData.csv';
        jQuery("#lnkDwnldLnk")
        .attr({
            'download': filename,
            'href': csvUrl
        });
        jQuery('#lnkDwnldLnk')[0].click();
        document.body.removeChild(link);
    </script>
</body>
</html>

Answer №9

A sophisticated method for converting an object array to CSV:

const convertToCsv = (arr) => {
    const keys = Object.keys(arr[0]);
    const replacer = (_key, value) => value === null ? '' : value;
    const processRow = row => keys.map(key => JSON.stringify(row[key], replacer)).join(',');
    return [ keys.join(','), ...arr.map(processRow) ].join('\r\n');
};

To easily download it as a file:

const downloadFile = (fileName, data) => {
    var link = document.createElement('a');
    link.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(data));
    link.setAttribute('download', fileName);
    link.style.display = 'none';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
};

Answer №10

The solution provided as the accepted answer was incredibly helpful, but I required a modified version to accommodate unstructured JSON objects.

I have adapted the accepted answer to function with an array of unstructured objects that vary in size and schema.

Here is the input:

[
  {
    "name": "Item 1",
    "color": "Green",
    "sizerange": {
      "max": "X-Large",
      "min": "X-Small"
    }
  },
  {
    "name": "Item 2",
    "color": "Green",
    "size": "X-Large",
    "owner": {
      "name":"Bill",
      "address": {
        "line1": "1 test st",
        "suburb": "testville"
      }
    }
  },
  {
    "name": "Item 3",
    "color": "Green",
    "sizes": [
      "X-Large",
      "Large",
      "Small"
    ]
  }
]

And here is the output:

"name","color","sizerange.max","sizerange.min","size","owner.name","owner.address.line1","owner.address.suburb","sizes.0","sizes.1","sizes.2"
"Item 1","Green","X-Large","X-Small","","","","","","",""
"Item 2","Green","","","X-Large","Bill","1 test st","testville","","",""
"Item 3","Green","","","","","","", "X-Large","Large","Small"

// JSON to CSV Converter

//https://www.codegrepper.com/code-examples/javascript/javascript+array+to+csv+string
function objectToCSVRow(dataObject) {
  var dataArray = [];
  for (var o in dataObject) {
    var innerValue = typeof dataObject[o] == 'undefined' ? '' : dataObject[o].toString();
    var result = innerValue.replace(/"/g, '""');
    result = '"' + result + '"';
    dataArray.push(result);
  }
  return dataArray.join(',') + '\r\n';
}

//https://stackoverflow.com/a/6491621
function findbystring(o, s) {
  s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
  s = s.replace(/^\./, ''); // strip a leading dot
  var a = s.split('.');
  for (var i = 0, n = a.length; i < n; ++i) {
    var k = a[i];
    if (k in o) {
      o = o[k];
    } else {
      return;
    }
  }
  return o;
}


function pushUnique(arr, item) {
  if (item != "" && !arr.includes(item))
    arr.push(item);
}


function getLabels(name, item, labels) {
  if (typeof item == 'object') {
    for (var index in item) {
      thisname = ""
      if (name != "") thisname = name + ".";
      thisname += index;
      getLabels(thisname, item[index], labels);
    }
  } else {
    pushUnique(labels, name);
  }
}

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

  var labels = [];

  for (var i = 0; i < array.length; i++) {
    getLabels("", array[i], labels);

  }

  str += objectToCSVRow(labels);
  
  for (var i = 0; i < array.length; i++) {

    var line = [];
    for (var label in labels) {

      line.push(findbystring(array[i], labels[label]));

    }

    str += objectToCSVRow(line);
  }

  return str;
}

// Example
$(document).ready(function() {

  // Create Object
  var items = [{
      name: "Item 1",
      color: "Green",
      sizerange: {
        max: "X-Large",
        min: "X-Small"
      }
    },
    {
      name: "Item 2",
      color: "Green",
      size: "X-Large",
      owner: {
        name: "Bill",
        address: {
          line1: "1 test st",
          suburb: "testville"
        }
      }
    },
    {
      name: "Item 3",
      color: "Green",
      sizes: ["X-Large", "Large", "Small"]
    }
  ];

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

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

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

<head>
  <title>Demo - Covnert JSON to CSV</title>
  <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
  <script type="text/javascript" src="https://github.com/douglascrockford/JSON-js/raw/master/json2.js"></script>

  <script type="text/javascript">
  </script>
</head>

<body>
  <h1>
    JSON</h1>
  <pre id="json"></pre>
  <h1>
    CSV</h1>
  <pre id="csv"></pre>
</body>

</html>

Answer №11

There are instances where objects vary in lengths, presenting a challenge similar to what Kyle Pennell encountered. Rather than sorting the array, I opted to iterate over it and select the longest item. This approach reduces the time complexity to O(n), as opposed to O(n log(n)) when employing sorting initially.

I began with Christian Landgren's updated ES6 (2016) version of the code.

json2csv(json) {
    // You may skip this step if your input is already a proper array:
    const simpleArray = JSON.parse(json)
    // Find the object in the array with the most keys to use as headers
    const header = simpleArray.map((x) => Object.keys(x))
      .reduce((acc, cur) => (acc.length > cur.length ? acc : cur), []);

    // Specify how to handle null values here
    const replacer = (key, value) => (
      value === undefined || value === null ? '' : value);
    let csv = simpleArray.map((row) => header.map(
      (fieldName) => JSON.stringify(row[fieldName], replacer)).join(','));
    csv = [header.join(','), ...csv];
    return csv.join('\r\n');
}

Answer №12

Based on an idea from praneybehl in their response, this script has been modified to handle nested objects and tab separation.

function ConvertToCSV(objArray) {
  let array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
  if(!Array.isArray(array))
      array = [array];

  let str = '';

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

      const item = array[i][index];
      line += (typeof item === 'object' && item !== null ? ConvertToCSV(item) : item);
    }
    str += line + '\r\n';
  }

  do{
      str = str.replace(',','\t').replace('\t\t', '\t');
  }while(str.includes(',') || str.includes('\t\t'));

  return str.replace(/(\r\n|\n|\r)/gm, ""); //removing line breaks: https://stackoverflow.com/a/10805198/4508758
}

Answer №13

Check out the latest answer showcasing a wonderfully optimized and convenient CSV plugin: (Feel free to try this code in your project after verifying, as it may not work on stackoverflow)

Utilizing jquery along with the efficient jquery.csv library (Skillfully escapes all characters) https://github.com/typeiii/jquery-csv

// Array of objects creation
const data = [
    { name: "Item 1", color: "Green", size: "X-Large" },
    { name: "Item 2", color: "Green", size: "X-Large" },
    { name: "Item 3", color: "Green", size: "X-Large" }
];

// Conversion to csv
const csv = $.csv.fromObjects(data);

// Function to download file as csv
const downloadBlobAsFile = function(csv, filename){
    var downloadLink = document.createElement("a");
    var blob = new Blob([csv], { type: 'text/csv' });
    var url = URL.createObjectURL(blob);
    downloadLink.href = url;
    downloadLink.download = filename;
    document.body.appendChild(downloadLink);
    downloadLink.click();
    document.body.removeChild(downloadLink);
}

// Download csv file
downloadBlobAsFile(csv, 'filename.csv');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdn.tutorialjinni.com/jquery-csv/1.0.11/jquery.csv.min.js"></script>

Answer №14

Here's a method for handling deeply nested objects in a more object-oriented manner using newer JavaScript versions. You may need to adjust the separator type after the region.

function convertToCSV(objArray) {
    let rows = typeof objArray !== "object" ? JSON.parse(objArray) : objArray;
    let header = "";
    Object.keys(rows[0]).map(property => (header += property + ";"));

    let csvString = "";
    rows.forEach(row => {
        let line = "";
        let columns =
            typeof row !== "object" ? JSON.parse(row) : Object.values(row);
        columns.forEach(column => {
            if (line !== "") {
                line += ";";
            }
            if (typeof column === "object") {
                line += JSON.stringify(column);
            }  else {
                line += column;
            }
        });
        csvString += line + "\r\n";
    });
    return header + "\r\n" + csvString;
}

Answer №15

Personally, I prefer utilizing the d3-dsv library for this task. There's no need to reinvent the wheel, right?


import { csvFormat } from 'd3-dsv';
/**
 * Convert input data into a CSV formatted string
 * @param (Array) columnsToBeIncluded array of column names (strings)
 *                that should be included in the formatted CSV
 * @param {Array} input array of objects to be transformed into a string
 */
export function convertDataToCSVFormatString(input, columnsToBeIncluded = []) {
  if (columnsToBeIncluded.length === 0) {
    return csvFormat(input);
  }
  return csvFormat(input, columnsToBeIncluded);
}

By using tree-shaking, you can easily import just the specific function needed from the d3-dsv library.

Answer №16

Inspired by @Christian Landgren's response, I encountered an issue with my CSV file containing only 3 columns/headers. This was due to the fact that the initial JSON element had only 3 keys. Therefore, it is important to exercise caution with the

const header = Object.keys(json[0])
line, as it assumes the first array element is representative. My JSON data was inconsistent, with some objects having more or fewer keys.

To address this, I implemented an array.sort, which organizes the JSON based on the number of keys present. By doing so, the resulting CSV will have the maximum number of columns possible.

This inclusive a method can be seamlessly integrated into your code. Simply provide it with the JSON dataset!

function convertJSONtocsv(json) {
    if (json.length === 0) {
        return;
    }

    json.sort(function(a, b){ 
       return Object.keys(b).length - Object.keys(a).length;
    });

    const replacer = (key, value) => value === null ? '' : value // define handling for null values
    const header = Object.keys(json[0])
    let csv = json.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','))
    csv.unshift(header.join(','))
    csv = csv.join('\r\n')

    fs.writeFileSync('awesome.csv', csv)
}

Answer №17

Below is a straightforward method I use to convert an array of objects into CSV format, assuming all objects in the array have the same attributes:

let csvData = []
if (dataArray.length) {
  let keysArray = Object.keys(dataArray[0])
  csvData.push(keysArray.join(','))
  dataArray.forEach(obj => {
    let valuesArray = keysArray.map(key => obj[key] || '')
    csvData.push(valuesArray.join(','))
  })
}

csvData = csvData.join('\n')

Answer №18

function generateCSV(data, name = "output.csv") {
    /*  *This function takes data in JSON format and converts it to CSV before downloading
    *The input data should be an array of objects with the same structure  
    *If no filename is provided, the default name will be used.
    */

    /* Convert JSON data to CSV format*/
    let jsonData = data;
    let headers = Object.keys(jsonData[0]);
    let replacerFunction = function (key, value) { return value === null ? '' : value }
    let csvData = jsonData.map(function (row) {
        return headers.map(function (headerName) {
            return JSON.stringify(row[headerName], replacerFunction)
        }).join(',')
    })
    csvData.unshift(headers.join(','))
    csvData = csvData.join('\r\n');

    /* Download the CSV file */
    let downloadLinkElement = document.createElement("a");
    let blobData = new Blob(["\ufeff", csvData]);
    let urlLink = URL.createObjectURL(blobData);
    downloadLinkElement.href = urlLink;
    downloadLinkElement.download = name;
    document.body.appendChild(downloadLinkElement);
    downloadLinkElement.click();
    document.body.removeChild(downloadLinkElement);
}

This custom function was crafted based on previous explanations.

Answer №19

Export data to CSV format.

function writeToCsv(dataToWrite, callback) {
    var dataToWrite;
    var fs = require('fs');
    dataToWrite = convertToCSV(dataToWrite);
    fs.writeFile('assets/distanceInfo.csv', dataToWrite, 'utf8', function (err) {
      if (err) {
        console.log('An error occurred - the file may not have been saved or a corrupted file was saved.');
      } else{
        console.log('Data successfully saved to CSV file!');
      }
      callback("data_saved | assets/distanceInfo.csv")
    });
}

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;
}

Answer №20

Looking for a solution that actually works? Look no further! Check out my structured JSON response to a related question, complete with a demo snippet. JSON To CSV conversion (JavaScript) : How to properly format CSV conversion Don't settle for just one type of converter. Explore similar tools on my Github profile for analyzing unknown JSON structures. I take pride in being the author of the code provided in this response, as well as most of the projects on my Github page (excluding a few that were originally forks or translations).

Answer №21

A straightforward method for transforming nested JavaScript objects (excluding arrays) into CSV format while maintaining an organized structure.

const ConvertToCsv = (data, level = 0) => (
  Object.keys(data).reduce((prevValue, currValue) => {
    if (typeof data[currValue] === 'object' && !Array.isArray(data[currValue])) {
      // handle nested object
      const formattedObjProp = `${prevValue}${','.repeat(level)}${currValue}\r\n`;
      level++;
      const formattedObj = `${formattedObjProp}${ConvertToCsv(data[currValue], level)}`;
      level--;
      return formattedObj;
    }
    return `${prevValue}${','.repeat(level)}${currValue},${data[currValue]}\r\n`
  }, '')
)

const obj = {
  baz: {
    foo: {
      bar: 5
    }
  };
  
console.log(ConvertToCsv(obj))

Answer №22

My approach to converting an array of JSON objects into a CSV file involves following certain guidelines inspired by RFC 4180 and MIME standards:

  1. Each record should have the same number of comma-separated fields.
  2. Fields can be quoted with double quotes.
  3. If double-quotes are used, then a double-quote in a field must be escaped as two double-quote characters.
  4. Include some type of carriage return or line feed.

Although there may be more efficient methods available, I've created a function that is easy to read and understand while enforcing these constraints.

The function operates in two passes:

  1. Iterate through each array entry to collect all key names on the first pass.
  2. Create a header using the collected key names.
  3. In the second pass, populate the table with values corresponding to the keys.

For handling different data types:

  • If a value is undefined, it is replaced with an empty string.
  • If a value is not a string, it is converted to a string using JSON.stringify.
  • Replace any interior double quotes with two double quotes for proper formatting.
  • Wrap each entry in double quotes separated by commas without spaces.
  • Ensure there is a new line between each row.

The resulting CSV string should be easily viewable in most spreadsheet applications.

function makeCSVFromJSON(myJSON) {
    // Function logic...
}

Answer №23

function convertJsonToCsv(data) {
  return (
    Object.keys(data[0]).join(",") +
    "\n" +
    data.map((d) => Object.values(d).join(",")).join("\n")
  );
}

This method is designed to handle simple json arrays and convert them into csv format. For nested json arrays, it is recommended to first simplify the structure before using this function.

Answer №24

Typescript function made simple considering the following:

  • ✅ Keys/Values can contain "
  • ✅ Keys/Values can contain ,
  • ✅ Values can be an array or object

Playground Link

https://i.sstatic.net/RQ4M1.png

const arrayToCSV = (myJSON: any[]) => {
  const escapeValue = (value: any) => {
    const content = (() => {
      if (!value) {
        return "";
      }
      if (typeof value === "object") {
        return JSON.stringify(value).replace(/"/g, '""')
      }
      return value.toString();
    })()
    return `"${content}"`
  };
  
  const fieldNamesArray: string[] = [...new Set(
    myJSON.reduce((acc, arrayEntry) => {
      return [...acc, ...Object.keys(arrayEntry)];
    }, [])
  )] as any[];

  const header = fieldNamesArray.map(escapeValue).join(',');

  const rows = myJSON.map(arrayEntry => {
    return fieldNamesArray.map((field) => {
      return escapeValue(arrayEntry[field]);
    }).join(',');
  }).join('\n');

  return `${header}\n${rows}`;
};

Hopefully this explanation is useful :)

Answer №25

Transforming data with Python:

import pandas as pd

data = pd.read_json("./dataset.json")
data.to_csv("./dataset.csv")

Answer №26

My approach is unique because it supports dynamic columns unlike other solutions that rely on the first row to determine the columns:

function convertToCsv(data, replacer = (_, v) => v) {
    let csvArray = [[]]

    for (const record of data) {
        let row = []
        for (const key in record) {
            let columnIndex = csvArray[0].indexOf(key)

            if (columnIndex === -1) {
                columnIndex = csvArray[0].length
                csvArray[0].push(key)
            }

            row[columnIndex] = replacer(key, record[key])
        }
        csvArray.push(row.join(","))
    }

    csvArray[0] = csvArray[0].join(",")

    return csvArray.join("\r\n")
}

If needed, you can provide a custom replacer function to manipulate specific column values.

Answer №27

While not an exact match for the original request, this solution could prove to be beneficial. Within my personal ~/.zshrc file, I have implemented a function that pulls JSON data from a URL and converts it into a CSV format using jq. To utilize this function, you may need to install jq by running the command brew install jq

json_to_csv() {
  url=$1
  filename=$2

curl -s "$url" | jq -r '(.data[0] | keys_unsorted) as $headers | $headers, (.data[] | [.[$headers[]]]) | @csv' > "$filename"
}

# Usage: json_to_csv <url> <filename>
# If your URL includes a '?' query parameter, remember to enclose the entire URL in single or double quotes.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

JavaScript - Navigating through JSON object in reverse (from leaf to root) direction

FamilyTree= { "name":"Family", "photo":"images/family.jpg", "members":[ { "name":"Parent", "photo":"images/parent.jpg", "relationships":[ { "name":"Spouse", "photo":"images/spouse.jpg" }, ...

There was an issue with the Discord.js (v12) Giveaway Command that resulted in an error stating "Error: Cannot read property 'hasPermission' of undefined"

Hey everyone, I'm trying to develop my own Discord bot and I want to add a giveaway command to it. I found an example code online that I tried to implement, but unfortunately, it's not working as expected... const ms = require('ms'); c ...

Expecting a declaration statement for exporting React

When attempting to export my component, I encounter an error in my editor stating export declaration statement expected Here is the code snippet: export Header from './Header/Header'; However, if I modify it like this: export {default as Head ...

Troubleshooting Node.js - MongoDB document removal issue

I am attempting to delete all documents from a collection that contain a field named uuid with values matching the $in operator along with an array I provide. However, for some reason the deletion is not functioning as expected. Below is the code snippet a ...

The local variable within the Angular constructor is not initialized until the ngOnInit() function is invoked

I am encountering difficulties with making backend calls from Angular. In my component, I am fetching the "category" parameter from the URL as shown below: export class ProductsComponent{ productList = [] category = "" $params; $products ...

Guide to extracting values from changing key JSON with Retrofit

https://i.sstatic.net/JhJ5a.pngI received the following response from an API. How can I parse this Json using retrofit? { "country1":{ "id":"0", "name":"Jack" }, "country2":{ "id":"1", "name":"Ri ...

lint-staged executes various commands based on the specific folder

Within my project folder, I have organized the structure with two subfolders: frontend and backend to contain their respective codebases. Here is how the root folder is set up: - backend - package.json - other backend code files - frontend - p ...

Developing a function to handle form submissions using ajax

I need help creating a function to send $_POST data using ajax. I tried the following code but it's not functioning properly. function sendData(variable, value){ var e = value; bar = variable; $.ajax({ type: 'POST&a ...

Bootstrap Toggle Button with Dropdown Menu

I have a button-group with font awesome icons and a dropdown on one of them, as illustrated in the example below. I am trying to toggle the button status, but for some reason, the 'active' class is automatically removed on mouseout. It seems to ...

defineProps withDefaults "The type is lacking the following properties from the specified type"

I am currently working on a custom Button component with some unique functionality: <script lang="ts" setup> import { computed, ref } from 'vue'; const { type = 'button', color = 'primary', disabled = fa ...

Tips for parsing through extensive JSON documents containing diverse data types

In the process of developing an npm package that reads json files and validates their content against predefined json-schemas, I encountered issues when handling larger file sizes (50MB+). When attempting to parse these large files, I faced memory allocati ...

Searching for values in JSON using jQuery's autocomplete feature

I have implemented jquery autocomplete with a json request in my code. Here is the code snippet for the autocomplete feature: $("#company_name").autocomplete({ source: function( request, response ) { $.ajax({ url: "https://ur ...

Customizing JSON response with Spring MVC

I'm facing a challenge with my RestController method that returns data in a custom JSON format. Originally, I was using a HashMap to build the response: // The method which builds custom JSON response from retrieved data public List<HashMap<Str ...

Issue with AngularJS: Controller unable to access property of ng-model object

I am looking to create a reusable controller that can be used by multiple views. This controller will essentially serve as a template. The issue I'm facing is with setting up simple validation. The problem lies in the fact that the properties set in ...

What does the file_get_contents('php://input') contain when used with an HTML form submission?

I'm seeking clarification regarding the implementation of file_get_contents('php://input'). Specifically, I am interested in understanding what data is actually returned when this code is utilized within a submitted <form> for processi ...

Activate the current page link in materializecss pagination

I stumbled upon a fantastic pagination plugin for Materializescss UI, available on Github, and it's working like a charm. Now, I am looking to customize this plugin by adding the ability to set the current page and have it highlighted as active. Take ...

Disabling a button when the specified class condition is met

I am currently developing an application that allows users to add individuals from an API to a list within the app. Each time a person is added, a new Bootstrap card is generated. I am currently facing a challenge regarding how to disable the "Watch Stream ...

Issue with NullInjectorError: Failure to provide a custom component - Attempting to add to providers without success

I keep encountering errors during my test attempts... Despite looking into similar issues, I am still facing problems even after adding my custom LoginComponent to app.module.ts providers. It is already included in the imports section. app.module.ts @Ng ...

The function react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxDEV(...) is not recognized

For my react-redux project, I utilized json-server as the server for managing orders. The status of each order is saved in the state within UiReducer and is then accessed in the "OrderStatusPage". The current NODE_ENV configuration is set to "development". ...

Guide to retrieving information from an API and incorporating it into a fresh JSON structure

I am currently working on fetching data from an existing API endpoint and using a part of that data to create a new endpoint in Node.js with Express. Specifically, I am trying to retrieve the userId from https://jsonplaceholder.typicode.com/posts/1 and int ...