Jak przekonwertować JSON do formatu CSV i zapisać w zmiennej

103

Mam link, który otwiera dane JSON w przeglądarce, ale niestety nie mam pojęcia, jak to odczytać. Czy istnieje sposób na przekonwertowanie tych danych za pomocą JavaScript w formacie CSV i zapisanie ich w pliku JavaScript?

Dane wyglądają następująco:

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

Najbliższe, jakie udało mi się znaleźć, to: Konwertuj format JSON na format CSV dla MS Excel

Ale ściąga w pliku CSV, ja przechowuję w zmiennej całość przekonwertowanych danych.

Chciałbym również wiedzieć, jak zmienić znaki ucieczki: z '\u2019'powrotem do normalności.


Wypróbowałem ten kod:

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

Ale to nie działa. Czy ktoś może pomóc?

praneybehl
źródło
masz tam dobry kod. linia, która pobiera to window.open ("data: text / csv; charset = utf-8," + escape (str)) .. po prostu pomiń ją, jeśli jej nie potrzebujesz. a ciąg csv jest przechowywany w tej zmiennej: str
zdrsh
CSV nie obsługuje wielu poziomów danych (jak również), jak JSON. Jak spodziewałbyś się, że Twój JSON będzie wyglądał jako CSV? 2,Apple iPhone 4S Sale Cancelled in Beijing Amid Chaos (Design You Trust), ...?
Stefan
Chciałbym, aby moje dane wyglądały następująco: Wyprzedaż Apple iPhone 4S anulowana w Pekinie pośród chaosu (Design You Trust), Reklamuj się tutaj z BSA Firma Apple anulowała zaplanowaną sprzedaż iPhone'a 4S w jednym ze swoich sklepów ... Mogę łatwo usunąć te początkowe znaki: "{" count ": 2," items ": [:"
praneybehl
@zdrsh tak, ale z jakiegoś powodu nie jestem w stanie zmusić go do pracy.
praneybehl

Odpowiedzi:

157

Bardziej eleganckim sposobem konwersji json do csv jest użycie funkcji map bez żadnego frameworka:

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)

Wynik:

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"

Zaktualizuj ES6 (2016)

Użyj tej mniej zagęszczonej składni, a także JSON.stringify, aby dodać cudzysłowy do ciągów, zachowując liczby bez cytowania:

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
źródło
3
Podoba mi się zwięzłość tego, ale należy zauważyć, że nie dotyczy kilku rzeczy, które niektórzy mogą uznać za idealne. np. każdy rekord w osobnym wierszu, liczby i wartości logiczne pozostawione bez
cytowania
2
Możesz dodać + "\ r \ n" po fields.map (), aby uzyskać jeden rekord na wiersz. Aby uzyskać liczby niecytowane, możesz użyć JSON.stringify (wiersz [nazwa_pola]), który będzie cytował tylko ciągi znaków i pozostawi liczby bez cytowania.
Christian Landgren
1
@scunliffe: Zaktualizowałem nowy przykład za pomocą JSON.stringify - powinien obsługiwać opisane przez Ciebie przypadki.
Christian Landgren
1
@marathon, Good catch, zaktualizował przykład za pomocą zamiennika, aby osobno obsługiwać przypadki zerowe. Jeśli nie zostanie użyty żaden zamiennik, zostanie wyprowadzone null jako null- teraz przykłady powinny poprawnie obsługiwać zarówno null, undefined, jak i liczby.
Christian Landgren
4
Warto zauważyć, że \"powoduje ""to uniknięcie ciągów znaków w cudzysłowach, co umożliwia niektórym polom „wyskakiwanie” z kolumny podczas przeglądania w programie Excel (co wydaje się być preferowane jako znak zmiany znaczenia w cudzysłowach). Można to rozwiązać, dodając .replace(/\\"/g, '""')na końcu, JSON.stringify(row[fieldName], replacer)jak zauważyłem w mojej odpowiedzi powyżej.
user1274820
54

Ok, w końcu ten kod działa:

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

Bardzo dziękuję za wsparcie dla wszystkich współpracowników.

Praney

praneybehl
źródło
1
Próbowałem tego. mam trzy kolumny, ale w programie Excel wszystkie rzeczy pojawią się w jednej kolumnie
Nithesh Narayanan
1
Nithesh należy określić jako separator „,”
Jacer Omri
Dzięki za udostępnienie tego tutaj. Po prostu go użyłem i działa idealnie.
Ramin Arabbagheri
Dzięki za to! Dodałem następujący tekst, aby uniknąć umieszczania w wierszu wyrażenia „[obiekt obiekt]”, jeśli komórka zawiera obiekt. if (_.isObject (tablica [i] [indeks])) {tablica [i] [indeks] = JSON.stringify (tablica [i] [indeks]); }. (używa podkreślenia, ale możesz zmienić na waniliowy)
claytronicon
1
@Sunil Znalazłem, jeśli wartości zawierają przecinki, to pęka. Na moje potrzeby właśnie zrobiłem to: var re = new RegExp (',', 'g'); array [i] [index] = array [i] [index] .toString (). replace (re, ';')
claytronicon,
18

Bardzo fajne rozwiązanie autorstwa praneybehl, ale jeśli ktoś chce zapisać dane jako csvplik i za pomocą blobmetody, może polecić to:

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
źródło
To rozwiązanie działa, ale ma kilka dziwnych punktów - definiujesz var rowdwa razy (jeśli instrukcje i pętle for nie tworzą domknięć). Również pętla etykieta / nagłówek mogłaby prawdopodobnie zostać zredukowana do jednej linii:Object.keys(arrData[0]).join(',')
ccnokes
Twoja odpowiedź działa. Ale w przypadkach, gdy jakaś kolumna nie jest dostępna dla jakiegoś wiersza, nie uwzględni brakującej kolumny i nie wyrówna danych kolumny dla danych tego wiersza.
sms
Udało mi się uruchomić tę metodę, ale musiałem edytować część kodu, aby: 1. pracować bez JQuery: document.getElementById("lnkDwnldLnk").download = filename; document.getElementById("lnkDwnldLnk").href = csvUrl;2. pracować w IE11:if (window.navigator && window.navigator.msSaveOrOpenBlob) { window.navigator.msSaveOrOpenBlob(blob, filename); } else { document.getElementById('lnkDwnldLnk').click(); }
Jason
17

Chciałem tylko dodać tutaj kod dla ludzi w przyszłości, ponieważ próbowałem wyeksportować JSON do dokumentu CSV i pobrać go.

Używam $.getJSONdo pobierania danych json z zewnętrznej strony, ale jeśli masz podstawową tablicę, możesz po prostu jej użyć.

Wykorzystuje to kod Christiana Landgrena do tworzenia danych 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);
    });
});

Edycja: Warto to zauważyć JSON.stringify dodanie cudzysłowu pozwoli uniknąć cudzysłowów \". Jeśli przeglądasz plik CSV w programie Excel, nie podoba mu się to jako znak ucieczki.

Można dodać .replace(/\\"/g, '""')do końca JSON.stringify(row[fieldName], replacer), aby wyświetlić ten prawidłowo w programie Excel (ten zastąpi \"z"" których co preferuje Excel).

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

user1274820
źródło
11

Jeśli ktoś chciałby to również pobrać.
Oto niesamowita mała funkcja, która konwertuje tablicę obiektów JSON na csv, a następnie pobiera ją.

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

Następnie nazwij to tak:

this.downloadCSVFromJson(`myCustomName.csv`, this.state.csvArrayOfJson)
waz
źródło
to wydaje się nie działać w przypadku rzeczy, gdy w jednym z elementów występuje pojedynczy cytat, np.Cap D'antibes
MidnightDataGeek
9

Dostępnych jest wiele opcji ponownego wykorzystania istniejących potężnych bibliotek opartych na standardach.

Jeśli zdarzy ci się używać D3 w swoim projekcie, możesz po prostu wywołać:

    d3.csv.formatlub d3.csv.formatRowsfunkcje do konwersji tablicy obiektów na łańcuch csv.

    d3.csv.formatRows daje większą kontrolę nad tym, które właściwości są konwertowane na csv.

    Zobacz d3.csv.format i d3.csv.formatRows strony wiki .

Dostępne są również inne biblioteki, takie jak jquery-csv , PapaParse . Papa Parse nie ma żadnych zależności - nawet jQuery.

W przypadku wtyczek opartych na jquery sprawdź to .

nagu
źródło
1
To działało świetnie dla mnie. Zwróć uwagę, że interfejs API D3 zmienił się od 2017.v3 (obecnie jest to wersja 4): github.com/d3/d3-dsv/blob/v1.2.0/README.md#csvFormat
aljabear
8

Wypróbuj te przykłady

Przykład 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;
}

