In order to write to a CSV file, you need to create the file and then create a Writer
.
type Bread struct {
Name string
Location string
}
var breads = []*Bread{
{Name: "mantou", Location: "China"},
{Name: "baguette", Location: "France"},
{Name: "cottage loaf", Location: "England"},
{Name: "pan", Location: "Spain"},
{Name: "tortilla", Location: "Mexico"},
{Name: "injera", Location: "Africa"},
{Name: "corn bread", Location: "America"},
}
func main() {
csvFile, err := os.Create("breads.csv")
if err != nil {
panic(err)
}
defer csvFile.Close()
writer := csv.NewWriter(csvFile)
header := []string{"bread", "location"}
if err = writer.Write(header); err != nil {
panic(err)
}
for _, bread := range breads {
line := []string{bread.Name, bread.Location}
if err := writer.Write(line); err != nil {
panic(err)
}
}
writer.Flush()
}
Notice that you have to Flush
the writer to write to the file. When you call Write
on the writer, it adds the content to an internal buffer, which is added to the file when you call Flush
.
The Go source code for the Writer
struct and the NewWriter
method look like:
// A Writer writes records to a CSV encoded file.
//
// As returned by NewWriter, a Writer writes records terminated by a
// newline and uses ',' as the field delimiter. The exported fields can be
// changed to customize the details before the first call to Write or WriteAll.
//
// Comma is the field delimiter.
//
// If UseCRLF is true, the Writer ends each record with \r\n instead of \n.
type Writer struct {
Comma rune // Field delimiter (set to ',' by NewWriter)
UseCRLF bool // True to use \r\n as the line terminator
w *bufio.Writer
}
// NewWriter returns a new Writer that writes to w.
func NewWriter(w io.Writer) *Writer {
return &Writer{
Comma: ',',
w: bufio.NewWriter(w),
}
}
And the Write
method on the writer has this signature:
func (w *Writer) Write(record []string) error
So, it expects an array of strings.
To export a tab delimited file, you just need to update the Comma
value of the csv.Writer
struct.
writer := csv.NewWriter(csvFile)
writer.Comma = '\t'
Say we have a breads.csv
file:
bread,location
mantou,China
baguette,France
cottage loaf,England
pan,Spain
tortilla,Mexico
injera,Africa
corn bread,America
We can load the file and work with the rows (records) of data:
func main() {
file, err := os.Open("breads.csv")
if err != nil {
panic(err)
}
defer file.Close()
reader := csv.NewReader(file)
records, err := reader.ReadAll()
if err != nil {
panic(err)
}
for i, record := range records {
if i == 0 { // skip header line
continue
}
fmt.Printf("Bread: %s, Location: %s\n", record[0], record[1])
}
}
The Go source code for the Reader
struct and the NewReader
function, look like this:
// A Reader reads records from a CSV-encoded file.
//
// As returned by NewReader, a Reader expects input conforming to RFC 4180.
// The exported fields can be changed to customize the details before the
// first call to Read or ReadAll.
//
// Comma is the field delimiter. It defaults to ','.
//
// Comment, if not 0, is the comment character. Lines beginning with the
// Comment character are ignored.
//
// If FieldsPerRecord is positive, Read requires each record to
// have the given number of fields. If FieldsPerRecord is 0, Read sets it to
// the number of fields in the first record, so that future records must
// have the same field count. If FieldsPerRecord is negative, no check is
// made and records may have a variable number of fields.
//
// If LazyQuotes is true, a quote may appear in an unquoted field and a
// non-doubled quote may appear in a quoted field.
//
// If TrimLeadingSpace is true, leading white space in a field is ignored.
type Reader struct {
Comma rune // field delimiter (set to ',' by NewReader)
Comment rune // comment character for start of line
FieldsPerRecord int // number of expected fields per record
LazyQuotes bool // allow lazy quotes
TrailingComma bool // ignored; here for backwards compatibility
TrimLeadingSpace bool // trim leading space
line int
column int
r *bufio.Reader
field bytes.Buffer
}
// NewReader returns a new Reader that reads from r.
func NewReader(r io.Reader) *Reader {
return &Reader{
Comma: ',',
r: bufio.NewReader(r),
}
}