Cómo convertir JSON a formato CSV y almacenarlo en una variable

99

Tengo un enlace que abre datos JSON en el navegador, pero desafortunadamente no tengo ni idea de cómo leerlo. ¿Hay alguna forma de convertir estos datos usando JavaScript en formato CSV y guardarlos en un archivo JavaScript?

Los datos se ven así:

{
  "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\u2019s 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\u2019s 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 \u2013 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"
  }]
}

Lo más cercano que pude encontrar fue: Convertir formato JSON a formato CSV para MS Excel

Pero se descarga en un archivo CSV, lo guardo en una variable, todos los datos convertidos.

También me gustaría saber cómo cambiar los caracteres de escape: '\u2019'volver a la normalidad.


Probé este código:

<!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. 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"
        }
      ]
    }
    //var objJson = JSON.parse(json3.items);

    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>

Pero no parece funcionar. ¿Puede ayudarme alguien, por favor?

praneybehl
fuente
¿Qué pasa con zachhunter.com/2011/06/json-to-csv ?
ldiqual
tienes un buen código ahí. la línea que se descarga es window.open ("data: text / csv; charset = utf-8," + escape (str)) .. simplemente omítala si no la necesitas. y la cadena csv se mantiene en esta variable: str
zdrsh
CSV no puede manejar múltiples niveles de datos (también) como JSON. ¿Cómo esperaría que su JSON se vea como CSV? 2,Apple iPhone 4S Sale Cancelled in Beijing Amid Chaos (Design You Trust), ...?
Stefan
Me gustaría que mis datos se vean así: Venta de iPhone 4S de Apple cancelada en Beijing en medio del caos (Design You Trust), Anuncie aquí con BSA Apple canceló la venta programada de iPhone 4S en una de sus tiendas .. ,,,,,, etc. Puedo eliminar fácilmente estos caracteres iniciales: "{" count ": 2," items ": [:"
praneybehl
@zdrsh sí, pero por alguna razón no puedo hacer que funcione.
praneybehl

Respuestas:

154

Una forma más elegante de convertir json a csv es usar la función map sin ningún marco:

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)

Salida:

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"

Actualización ES6 (2016)

Use esta sintaxis menos densa y también JSON.stringify para agregar comillas a las cadenas mientras mantiene los números sin comillas:

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')

console.log(csv)
Christian Landgren
fuente
3
Me gusta la concisión de esto, pero debe tenerse en cuenta que no maneja algunas cosas que algunos podrían encontrar ideales. por ejemplo, cada registro en su propia línea, números y valores booleanos sin comillas, etc.
scunliffe
2
Puede agregar un + "\ r \ n" después de fields.map () para obtener un registro por fila. Para obtener números sin comillas, puede usar JSON.stringify (fila [fieldName]) en su lugar, que solo citará cadenas y dejará los números sin comillas.
Christian Landgren
1
@scunliffe: Actualicé un nuevo ejemplo con JSON.stringify; debería manejar los casos que describiste.
Christian Landgren
1
@marathon, Good catch, actualizó el ejemplo con un reemplazador para manejar casos nulos por separado. Si no se usa un sustituto, el valor nulo se generará como null: ahora los ejemplos deben manejar correctamente tanto nulo como no definido y números.
Christian Landgren
3
Vale la pena señalar que esto escapa a las cadenas entre comillas, lo \"que permite que algunos campos "salgan" de su columna cuando se ven en Excel (que parece preferir ""como carácter de escape para las comillas). Esto se puede resolver agregando .replace(/\\"/g, '""')al final de JSON.stringify(row[fieldName], replacer)como señalé en mi respuesta anterior.
user1274820
51

