JSON nested a formato CSV Node.js

Soy nuevo en progtwigción y estoy trabajando en un proyecto que recibió una respuesta JSON anidada de una API usando node.js. Espero encontrar un método simple para convertir este JSON en un CSV para exportación. He buscado un poco los paquetes jsonexport y nestedcsv2json, pero no he podido obtener el formato correcto y no puedo iterar mi respuesta JSON.

Básicamente la respuesta JSON es la siguiente:

{ '2016-01-31': { chats: 0, missed_chats: 5 }, '2016-02-01': { chats: 60, missed_chats: 7 }, '2016-02-02': { chats: 56, missed_chats: 1 }, '2016-02-03': { chats: 46, missed_chats: 0 }, '2016-02-04': { chats: 63, missed_chats: 2 }, '2016-02-05': { chats: 59, missed_chats: 4 }, '2016-02-06': { chats: 0, missed_chats: 1 } } 

El problema que tengo es que el tamaño de esto puede variar según el rango de fechas que ingrese el usuario. Así que tendré que recorrer las fechas devueltas y luego extraer el JSON nested. Podría ser una fecha o 100 fechas.

Estoy buscando hacer un formato CSV con encabezados que pueda exportar:

  Date Chats Missed Chats 2016-02-02 60 7 

Esto debería ser rápido y fácil, pero estoy luchando para hacer esto bien. Cualquier consejo o ayuda es muy apreciado. ¡Gracias!

Esto genera una cadena CSV separada por punto y coma. Edite el separador (por ejemplo, reemplácelo con tab \t ) para adaptarlo a sus necesidades:

 var json = { '2016-01-31': { chats: 0, missed_chats: 5 }, '2016-02-01': { chats: 60, missed_chats: 7 }, '2016-02-02': { chats: 56, missed_chats: 1 }, '2016-02-03': { chats: 46, missed_chats: 0 }, '2016-02-04': { chats: 63, missed_chats: 2 }, '2016-02-05': { chats: 59, missed_chats: 4 }, '2016-02-06': { chats: 0, missed_chats: 1 } }; var headers = 'Date;Chats;Missed chats'; var csv = headers + '\r\n'; for(key in json){ csv += key + ';' + json[key].chats + ';' + json[key].missed_chats + '\r\n' } console.log(csv) 

La salida es:

 Date;Chats;Missed chats 2016-01-31;0;5 2016-02-01;60;7 2016-02-02;56;1 2016-02-03;46;0 2016-02-04;63;2 2016-02-05;59;4 2016-02-06;0;1 

Puede encontrar un ejemplo funcional aquí: https://jsfiddle.net/owd8zsa0/

Esta respuesta obtendrá automáticamente los encabezados (primera línea) y los agregará al CSV.

 var input={ '2016-01-31': { chats: 0, missed_chats: 5 }, '2016-02-01': { chats: 60, missed_chats: 7 }, '2016-02-02': { chats: 56, missed_chats: 1 }, '2016-02-03': { chats: 46, missed_chats: 0 }, '2016-02-04': { chats: 63, missed_chats: 2 }, '2016-02-05': { chats: 59, missed_chats: 4 }, '2016-02-06': { chats: 0, missed_chats: 1 } } function json2csv(input){ var result='' var firstLine=true for (var i in input){ if(firstLine){ firstLine=false result='id\t' for (var j in input[i]){ result+=j +';' } result+='\n' } else{ result+=i+'\t' for (var j in input[i]){ result+=input[i][j] +';' } result+='\n' } } return result } console.log(json2csv(input)); 

Resultará:

 id;chats;missed_chats; 2016-02-01;60;7; 2016-02-02;56;1; 2016-02-03;46;0; 2016-02-04;63;2; 2016-02-05;59;4; 2016-02-06;0;1; 

Usando lodash y el paquete csv :

 var csv = require('csv'); var _ = require('lodash'); var obj = { '2016-01-31': { chats: 0, missed_chats: 5 }, '2016-02-01': { chats: 60, missed_chats: 7 }, '2016-02-02': { chats: 56, missed_chats: 1 }, '2016-02-03': { chats: 46, missed_chats: 0 }, '2016-02-04': { chats: 63, missed_chats: 2 }, '2016-02-05': { chats: 59, missed_chats: 4 }, '2016-02-06': { chats: 0, missed_chats: 1 } }; // flatten obj to have an array of object like // { date: '2016-01-31', chats: 0, missed_chats: 5 } obj = _.map(obj, function (value, key) { return _.merge({ date: key }, value); }) csv.stringify(obj, { header: true }, function(err, result) { console.log(result); }); /* output: date,chats,missed_chats 2016-01-31,0,5 2016-02-01,60,7 2016-02-02,56,1 2016-02-03,46,0 2016-02-04,63,2 2016-02-05,59,4 2016-02-06,0,1 */ 

La “respuesta JSON” mostrada en la pregunta no es JSON técnicamente válida, por lo que, dado que esta respuesta depende de una herramienta compatible con JSON ( jq ), la primera tarea es convertir la “respuesta JSON” a JSON válido. Esto se puede hacer (por ejemplo) usando json5 o any-json .

Asumiendo que la “respuesta JSON” está en un archivo llamado response.txt, podemos proceder de la siguiente manera, donde $ inicial significa una shell similar a bash:

 $ any-json -format json5 < response.txt | jq -r '. as $in | keys[] | [.] + ($in[.] | [.chats, .missed_chats ]) | @csv' 

Esto produce el siguiente resultado:

 "2016-01-31",0,5 "2016-02-01",60,7 "2016-02-02",56,1 "2016-02-03",46,0 "2016-02-04",63,2 "2016-02-05",59,4 "2016-02-06",0,1 

Esta salida es CSV válida (con coma como carácter separador), pero si desea TSV (con tabulador como separador) o si no desea las comillas dobles, simplemente reemplace @csv por @tsv para producir la siguiente salida:

 2016-01-31 0 5 2016-02-01 60 7 2016-02-02 56 1 2016-02-03 46 0 2016-02-04 63 2 2016-02-05 59 4 2016-02-06 0 1 

En cualquier caso, es trivial agregar una fila de encabezados (ya sea usando jq o de otra manera), así que puedes elegir cómo manejar eso.

Nota: Si usa json5, procederá en dos pasos.