1

I tried to convert dynamic JSON to CSV, I investigate libs and answers I can't find a remarkable thing.

This and this examples could be helpful but I can't add the JSON's struct to my code, JSON is dynamic.

In Python & JS, I saw these examples;

Python;

# Python program to convert
# JSON file to CSV
 
 
import json
import csv
 
 
# Opening JSON file and loading the data
# into the variable data
with open('data.json') as json_file:
    data = json.load(json_file)
 
employee_data = data['emp_details']
 
# now we will open a file for writing
data_file = open('data_file.csv', 'w')
 
# create the csv writer object
csv_writer = csv.writer(data_file)
 
# Counter variable used for writing
# headers to the CSV file
count = 0
 
for emp in employee_data:
    if count == 0:
 
        # Writing headers of CSV file
        header = emp.keys()
        csv_writer.writerow(header)
        count += 1
 
    # Writing data of CSV file
    csv_writer.writerow(emp.values())
 
data_file.close()

JS;

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])
const csv = [
  header.join(','), // header row first
  ...items.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','))
].join('\r\n')

console.log(csv)

These codes help convert dynamic JSON to CSV easily.

Example input & output;

JSON(input);

[
  {
    "name": "John",
    "age": "21"
  },
  {
    "name": "Noah",
    "age": "23"
  },
  {
    "name": "Justin",
    "age": "25"
  }
]

CSV(output);

"name","age"
"John","21"
"Noah","23"
"Justi","25"

So how can I convert dynamic JSON to CSV in Go?

PS: I discover a Golang lib(json2csv) that helps to convert but only works on command prompt.

I few online tools for example;

https://csvjson.com/json2csv

https://data.page/json/csv

8
  • 1
    json2csv is a library (as you mentioned), not just a command line tool. Commented Aug 10, 2022 at 8:38
  • How does your input look like? Is it a JSON array of dynamic, but identical JSON objects? Or elements may be completely independent? Please be more specific in what you want, provide example input and output at least. Commented Aug 10, 2022 at 9:36
  • I added the example input and output @icza Commented Aug 10, 2022 at 10:03
  • json2csv can do this for you, so what's your question? Commented Aug 10, 2022 at 10:07
  • 1
    For an example check out their cmd main file. But for your simple example I would just implement it by hand and not depend on another library. Commented Aug 10, 2022 at 10:36

2 Answers 2

2

After investigation, I handle it with yukithm/json2csv package.

package main

import (
    "bytes"
    "encoding/json"
    "github.com/yukithm/json2csv"
    "log"
    "os"
)

func main() {
    b := &bytes.Buffer{}
    wr := json2csv.NewCSVWriter(b)
    j, _ := os.ReadFile("your-input-path\\input.json")
    var x []map[string]interface{}

    // unMarshall json
    err := json.Unmarshal(j, &x)
    if err != nil {
        log.Fatal(err)
    }

    // convert json to CSV
    csv, err := json2csv.JSON2CSV(x)
    if err != nil {
        log.Fatal(err)
    }

    // CSV bytes convert & writing...
    err = wr.WriteCSV(csv)
    if err != nil {
        log.Fatal(err)
    }
    wr.Flush()
    got := b.String()

    //Following line prints CSV
    println(got)

    // create file and append if you want
    createFileAppendText("output.csv", got)
}

//
func createFileAppendText(filename string, text string) {
    f, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
    if err != nil {
        panic(err)
    }

    defer f.Close()

    if _, err = f.WriteString(text); err != nil {
        panic(err)
    }
}

input.json;

[
  {
    "Name": "Japan",
    "Capital": "Tokyo",
    "Continent": "Asia"
  },
  {
    "Name": "Germany",
    "Capital": "Berlin",
    "Continent": "Europe"
  },
  {
    "Name": "Turkey",
    "Capital": "Ankara",
    "Continent": "Europe"
  },
  {
    "Name": "Greece",
    "Capital": "Athens",
    "Continent": "Europe"
  },
  {
    "Name": "Israel",
    "Capital": "Jerusalem",
    "Continent": "Asia"
  }
]

output.csv

/Capital,/Continent,/Name
Tokyo,Asia,Japan
Berlin,Europe,Germany
Ankara,Europe,Turkey
Athens,Europe,Greece
Jerusalem,Asia,Israel
Sign up to request clarification or add additional context in comments.

Comments

0

Paste this to https://github.com/yukithm/json2csv/blob/master/cmd/json2csv/main.go and insert the func to main.

func stackoverflow() {

    jsonStr := `
[
  {
    "name": "John",
    "age": "21"
  },
  {
    "name": "Noah",
    "age": "23"
  },
  {
    "name": "Justin",
    "age": "25"
  }
]`

    buff := bytes.NewBufferString(jsonStr)

    data, _ := readJSON(buff)

    results, _ := json2csv.JSON2CSV(data)

    headerStyle := headerStyleTable["jsonpointer"]
    err := printCSV(os.Stdout, results, headerStyle, false)
    if err != nil {
        log.Fatal(err)
    }
}

It works for me.

➜  json2csv git:(master) ✗ go run main.go 
/age,/name
21,John
23,Noah
25,Justin

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.