CSV Files

CSV Files are a handy way to pass data around. A lot of programs can import/export CSV file for you to easily edit in excel and save some time. Sometimes you want to parse through and maybe generate CSV files to use as well. Let’s read a CSV file in golang.

Open a CSV file

fi, err := os.Open("path-to-csv.csv")
if err != nil {
    log.Fatal(err)
}
defer fi.Close()

Initialize our reader

rdr := csv.NewReader(fi)

Once we set up our reader, when we want the next row, we call row, err := csv.Read()

row is a slice of strings and each index is a column.

Optionally skip the header row

_, err := rdr.Read()
if err != nil {
    // if we encounter EOF, then there's no point in going further
    if err == io.EOF {
        log.Fatal("Error parsing csv file: Not enough content")
    }
    log.Fatalf("Error parsing csv file: %s", err)
}

Loop over the rows and do our work

for {
    row, err := rdr.Read()
    if err != nil {
        if err != io.EOF { // real error
            log.Fatalf("Error parsing CSV file: %s", err)
        }
        break // reached the end. break the for loop
    }

    // do something with the row
    fmt.Println(row)
}

Full Code

package main

import (
    "encoding/csv"
    "fmt"
    "log"
)

func main() {
    fi, err := os.Open("path-to-csv.csv")
    if err != nil {
        log.Fatal(err)
    }
    defer fi.Close()
    rdr := csv.NewReader(fi)

    _, err := rdr.Read()
    if err != nil {
        // if we encounter EOF, then there's no point in going further
        if err == io.EOF {
            log.Fatal("Error parsing csv file: Not enough content")
        }
        log.Fatalf("Error parsing csv file: %s", err)
    }

    for {
        row, err := rdr.Read()
        if err != nil {
            if err != io.EOF { // real error
                log.Fatalf("Error parsing CSV file: %s", err)
            }
            break // reached the end. break the for loop
        }

        // do something with the row
        fmt.Println(row)
    }
}

Photo by Markus Spiske on Unsplash