Ok, finalmente conseguí que este código funcionara:

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

        // Example
        $(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>

Muchas gracias por todo el apoyo a todos los colaboradores.

Praney

praneybehl
fuente
1
Intenté esto. Tengo tres columnas, pero en Excel, todas las cosas vendrán en una sola columna
Nithesh Narayanan
1
Nithesh, debe especificar ',' como delimitador
Jacer Omri
Gracias por compartir esto aquí. Solo lo usé y funciona perfecto.
Ramin Arabbagheri
¡Gracias por esto! Agregué lo siguiente para evitar tener "[objeto Objeto]" en la línea si una celda contiene un objeto. if (_.isObject (matriz [i] [índice])) {matriz [i] [índice] = JSON.stringify (matriz [i] [índice]); }. (usa guión bajo, pero puede cambiar a vainilla)
Claytronicon
1
@Sunil Encontré que si los valores contienen comas, se rompe. Para mis necesidades, acabo de hacer esto: var re = new RegExp (',', 'g'); array [i] [index] = array [i] [index] .toString (). replace (re, ';')
claytronicon
17

Muy buena solución de praneybehl, pero si alguien quiere guardar los datos como un csvarchivo y usar un blobmétodo, puede consultar esto:

function JSONToCSVConvertor(JSONData, ReportTitle, ShowLabel) {     

//If JSONData is not an object then JSON.parse will parse the JSON string in an Object
var arrData = typeof JSONData != 'object' ? JSON.parse(JSONData) : JSONData;
var CSV = '';    
//This condition will generate the Label/Header
if (ShowLabel) {
    var row = "";

    //This loop will extract the label from 1st index of on array
    for (var index in arrData[0]) {
        //Now convert each value to string and comma-seprated
        row += index + ',';
    }
    row = row.slice(0, -1);
    //append Label row with line break
    CSV += row + '\r\n';
}

//1st loop is to extract each row
for (var i = 0; i < arrData.length; i++) {
    var row = "";
    //2nd loop will extract each column and convert it in string comma-seprated
    for (var index in arrData[i]) {
        row += '"' + arrData[i][index] + '",';
    }
    row.slice(0, row.length - 1);
    //add a line break after each row
    CSV += row + '\r\n';
}

if (CSV == '') {        
    alert("Invalid data");
    return;
}   

//this trick will generate a temp "a" tag
var link = document.createElement("a");    
link.id="lnkDwnldLnk";

//this part will append the anchor tag and remove it after automatic click
document.body.appendChild(link);

var csv = CSV;  
blob = new Blob([csv], { type: 'text/csv' }); 
var csvUrl = window.webkitURL.createObjectURL(blob);
var filename = 'UserExport.csv';
$("#lnkDwnldLnk")
.attr({
    'download': filename,
    'href': csvUrl
}); 

$('#lnkDwnldLnk')[0].click();    
document.body.removeChild(link);
}
Samuel Joy
fuente
Esta solución funciona pero tiene algunos puntos extraños: define var rowdos veces (si las declaraciones y los bucles for no crean cierres). Además, el ciclo de etiqueta / encabezado probablemente podría reducirse a una línea:Object.keys(arrData[0]).join(',')
ccnokes
Tu respuesta está funcionando. Pero para casos como si alguna columna no está disponible para alguna fila, no considerará la columna que falta y no volverá a alinear los datos de la columna para los datos de esa fila.
sms
Pude hacer que este método funcionara, pero tuve que editar parte del código para: 1. trabajar sin JQuery: document.getElementById("lnkDwnldLnk").download = filename; document.getElementById("lnkDwnldLnk").href = csvUrl;2. trabajar en IE11: if (window.navigator && window.navigator.msSaveOrOpenBlob) { window.navigator.msSaveOrOpenBlob(blob, filename); } else { document.getElementById('lnkDwnldLnk').click(); }
Jason
17

Solo quería agregar un código aquí para las personas en el futuro, ya que estaba tratando de exportar JSON a un documento CSV y descargarlo.

Utilizo $.getJSONpara extraer datos json de una página externa, pero si tiene una matriz básica, puede usarla.

Esto usa el código de Christian Landgren para crear los datos csv.

$(document).ready(function() {
    var JSONData = $.getJSON("GetJsonData.php", function(data) {
        var items = data;
        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');

        //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";  //Name the file here
        document.body.appendChild(downloadLink);
        downloadLink.click();
        document.body.removeChild(downloadLink);
    });
});

Editar: Vale la pena señalar que JSON.stringifyse escaparán las comillas entre comillas al agregar \". Si ve el CSV en Excel, no le gusta que sea un carácter de escape.

Puede agregar .replace(/\\"/g, '""')al final de JSON.stringify(row[fieldName], replacer)para mostrar esto correctamente en Excel (esto reemplazará \"con ""cuál es lo que Excel prefiere).

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

usuario1274820
fuente
11

Si alguien quería descargarlo también.
Aquí hay una pequeña función increíble que convertirá una matriz de objetos JSON a csv y luego la descargará.

downloadCSVFromJson = (filename, arrayOfJson) => {
  // convert JSON to CSV
  const replacer = (key, value) => value === null ? '' : value // specify how you want to handle null values here
  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 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);
};

Entonces llámalo así:

this.downloadCSVFromJson(`myCustomName.csv`, this.state.csvArrayOfJson)
waz
fuente
esto no parece funcionar para las cosas cuando hay una sola cita en uno de los elementos, por ejemploCap D'antibes
MidnightDataGeek
9

Hay varias opciones disponibles para reutilizar las potentes bibliotecas existentes que se basan en estándares.

Si utiliza D3 en su proyecto, simplemente puede invocar:

    d3.csv.formato d3.csv.formatRowsfunciones para convertir una matriz de objetos en una cadena csv.

    d3.csv.formatRows le brinda un mayor control sobre qué propiedades se convierten a csv.

    Consulte las páginas wiki d3.csv.format y d3.csv.formatRows .

También hay otras bibliotecas disponibles como jquery-csv , PapaParse . Papa Parse no tiene dependencias, ni siquiera jQuery.

Para complementos basados ​​en jquery, marque esto .

nagu
fuente
1
Esto funciono muy bien para mi. Tenga en cuenta que la API D3 ha cambiado desde 2017.v3 (actualmente es v4): github.com/d3/d3-dsv/blob/v1.2.0/README.md#csvFormat
aljabear
7

Prueba estos ejemplos

Ejemplo 1:

JsonArray = [{
    "AccountNumber": "123",
    "AccountName": "abc",
    "port": "All",
    "source": "sg-a78c04f8"

}, {
    "Account Number": "123",
    "Account Name": "abc",
    "port": 22,
    "source": "0.0.0.0/0",
}]

JsonFields = ["Account Number","Account Name","port","source"]

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

    JsonArray.forEach(element => {
        AccountNumber = element.AccountNumber;
        AccountName   = element.AccountName;
        port          = element.port
        source        = element.source

        csvStr += AccountNumber + ',' + AccountName + ','  + port + ',' + source + "\n";
        })
        return csvStr;
}

