Como converter JSON em formato CSV e armazenar em uma variável

97

Tenho um link que abre dados JSON no navegador, mas infelizmente não tenho ideia de como lê-lo. Existe uma maneira de converter esses dados usando JavaScript no formato CSV e salvá-los no arquivo JavaScript?

Os dados se parecem com:

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

O mais próximo que consegui encontrar foi: Converter o formato JSON para o formato CSV para MS Excel

Mas ele baixa em um arquivo CSV, eu armazeno em uma variável, todos os dados convertidos.

Também gostaria de saber como alterar os caracteres de escape: de '\u2019'volta ao normal.


Tentei 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>

Mas não parece funcionar. Alguém pode ajudar por favor?

praneybehl
fonte
você tem um bom código lá. a linha que baixa é window.open ("data: text / csv; charset = utf-8," + escape (str)) .. apenas pule se você não precisar. e a string csv é mantida nesta variável: str
zdrsh
CSV não pode lidar com vários níveis de dados (também) como JSON. Como você espera que seu JSON seja um CSV? 2,Apple iPhone 4S Sale Cancelled in Beijing Amid Chaos (Design You Trust), ...?
Stefan
Gostaria que meus dados fossem parecidos com: Apple iPhone 4S Venda cancelada em Pequim Amid Chaos (Design You Trust), Anuncie aqui com BSA Apple cancelou sua venda programada de iPhone 4S em uma de suas lojas .. ,,,,,, etc. Posso remover facilmente estes caracteres iniciais: "{" count ": 2," items ": [:"
praneybehl
@zdrsh sim, mas por algum motivo não consigo fazer funcionar.
praneybehl

Respostas:

151

Uma maneira mais elegante de converter json em csv é usar a função map sem qualquer estrutura:

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)

Resultado:

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"

Atualizar ES6 (2016)

Use esta sintaxe menos densa e também JSON.stringify para adicionar aspas a strings, mantendo os números sem aspas:

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
fonte
3
Eu gosto da concisão disso, mas deve-se notar que não lida com algumas coisas que alguns podem achar ideais. por exemplo, cada registro em sua própria linha, números e booleanos deixados sem
aspas
2
Você pode adicionar um + "\ r \ n" após o fields.map () para obter um registro por linha. Para obter números sem aspas, você pode usar JSON.stringify (row [fieldName]) em vez disso, que citará apenas strings e deixará os números sem aspas.
Christian Landgren
1
@scunliffe: Eu atualizei um novo exemplo com JSON.stringify - ele deve lidar com os casos que você descreveu.
Christian Landgren
1
@marathon, Good catch, atualizou o exemplo com um substituto para lidar com casos nulos separadamente. Se nenhum substituto for usado, nulo será gerado como null- agora os exemplos devem lidar com nulos, indefinidos e números corretamente.
Christian Landgren de
3
É interessante notar que isso escapa strings entre aspas usando o \"que permite que alguns campos "saltem" de suas colunas quando visualizados no Excel (o que parece preferir ""como um caractere de escape para aspas). Isso pode ser resolvido adicionando .replace(/\\"/g, '""')ao final de, JSON.stringify(row[fieldName], replacer)conforme observei na minha resposta acima.
user1274820
51

Ok, finalmente fiz este código funcionar:

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

Muito obrigado por todo o apoio a todos os contribuidores.

Praney

praneybehl
fonte
1
Eu tentei isso. eu tenho três colunas, mas no excel todas as coisas virão em uma única coluna
Nithesh Narayanan
1
Nithesh você deve especificar ',' como um delimitador
Jacer Omri
Obrigado por compartilhar isso aqui. Apenas usei e funciona perfeitamente.
Ramin Arabbagheri
Obrigado por isso! Eu adicionei o seguinte para evitar ter "[objeto Object]" na linha se uma célula contiver um objeto. if (_.isObject (array [i] [index])) {array [i] [index] = JSON.stringify (array [i] [index]); } (usa sublinhado, mas você pode mudar para baunilha)
claytronicon
1
@ Sunil Eu descobri que se os valores contêm vírgulas, ele quebra. Para minhas necessidades, acabei de fazer isso: var re = new RegExp (',', 'g'); matriz [i] [índice] = matriz [i] [índice] .toString (). substituir (re, ';')
claytronicon
17

Muito boa solução por praneybehl, mas se alguém quiser salvar os dados como um csvarquivo e usando um blobmétodo, eles podem se referir a isto:

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
fonte
Esta solução funciona, mas tem alguns pontos estranhos - você define var rowduas vezes (instruções if e loops for não criam fechamentos). Além disso, o loop de rótulo / cabeçalho provavelmente poderia ser reduzido a uma linha:Object.keys(arrData[0]).join(',')
ccnokes de
Sua resposta está funcionando. Mas, para casos como se alguma coluna não estiver disponível para alguma linha, ele não considerará a coluna ausente e não realinhará os dados da coluna para os dados dessa linha.
sms de
Consegui fazer esse método funcionar, mas tive que editar parte do código para: 1. trabalhar sem JQuery: document.getElementById("lnkDwnldLnk").download = filename; document.getElementById("lnkDwnldLnk").href = csvUrl;2. trabalhar no IE11: if (window.navigator && window.navigator.msSaveOrOpenBlob) { window.navigator.msSaveOrOpenBlob(blob, filename); } else { document.getElementById('lnkDwnldLnk').click(); }
Jason
17

