Skip to content

Instantly share code, notes, and snippets.

@developer-kikikaikai
Created October 25, 2020 10:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save developer-kikikaikai/900ea4c5d2e95037b00779f8de6477fb to your computer and use it in GitHub Desktop.
Save developer-kikikaikai/900ea4c5d2e95037b00779f8de6477fb to your computer and use it in GitHub Desktop.
Add double quotation for golang csv encoding
package main
import (
"fmt"
"bytes"
"encoding/csv"
"strings"
"github.com/gocarina/gocsv"
)
type Client struct { // Our example struct, you can use "-" to ignore a field
Id string `csv:"client_id"`
Name string `csv:"client_name"`
Age string `csv:"client_age"`
NotUsed string `csv:"-"`
}
//base data
func basedata() []*Client {
clients := []*Client{}
clients = append(clients, &Client{Id: "12", Name: "John", Age: "21"}) // Add clients
clients = append(clients, &Client{Id: "13", Name: "Fred"})
clients = append(clients, &Client{Id: "14", Name: "James", Age: "32"})
clients = append(clients, &Client{Id: "15", Name: "Danny"})
return clients
}
//add double quotation
func convert(b *bytes.Buffer) ([]byte, error) {
//retry to decode, to check ""
reader := csv.NewReader(b)
reader.LazyQuotes = true
lines, err := reader.ReadAll()
if err != nil {
return []byte{}, err
}
//rewrite to add "", escape \"
bytes := make([]byte, 0, len(b.Bytes())*2)
//If you update writer by SetCSVWriter, please change the delimiter which you use
delimiter := ','
//If you update writer by SetCSVWriter, please change the crlf which you use
for _, line := range lines {
for i, part := range line {
if i != 0 {
bytes = append(bytes, byte(delimiter))
}
bytes = append(bytes, []byte(escape(part))...)
}
bytes = append(bytes, byte('\r'))
}
return bytes, nil
}
func escape(part string) string {
//"XXX" => XXX
escapeStr := strings.Replace(part, "\"", "\"\"", -1)
return "\"" + escapeStr + "\""
}
func main() {
clients := basedata()
out := bytes.Buffer{}
err := gocsv.Marshal(&clients, &out) // Get all clients as CSV string
if err != nil {
panic(err)
}
csvContent, _ := convert(&out)
fmt.Println(string(csvContent)) // Display all clients as CSV string
}
@developer-kikikaikai
Copy link
Author

@developer-kikikaikai
Copy link
Author

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