Utvecklare

Konvertera JSON till CSV: regeln för escaping som avgör allt

7 min läsning

Att konvertera JSON till CSV innebär att göra om en array av objekt till en tabell med rader och kolumner. Det låter enkelt, och för raka värden är det också det. Det som faktiskt avgör om resultatet blir användbart är hur konverteraren hanterar tre saker: kolumner som skiljer sig mellan objekten, värden som innehåller kommatecken eller citattecken, och nästlade objekt eller arrayer. Missar man den tredje punkten tappar man data utan ett enda felmeddelande.

Varför CSV fortfarande används

JSON är det naturliga formatet för API:er och applikationskod, men så fort data ska in i ett kalkylblad, en analytikers verktyg eller ett dataflöde som förväntar sig rader och kolumner, är CSV fortfarande standarden. Excel, Google Kalkylark, de flesta BI-verktyg och en stor del av import/export-funktionerna i affärssystem läser CSV som ett förstahandsval. Att gå från en JSON-array till en CSV-fil är därför ett av de vanligaste stegen mellan “data från ett API” och “data någon kan öppna och filtrera direkt”.

Ett verkligt exempel, rad för rad

Ta den här JSON-arrayen med tre produkter:

[
  { "sku": "A100", "product": "Wireless Mouse, Black", "price": 19.99, "in_stock": true },
  { "sku": "A101", "product": "17\" Laptop Stand", "price": 42.5, "in_stock": false },
  { "sku": "A102", "product": "USB-C Cable", "price": 8.99, "in_stock": true }
]

Konverterad till CSV blir resultatet:

sku,product,price,in_stock
A100,"Wireless Mouse, Black",19.99,true
A101,"17"" Laptop Stand",42.5,false
A102,USB-C Cable,8.99,true

Kolumnrubrikerna hämtas från unionen av alla nycklar som förekommer i arrayen, i den ordning de först dyker upp: sku, product, price, in_stock. Här har alla tre objekten samma nycklar, så det är inte synligt än, men det är avgörande så fort objekten skiljer sig åt (se nästa avsnitt).

Titta nu på hur varje rad escapas, eftersom det är här de flesta konverterare, och en hel del handskrivna skript, går fel:

Rad 1 har värdet Wireless Mouse, Black, som innehåller ett kommatecken. Ett kommatecken mitt i ett värde skulle annars tolkas som en ny kolumn, så värdet omsluts med citattecken: "Wireless Mouse, Black".

Rad 2 har värdet 17" Laptop Stand, som innehåller ett bokstavligt citattecken (tumindikatorn för tum). Enligt RFC 4180-regeln för CSV-escaping dubbleras varje citattecken inuti värdet (" blir ""), och hela värdet omsluts dessutom av ett yttre par citattecken. Resultatet blir "17"" Laptop Stand". De två citattecknen i mitten är alltså det escapade originaltecknet, inte ett fel i exemplet.

Rad 3 har värdet USB-C Cable, som varken innehåller kommatecken, citattecken eller radbrytning. Det passerar oescapat.

Samma logik gäller radbrytningar inuti ett värde: förekommer en, omsluts hela värdet med citattecken precis som med ett kommatecken.

Saknade nycklar: unionen av kolumner, inte bara den första radens

En vanlig bugg i enkla konverterare är att bara läsa nycklarna från det första objektet i arrayen och strunta i resten. Det fungerar tills ett senare objekt har ett fält de tidigare saknar, och då försvinner det fältet helt ur resultatet utan varning.

Ett korrekt beteende är att samla in unionen av samtliga nycklar från alla objekt, i den ordning de först förekommer, och sedan lämna cellen tom för de objekt som saknar en given nyckel. Ett exempel:

[
  { "name": "Anna", "city": "Malmö" },
  { "name": "Erik", "city": "Umeå", "phone": "070-1234567" }
]

Här introducerar det andra objektet nyckeln phone, som det första saknar. Rätt resultat blir:

name,city,phone
Anna,Malmö,
Erik,Umeå,070-1234567

Kolumnen phone finns med för båda raderna, och cellen för Anna lämnas tom istället för att kolumnen tappas bort eller att raderna hamnar fel i förhållande till varandra.

Prova själv

Klistra in din egen JSON-array nedan för att se CSV-resultatet direkt i webbläsaren. Inget skickas till någon server, allt körs lokalt i sidan. Länken i verktyget uppdateras normalt automatiskt när du delar den, men inte i den här inbäddade varianten på en artikelsida.

