Konvertere JSON til CSV: slik unngår du de vanligste fellene
Å konvertere JSON til CSV betyr å ta en liste av objekter og gjøre den om til rader og kolonner: hver unike nøkkel i objektene blir en kolonneoverskrift, og hvert objekt blir én rad. Det som skaper mest forvirring i praksis, er ikke selve omgjøringen, men escape-reglene: når skal en verdi pakkes inn i anførselstegn, og hva skjer med anførselstegn som allerede finnes inni verdien selv.
Hvorfor CSV fortsatt er relevant
JSON er formatet API-er og databaser snakker, men CSV er formatet mennesker åpner. Regneark som Excel og Google Sheets forstår CSV ut av boksen, og de fleste dataanalyseverktøy, importrutiner for regnskapssystemer og BI-dashboard tar imot CSV som et av de tryggeste utgangspunktene. Har du en JSON-eksport fra et API og trenger å sende den videre til noen som skal åpne den i et regneark, er CSV som regel raskeste vei dit.
Problemet oppstår når en verdi i JSON-en inneholder tegn som CSV-formatet selv bruker til å skille kolonner og rader, altså komma og linjeskift, eller når en verdi inneholder et anførselstegn. Da må konverteren gjøre noe smart, ellers ryker strukturen.
Et gjennomregnet eksempel
Ta følgende JSON, en liste 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 }
]
Kjørt gjennom konverteren blir resultatet dette:
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
Overskriftsraden (sku,product,price,in_stock) kommer fra unionen av nøklene på tvers av alle objektene, i den rekkefølgen de først dukker opp. Det høres kanskje opplagt ut, men det er ikke alle konvertere som gjør det riktig: noen enklere implementasjoner ser bare på nøklene i det aller første objektet, og hvis objekt nummer to eller tre har et felt de andre ikke har, forsvinner den kolonnen stille og rolig uten varsel. Verktøyet her skanner samtlige objekter i lista før det setter opp overskriftene, så ingen felt går tapt selv om strukturen varierer litt fra rad til rad.
Se så på de tre radene, én etter én:
Rad 1 har verdien Wireless Mouse, Black i product-feltet. Den inneholder et komma, og siden komma er selve skilletegnet CSV bruker mellom kolonner, må verdien pakkes inn i doble anførselstegn for at en CSV-leser skal forstå at kommaet er en del av teksten og ikke et kolonneskille. Derfor blir cellen "Wireless Mouse, Black".
Rad 2 er den mest lærerike. Verdien er 17" Laptop Stand, altså med et bokstavelig anførselstegn for tommer rett etter tallet 17. Regelen (RFC 4180, standarden CSV som regel følger) sier at et anførselstegn inni en verdi skal dobles, " blir til "", og at hele verdien i tillegg skal pakkes inn i et ytre par anførselstegn fordi den nå inneholder et anførselstegn. Resultatet blir "17"" Laptop Stand". Legg merke til at det er to forskjellige ting som skjer samtidig her: dobling av tegnet inni verdien, og innpakking av hele verdien utenpå. Glemmer man den ene eller den andre, får man enten en verdi som ikke lar seg lese riktig tilbake, eller en verdi som ser ut som den er delt i to.
Rad 3, USB-C Cable, har verken komma, anførselstegn eller linjeskift, og går derfor rett gjennom uten noen form for innpakking. Dette er hovedregelen: en verdi kvoteres bare når det faktisk er nødvendig, ikke som standard for alle celler.
Prøv det selv
Lim inn egen JSON under, eller bruk eksempelet over, og se konverteringen skje direkte i nettleseren. Ingenting sendes til noen server, alt skjer lokalt hos deg.
Vanlige feil
Nøstede objekter blir til [object Object]. Har du et felt som address som selv er et objekt, for eksempel { "city": "Oslo", "zip": "0150" }, blir det ikke automatisk splittet i flere kolonner. Objektet stringifiseres, og resultatet i CSV-cellen blir den bokstavelige teksten [object Object], altså fullstendig tap av dataene som lå inni. Løsningen er å flate strukturen ut før du konverterer: gjør address: { city, zip } om til to felt på toppnivå, address_city og address_zip, i hvert objekt. Da får du to lesbare kolonner i stedet for én ubrukelig.
Arrayer flates ut til én kommaseparert celle, ikke egne kolonner. Har et felt en verdi som ["red", "blue"], blir ikke det tre eller to separate kolonner. Arrayen gjøres om til tekst ved å slå sammen elementene med komma og uten klammer, så resultatet blir strengen red,blue. Siden den strengen nå selv inneholder et komma, blir den i sin tur kvotert av escape-regelen, og du ender opp med "red,blue" som én enkelt celle. Det er sjelden det man faktisk ønsker: vil du ha fargene i separate kolonner, må du selv bygge om strukturen til for eksempel color_1 og color_2 før konvertering, eller slå sammen verdiene til én tekststreng med et annet skilletegn enn komma.
Excel og listeskilletegnet. Denne konverteren bruker komma som skilletegn, og det er også CSV-standarden internasjonalt. Men norsk Excel, med komma som desimaltegn i tall, forventer som regel semikolon som listeskilletegn i CSV-filer. Åpner du en komma-separert CSV-fil direkte i norsk Excel, kan hele innholdet lande i én eneste kolonne A i stedet for å bli delt opp riktig. Løsningen er enten å bruke Excels «Data > Tekst til kolonner» og velge komma som skilletegn manuelt etter import, eller å endre listeskilletegnet i Windows’ regionsinnstillinger til komma slik at Excel forventer samme format som filen faktisk bruker.
Et enkeltstående objekt uten klammer rundt. Verktøyet forventer en JSON-array, altså data pakket inn i hakeklammer [ ], selv om du bare har ett objekt å konvertere. Limer du inn { "sku": "A100" } uten de omsluttende klammene, blir det ikke tolket som en liste med ett element, og du får en feilmelding i stedet for en CSV-rad. Riktig format er [{ "sku": "A100" }]. Er ikke input gyldig JSON, eller er den ikke en array i utgangspunktet, viser verktøyet en feilmelding direkte i grensesnittet i stedet for å krasje.
Ofte stilte spørsmål
Hvordan bestemmes kolonneoverskriftene i CSV-filen? Overskriftene er unionen av samtlige nøkler som forekommer i noen av objektene i JSON-arrayen, i den rekkefølgen nøklene først dukker opp. Det holder ikke å bare se på det første objektet: har objekt nummer to eller tre et felt de andre mangler, blir det likevel med som egen kolonne, med tomme celler for de radene som ikke har verdien.
Hva skjer hvis et objekt mangler en verdi som de andre objektene har? Cellen blir stående tom. Det gir ikke en feilmelding og stopper ikke konverteringen, den manglende verdien representeres rett og slett som en tom streng i den raden.
Kan jeg konvertere JSON med nøstede objekter eller arrayer direkte?
Ikke pålitelig. Et nøstet objekt blir til den bokstavelige teksten [object Object] i CSV-cellen, og en array blir flatet til én kommaseparert tekststreng uten klammer. Skal dataene bli lesbare, må du flate ut nøstede objekter til egne toppnivåfelt (for eksempel address_city) før du konverterer, og eventuelt gjøre om arrayer til separate felt hvis du trenger dem i egne kolonner.
Hvorfor viser CSV-filen alt i én kolonne når jeg åpner den i Excel? Dette skjer typisk i norsk Excel, hvor komma brukes som desimaltegn og semikolon derfor er standard listeskilletegn i CSV-import. Filen fra dette verktøyet bruker komma som skilletegn, i tråd med CSV-standarden. Bruk «Data > Tekst til kolonner» i Excel og velg komma som skilletegn for å dele opp innholdet riktig etter import, eller endre listeskilletegnet i de regionale innstillingene på maskinen din.
Sendes dataene mine til en server når jeg bruker konverteren? Nei, konverteringen skjer utelukkende i nettleseren din. JSON-en du limer inn blir aldri sendt noe sted, og det samme gjelder CSV-resultatet.