I want to quote all fields in a CSV document. Is there a way to modify golang's csv module without having to copy all the code? In another language, I'd simply inherit from csv.Writer and override fieldNeedsQuotes
, but that is not possible in Go, or is it?
Matt and Volker already said that you can copy the module and modify it.
You can use a Writer wrapper as well, but I think it's a bit more complex. See my attempt as a proof of concept (not to be used*).
type quoteWriter struct {
w io.Writer
}
func (w quoteWriter) Write(p []byte) (n int, err error) {
q := make([]byte, 0)
quoted := true
quoted = (p[0] == '"')
if !quoted {
//begin field quote
q = append(q, '"')
}
for i, v := range p {
//We check the "quotation" status for new field or line
//This is a simplification
if v == ',' || v == '
' {
if !quoted { //end field quote
q = append(q, '"')
}
//copy current byte
q = append(q, v)
//is next byte quote?
if len(p) > i+1 {
quoted = (p[i+1] == '"')
}
if !quoted { //begin field quote
q = append(q, '"')
}
} else {
q = append(q, v)
}
}
return w.w.Write(q)
}
See below the example coming from the csv#Writer test (http://golang.org/src/pkg/encoding/csv/writer_test.go) with the proof of concept applied:
http://play.golang.org/p/wovYUkt6Vq
not to be used* Please, notice that I haven't checked all cases, for instance, if a comma is within a quoted text or not, so you would need to check and adapt it. I also recommend to copy and modify the csv package.
I see, it's an old question. But I recently faced the same problem, and created a small library altcsv
, by extending the Golang's encoding/csv
.
If someone else is wondering about the same, you can use the below library: https://github.com/tushar2708/altcsv
It's backward compatible with existing CSV library. I plan to add more python-like CSV interface to the same in future.
Reading from a CSV file:
fileRdr, _ = os.Open("/tmp/custom_csv_file.txt")
csvRdr := altcsv.NewReader(fileRdr)
content := csvReader.ReadAll()
Writing to a CSV file:
headers = []string{"hero_name", "alter_ego", "identity"}
fileWtr, _ := os.Create("/tmp/all_quotes_csv_file.txt")
csvWtr := altcsv.NewWriter(csvH)
csvWtr.AllQuotes = true // surround each field with '"'
csvWtr.Write(headers)
csvWtr.Write([]string{"Spider-Man", "Peter Parker", "Secret Identity"})
csvWtr.Write([]string{"Captain America", "Steven Rogers", "Public Identity"})
csvWtr.Write([]string{"Thor", "Thor Odinson", "No dual Identity"})
csvWtr.Flush()
fileWtr.Close()