Przykład 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;
}

Możesz nawet pobrać plik csv za pomocą następującego kodu:

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
źródło
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
źródło
2

Adaptacja odpowiedzi praneybehl do pracy z zagnieżdżonymi obiektami i separatorem tabulatorów

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
źródło
1
Działa to idealnie do kopiowania i wklejania bezpośrednio do Excela / Arkuszy! Dzięki!
UP3
1

Oto sposób na zrobienie tego dla dynamicznie głębokich obiektów w sposób obiektowy dla nowszych wersji js. może być konieczna zmiana typu separatora po regionie.

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
źródło
1

Czasami przedmioty mają różne długości. Więc napotkałem ten sam problem co Kyle Pennell. Ale zamiast sortować tablicę, po prostu przechodzimy przez nią i wybieramy najdłuższą. Złożoność czasowa jest zredukowana do O (n), w porównaniu do O (n log (n)) podczas sortowania.

Zacząłem od kodu z zaktualizowanej wersji ES6 (2016) Christiana Landgrena .

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
źródło
1

Chciałem odrzucić powyższą odpowiedź @Christian Landgren. Nie wiedziałem, dlaczego mój plik CSV ma tylko 3 kolumny / nagłówki. To dlatego, że pierwszy element w moim jsonie miał tylko 3 klucze. Musisz więc uważać na plikconst header = Object.keys(json[0]) linię. Zakłada się, że pierwszy element w tablicy jest reprezentatywny. Miałem niechlujny JSON z niektórymi obiektami mniej więcej.

Więc dodałem array.sortdo tego, który uporządkuje JSON według liczby kluczy. W ten sposób Twój plik CSV będzie miał maksymalną liczbę kolumn.

Jest to również funkcja, której możesz użyć w swoim kodzie. Po prostu podaj 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
źródło
1

Oto moja prosta wersja konwersji tablicy obiektów na CSV (zakładając, że wszystkie te obiekty mają te same atrybuty):

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
źródło
0

Napisz 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
źródło
2
Nie sądzę, żeby to miało dużą wartość. Proszę edit dodać kilka wyjaśnień, w jaki sposób to pomaga odpowiedzieć na pytanie.
fedorqui 'SO przestań szkodzić'
0

Śmieszne, nic tu nie jest kompletne ani nie działa (IE ani node.js). Odpowiedź na podobne pytanie, nieco ustrukturyzowany kod JSON (przypuśćmy, że nie ma potrzeby ponownego kopiowania), zawiera również fragment demo. Konwersja JSON na CSV (JavaScript): Jak poprawnie sformatować konwersję CSV Mam nadzieję, że nie tylko jeden konwerter typu, również na moim Github (wspomniany w profilu) jest podobny do analizy nieznanej struktury JSON. Jestem autorem kodu w tej odpowiedzi i całego kodu na moim Githubie (z wyjątkiem niektórych projektów rozpoczętych jako fork / + translation).

Tomek
źródło
0

Osobiście użyłbym do tego biblioteki d3-dsv . Dlaczego 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);
}

Dzięki potrząsaniu drzewem możesz po prostu zaimportować tę konkretną funkcję z d3-dsvbiblioteki

Anuj
źródło