Ejemplo 2:

JsonArray = [{
    "AccountNumber": "1234",
    "AccountName": "abc",
    "inbound": [{
        "port": "All",
        "source": "sg-a78c04f8"
    },
    {
        "port": 22,
        "source": "0.0.0.0/0",
    }]
}]

JsonFields = ["Account Number", "Account Name", "port", "source"]

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

    JsonArray.forEach(element => {
        AccountNumber = element.AccountNumber;
        AccountName = element.AccountName;
        
        element.inbound.forEach(inboundELe => {
            port = inboundELe.port
            source = inboundELe.source
            csvStr += AccountNumber + ',' + AccountName + ',' + port + ',' + source + "\n";
        })
    })
    return csvStr;
}

Incluso puede descargar el archivo csv usando el siguiente código:

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();
}
YouBee
fuente
4
<!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>
</head>
<body>
    <h1>This page does nothing....</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 = 'UserExport.csv';
        jQuery("#lnkDwnldLnk")
        .attr({
            'download': filename,
            'href': csvUrl
        });
        jQuery('#lnkDwnldLnk')[0].click();
        document.body.removeChild(link);
    </script>
</body>
</html>
agravat.in
fuente
1

Esta es una forma de hacerlo para objetos dinámicamente profundos de una manera orientada a objetos para las versiones más nuevas de js. es posible que deba cambiar el seperatortipo tras la región.

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

    let str = "";
    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;
            }
        });
        str += line + "\r\n";
    });
    return header + "\r\n" + str;
}
Nicola Munz slimxshady
fuente
1

