To convert JSON data to a CSV file in Go, you need to create a new struct for JSON data, then decode the JSON file into an array of these structs, and finally save the data from this array as subsequent rows of the CSV file. The two main packages necessary to do this are encoding/json
to decode the JSON data with the json.Decoder
and encoding/csv
to write the output CSV data using csv.Writer
.
See also our examples of how to convert CSV to JSON and how to read CSV file or how to write data to a CSV file in Go.
In the example below, we use the data.json
file:
[
{
"vegetable": "carrot",
"fruit": "banana",
"rank": 1
},
{
"vegetable": "potato",
"fruit": "strawberry",
"rank": 2
}
]
Code
|
|
The contents of the output data.csv
file:
vegetable,fruit,rank
carrot,banana,1
potato,strawberry,2
How it works
- Create a new struct for storing read JSON objects
11 12 13 14 15 16
type FruitAndVegetableRank struct { // 1. Create a new struct for storing read JSON objects Vegetable string `json:"vegetable"` Fruit string `json:"fruit"` Rank int64 `json:"rank"` }
The first step of JSON to CSV conversion is to load the JSON data to a Go struct. So, we define a proper type, with the fields matching the data in the file and annotate them with JSON struct field tags to enable JSON decoding into that struct.
- Read the JSON file into the struct array
19 20 21 22 23 24 25 26 27 28 29 30
// 2. Read the JSON file into the struct array sourceFile, err := os.Open(source) if err != nil { return err } // remember to close the file at the end of the function defer sourceFile.Close() var ranking []FruitAndVegetableRank if err := json.NewDecoder(sourceFile).Decode(&ranking); err != nil { return err }
We can start processing our JSON file. We open it (remember to close the file to release resources back to the system, for example, using
defer
keyword) and then create a newjson.Decoder
with this file as an argument. Sincejson.NewDecoder(r io.Reader)
requiresio.Reader
, we do not need to read the content of the file beforehand. If we were to use thejson.Unmarshal()
function, it would be necessary. WithDecode()
method, we read the JSON file and convert it to the slice ofFruitAndVegetableRank
objects. - Create a new file to store CSV data
32 33 34 35 36 37
// 3. Create a new file to store CSV data outputFile, err := os.Create(destination) if err != nil { return err } defer outputFile.Close()
The CSV data will be saved to a file, so in this step, we create a new
destination
file in a pretty standard way. - Write the header of the CSV file and the successive rows by iterating through the JSON struct array
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
// 4. Write the header of the CSV file and the successive rows by iterating through the JSON struct array writer := csv.NewWriter(outputFile) defer writer.Flush() header := []string{"vegetable", "fruit", "rank"} if err := writer.Write(header); err != nil { return err } for _, r := range ranking { var csvRow []string csvRow = append(csvRow, r.Vegetable, r.Fruit, fmt.Sprint(r.Rank)) if err := writer.Write(csvRow); err != nil { return err } }
As the last step, we create a new
csv.Writer
that writes the data in CSV format to the output file. Remember to callwriter.Flush
to ensure that all the buffered content is written before the function finishes. The writing process consists of iterating through the array ofFruitAndVegetableRank
objects and making a CSV row for each of them. Then, This row is saved usingwriter.Write()
method. In the example, we also wrote the header row as the first line of the file.