CSV → JSON JSON → CSV
JSON till CSV-omvandlare
Gratis, ingen registrering, fungerar på alla enheter.
Öppna hela verktyget

Vanliga misstag

Nästlade objekt blir [object Object]. Om ett värde i JSON-objektet självt är ett objekt, till exempel "address": { "city": "Örebro", "zip": "70210" }, stringifieras det till den bokstavliga texten [object Object] i CSV-cellen. Det är inte en krasch, bara tyst dataförlust, vilket gör det extra lätt att missa. Lösningen är att platta ut strukturen innan konverteringen: gör om address: {city, zip} till två egna toppnivånycklar, address_city och address_zip, så hamnar båda värdena i egna, läsbara kolumner.

Arrayer blir en enda kommaseparerad cell, inte flera kolumner. Ett värde som "colors": ["red", "blue"] stringifieras genom att elementen slås ihop med kommatecken och utan hakparenteser, så resultatet blir strängen red,blue. Eftersom den strängen i sin tur innehåller ett kommatecken fångas den upp av escape-regeln och skrivs ut som "red,blue" i en enda cell, inte som två separata kolumner. Vill man ha en kolumn per färg måste man själv platta ut arrayen till egna fält innan konverteringen.

Excel-fällan med listavgränsare. Utdatan från verktyget använder alltid kommatecken som kolumnavgränsare, det finns inget alternativ för semikolon. I svenska Excel-installationer är kommatecken normalt satt som decimaltecken, vilket gör att Excel förväntar sig semikolon som listavgränsare i CSV-filer. Öppnar man en kommaseparerad CSV direkt i svenska Excel hamnar därför ofta hela raden i en enda cell, kolumn A, istället för att delas upp. Lösningen är antingen att importera via “Data > Text till kolumner” och där välja komma som avgränsare, eller att ändra listavgränsaren i Windows regioninställningar från semikolon till komma.

Glömma hakparenteserna runt ett enskilt objekt. Verktyget förväntar sig en JSON-array av objekt, [{...}, {...}], inte ett enda objekt för sig, {...}. Har man bara en rad att konvertera måste den ändå omslutas av hakparenteser, [{ "sku": "A100", "product": "Mouse" }], annars visas ett felmeddelande istället för en CSV-fil. Ogiltig JSON ger samma sak: ett tydligt felmeddelande i stället för en krasch.

Vanliga frågor

Vilka kolumner får CSV-filen om objekten i arrayen har olika fält? Kolumnerna blir unionen av samtliga nycklar som förekommer i hela arrayen, i den ordning de först dyker upp, inte bara nycklarna från det första objektet. Ett objekt som saknar ett visst fält får en tom cell i den kolumnen istället för att kolumnen tas bort eller raderna hamnar fel.

Vad händer med ett värde som innehåller ett kommatecken eller citattecken? Det omsluts automatiskt med citattecken enligt RFC 4180. Innehåller värdet dessutom ett bokstavligt citattecken dubbleras det tecknet (" blir "") innan hela värdet omsluts av det yttre citattecknsparet, till exempel blir 17" Laptop Stand till "17"" Laptop Stand".

Varför blev ett fält i min CSV bara [object Object]? För att det ursprungliga JSON-värdet var ett nästlat objekt, inte ett enkelt värde som text eller tal. Konverteraren stringifierar nästlade objekt rakt av, vilket ger just den texten och tappar den underliggande datan. Platta ut strukturen till egna toppnivånycklar (till exempel address_city istället för address.city) innan du konverterar.

Kan jag få CSV med semikolon istället för kommatecken? Nej, verktyget använder alltid kommatecken som avgränsare. Om filen ska öppnas i en svensk Excel-installation, som normalt förväntar sig semikolon som listavgränsare, importera filen via “Data > Text till kolumner” och välj komma som avgränsare där, eller byt listavgränsare i systemets regioninställningar.

Måste JSON-datan vara en array, även om jag bara har ett objekt? Ja. Verktyget kräver en array av objekt, [{...}], även när det bara handlar om en enda rad. Skickar man in ett bart objekt utan de omslutande hakparenteserna visas ett felmeddelande istället för en konverterad fil.

JSON till CSV-omvandlare
Prova det nu själv med hela verktyget.
Prova nu
Relaterade verktyg