A veces, los objetos tienen diferentes longitudes. Así que me encontré con el mismo problema que Kyle Pennell. Pero en lugar de ordenar la matriz, simplemente la recorremos y elegimos la más larga. La complejidad del tiempo se reduce a O (n), en comparación con O (n log (n)) cuando se clasifica primero.

Comencé con el código de la versión actualizada ES6 (2016) de Christian Landgren .

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

    // specify how you want 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');
}
ctholho
fuente
1

Quería burlarse de la respuesta de @Christian Landgren anterior. Estaba confundido por qué mi archivo CSV solo tenía 3 columnas / encabezados. Esto se debió a que el primer elemento en mi json solo tenía 3 claves. Así que debes tener cuidado con la const header = Object.keys(json[0])línea. Se supone que el primer elemento de la matriz es representativo. Tenía JSON desordenado con algunos objetos que tienen más o menos.

Así que agregué array.sorta esto que ordenará el JSON por número de claves. De esa manera, su archivo CSV tendrá el número máximo de columnas.

Esta también es una función que puede usar en su código. ¡Solo alimentalo con JSON!

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 // specify how you want to handle null values here
    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)
}
Kyle Pennell
fuente
1

Una adaptación de la respuesta de praneybehl para trabajar con objetos anidados y separador de pestañas

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
}
DigaoParceiro
fuente
1
¡Esto funciona perfecto para copiar y pegar directamente en Excel / Sheets! ¡Gracias!
UP3
0

Escriba Csv.

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('Some error occured - file either not saved or corrupted file saved.');
      } else{
        console.log('It\'s saved!');
      }
      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;
}
Ashish Gupta
fuente
2
No creo que esto tenga mucho valor. Por favor, editar para añadir algunas explicaciones sobre cómo esto está ayudando a responder a la pregunta.
fedorqui 'SO deja de dañar'
0

Es curioso que no haya nada completo ni que funcione aquí (IE ni node.js). Responda a una pregunta similar, un JSON un poco estructurado (suponga que no es necesario copiarlo nuevamente), también se incluye un fragmento de demostración. Conversión de JSON a CSV (JavaScript): Cómo formatear correctamente la conversión de CSV Espero que no solo el convertidor de tipo único, también en mi Github (mencionado en el perfil) sea similar al utilizado para analizar la estructura JSON desconocida. Soy autor del código en esta respuesta y de todo el código en mi Github (excepto algunos proyectos que comenzaron como fork / + translation).

Tom
fuente
0

Personalmente , usaría la biblioteca d3-dsv para hacer esto. ¿Por qué hacerlo reinvent the wheel?


import { csvFormat } from 'd3-dsv';
/**
 * Based on input data convert it to csv formatted string
 * @param (Array) columnsToBeIncluded array of column names (strings)
 *                which needs to be included in the formated csv
 * @param {Array} input array of object which need to be transformed to string
 */
export function convertDataToCSVFormatString(input, columnsToBeIncluded = []) {
  if (columnsToBeIncluded.length === 0) {
    return csvFormat(input);
  }
  return csvFormat(input, columnsToBeIncluded);
}

Con la agitación de árboles, puede importar esa función particular de la d3-dsvbiblioteca

Anuj
fuente
0

Aquí está mi versión simple de convertir una matriz de objetos en CSV (asumiendo que todos esos objetos comparten los mismos atributos):

var csv = []
if (items.length) {
  var keys = Object.keys(items[0])
  csv.push(keys.join(','))
  items.forEach(item => {
    let vals = keys.map(key => item[key] || '')
    csv.push(vals.join(','))
  })
}

csv = csv.join('\n') 
Nimrod
fuente