Eu só queria adicionar um código aqui para as pessoas no futuro, já que estava tentando exportar JSON para um documento CSV e baixá-lo.

eu uso $.getJSON para extrair dados json de uma página externa, mas se você tiver um array básico, você pode simplesmente usá-lo.

Isso usa o código de Christian Landgren para criar os dados 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: é importante notar que JSON.stringifyirá escapar as aspas ao adicionar\" . Se você visualizar o CSV no excel, ele não gosta disso como um caractere de escape.

Você pode adicionar .replace(/\\"/g, '""')ao final de JSON.stringify(row[fieldName], replacer)para exibi-lo corretamente no Excel (isso substituirá \"por"" que é o que excel prefere).

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

usuário1274820
fonte
11

Se alguém quiser fazer o download também.
Aqui está uma pequena função incrível que converterá uma matriz de objetos JSON em csv e, em seguida, fará o download.

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

Em seguida, chame-o assim:

this.downloadCSVFromJson(`myCustomName.csv`, this.state.csvArrayOfJson)
waz
fonte
isso não parece funcionar para as coisas quando há uma aspas simples em um dos elementos, por exemploCap D'antibes
MidnightDataGeek
9

Existem várias opções disponíveis para reutilizar as poderosas bibliotecas existentes que são baseadas em padrões.

Se acontecer de você usar D3 em seu projeto, você pode simplesmente invocar:

    d3.csv.formatou d3.csv.formatRowsfunções para converter um array de objetos em string csv.

    d3.csv.formatRows oferece maior controle sobre quais propriedades são convertidas em csv.

    Por favor, consulte d3.csv.format e d3.csv.formatRows wiki páginas.

Existem outras bibliotecas disponíveis, como jquery-csv , PapaParse . Papa Parse não tem dependências - nem mesmo jQuery.

Para plug-ins baseados em jquery, verifique isto .

nagu
fonte
1
Isso funcionou muito bem para mim. Observe que a API D3 mudou desde 2017.v3 (atualmente é v4): github.com/d3/d3-dsv/blob/v1.2.0/README.md#csvFormat
aljabear
6

Experimente estes exemplos

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

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

Você pode até baixar o arquivo csv usando o seguinte 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
fonte
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>
desagravat.in
fonte
1

Aqui está uma maneira de fazer isso para objetos dinamicamente profundos de uma forma orientada a objetos para as versões mais recentes do js. você pode ter que alterar o tipo de separação após a região.

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
fonte
1

Às vezes, os objetos têm comprimentos diferentes. Então, tive o mesmo problema de Kyle Pennell. Mas, em vez de classificar o array, simplesmente o percorremos e escolhemos o mais longo. A complexidade do tempo é reduzida a O (n), em comparação com O (n log (n)) ao classificar primeiro.

Comecei com o código da versão ES6 (2016) atualizada 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
fonte
1

Eu queria resumir a resposta de @Christian Landgren acima. Fiquei confuso por que meu arquivo CSV tinha apenas 3 colunas / cabeçalhos. Isso ocorreu porque o primeiro elemento em meu json tinha apenas 3 chaves. Então você precisa ter cuidado com oconst header = Object.keys(json[0]) linha. Ele está assumindo que o primeiro elemento da matriz é representativo. Eu tinha um JSON bagunçado que com alguns objetos tendo mais ou menos.

Então, adicionei um array.sorta isso que ordenará o JSON por número de chaves. Assim, seu arquivo CSV terá o número máximo de colunas.

Essa também é uma função que você pode usar em seu código. Basta alimentá-lo com 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
fonte
1

Uma adaptação da resposta praneybehl para trabalhar com objetos aninhados e separador de tabulação

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
fonte
1
Isso funciona perfeitamente para copiar e colar direto no Excel / Planilhas! Obrigado!
UP3
0

Escreva 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
fonte
2
Não acho que isso tenha muito valor. Por favor editar para adicionar algumas explicações sobre como isso está ajudando a responder à pergunta.
fedorqui 'SO pare de prejudicar'
0

Engraçado nada completo nem funcionando aqui (IE nem node.js). Responda a uma pergunta semelhante, um JSON pouco estruturado (suponha que não haja necessidade de copiá-lo novamente), também inclui um trecho de demonstração. Conversão JSON para CSV (JavaScript): Como formatar corretamente a conversão CSV Espero que não apenas o conversor de tipo único, também no meu Github (mencionado no perfil) seja usado de forma semelhante para analisar a estrutura JSON desconhecida. Eu sou o autor do código nesta resposta e de todo o código no meu Github (exceto alguns projetos iniciados como tradução fork / +).

Tom
fonte
0

Pessoalmente, eu usaria a biblioteca d3-dsv para fazer isso. Por quê 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);
}

Com o tremor de árvore, você pode simplesmente importar essa função específica da d3-dsvbiblioteca

Anuj
fonte
0

Esta é minha versão simples de converter uma matriz de objetos em CSV (assumindo que todos os objetos compartilhem os mesmos 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
fonte