Skip to content

Instantly share code, notes, and snippets.

@HirbodBehnam
Created June 10, 2021 08:54
Show Gist options
  • Select an option

  • Save HirbodBehnam/a75de80fb91c6fb4b9ab19696a56379f to your computer and use it in GitHub Desktop.

Select an option

Save HirbodBehnam/a75de80fb91c6fb4b9ab19696a56379f to your computer and use it in GitHub Desktop.
A function to convert an array into csv file in go.
package util
import (
"encoding/csv"
"fmt"
"io"
"reflect"
)
// StreamCsv converts an array of an struct to csv
// The headers of struct is found using reflection and json tag in the struct
// Will panic if data is not slice
// Behaviour is undefined if elements of slice have different types
func StreamCsv(w io.Writer, data interface{}) error {
// At first ensure that the data is a slice
if reflect.TypeOf(data).Kind() != reflect.Slice {
panic("data is not an slice")
}
// If the length is zero, do nothing
dataValue := reflect.ValueOf(data)
if dataValue.Len() == 0 {
return nil
}
// Start the writer...
writer := csv.NewWriter(w)
defer writer.Flush()
var err error
// At first get the headers
var indexes []int
{
first := dataValue.Index(0).Type()
headersCount := first.NumField()
header := make([]string, 0, headersCount)
indexes = make([]int, 0, headersCount)
for i := 0; i < headersCount; i++ {
if tag, exists := first.Field(i).Tag.Lookup("csv"); exists {
header = append(header, tag)
indexes = append(indexes, i)
}
}
err = writer.Write(header)
if err != nil {
return err
}
}
// Now write all data in the array
row := make([]string, len(indexes))
for i := 0; i < dataValue.Len(); i++ {
now := dataValue.Index(i)
for j, index := range indexes {
row[j] = fmt.Sprintf("%v", now.Field(index))
}
err = writer.Write(row)
if err != nil {
return err
}
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment