Skip to content

Instantly share code, notes, and snippets.

@davidvthecoder
Created October 9, 2013 18:32
Show Gist options
  • Save davidvthecoder/6905911 to your computer and use it in GitHub Desktop.
Save davidvthecoder/6905911 to your computer and use it in GitHub Desktop.
Golang CSV Writer Example for a Web Application - Warning No error handling, just the basic concept.
import (
"../../web"
"bytes"
"encoding/csv"
}
func GenerateCSV(ctx *web.Context, args ...string) {
record := []string{"test1", "test2", "test3"} // just some test data to use for the wr.Writer() method below.
b := &bytes.Buffer{} // creates IO Writer
wr := csv.NewWriter(b) // creates a csv writer that uses the io buffer.
for i := 0; i < 100; i++ { // make a loop for 100 rows just for testing purposes
wr.Write(record) // converts array of string to comma seperated values for 1 row.
}
wr.Flush() // writes the csv writer data to the buffered data io writer(b(bytes.buffer))
ctx.ResponseWriter.Header().Set("Content-Type", "text/csv") // setting the content type header to text/csv
ctx.ResponseWriter.Header().Set("Content-Type", "text/csv")
ctx.ResponseWriter.Header().Set("Content-Disposition", "attachment;filename=TheCSVFileName.csv")
ctx.ResponseWriter.Write(b.Bytes())
}
@pvazquezdiaz
Copy link

Hello.
I am new in golang and I'm trying to export CSV data to a file from a web app and found your code, I still have to try to implement it, but I'm wondering where is the "../../web" library that you import???

@RoanBrand
Copy link

RoanBrand commented Apr 4, 2018

Ignore the web package and ctx object used and use the standard w http.ResponseWriter, r *http.Request parameters in your http handlers.

Better way (Allocates no memory for a buffer):

w.Header().Set("Content-Type", "text/csv")
w.Header().Set("Content-Disposition", "attachment;filename=TheCSVFileName.csv")
wr := csv.NewWriter(w)
err := wr.Write(record)
if err != nil {
    http.Error(w, "Error sending csv: "+err.Error(), http.StatusInternalServerError)
    return
}

@K4N0
Copy link

K4N0 commented Oct 13, 2018

How do i use this with a Query pull?
func query(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed)
return
}
rows, err := db.Query("SELECT rma_id, order_id, customer_id, bin_id, owner, asin, lpn, warehouse_id FROM crt.returns_in_inv WHERE warehouse_id = 'PHX7' limit 100;")
if err != nil {
http.Error(w, http.StatusText(500), 500)
return
}
defer rows.Close()

bks := make([]Book, 0)
for rows.Next() {
	bk := Book{}
	err := rows.Scan(&bk.Rma_id, &bk.Order_id, &bk.Customer_id, &bk.Bin_id, &bk.Owner, &bk.Asin, &bk.Lpn, &bk.Warehouse_id) // order matters
	if err != nil {
		http.Error(w, http.StatusText(500), 500)
		return
	}
	bks = append(bks, bk)
}
if err = rows.Err(); err != nil {
	http.Error(w, http.StatusText(500), 500)
	return
}

tpl.ExecuteTemplate(w, "query.gohtml", bks)

}

@rishabh-discovery
Copy link

Very Helpful article. Just to point out, ctx.ResponseWriter.Header().Set("Content-Type", "text/csv") , this has been repeated twice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment