【Golang】基礎-操作 csv 檔案
阿新 • • 發佈:2020-11-30
1. encoding/csv,自帶極簡
1.1 寫資料到csv檔案
知識點: Write 方法使用[]string
的切片格式追加方式寫入資料
1.1.1 追加寫入
package main import ( "encoding/csv" "fmt" "log" "os" "github.com/spf13/cast" ) type User struct { ID int64 Name string Tel string Addr string } func StructToCsv(filename string, UsersDb []User) { newFile, err := os.Create(filename) if err != nil { fmt.Println(err) } defer func() { newFile.Close() }() // 寫入UTF-8 newFile.WriteString("\xEF\xBB\xBF") // 寫入UTF-8 BOM,防止中文亂碼 // 寫資料到csv檔案 w := csv.NewWriter(newFile) header := []string{"ID", "Name", "Tel", "Addr"} //標題 w.Write(header) for _, v := range UsersDb { context := []string{ cast.ToString(v.ID), v.Name, v.Tel, v.Addr, } // data = append(data, context) w.Write(context) } if err := w.Error(); err != nil { log.Fatalln("error writing csv:", err) } w.Flush() } func main() { Users1 := []User{ {1, "admin", "adminTel", "adminAddr"}, {2, "test", "testTel", "testAddr"}, } StructToCsv("user.csv", Users1) }
1.1.2 一次性寫入
知識點:WriteAll 使用[][] [][]string
格式一次性寫入資料,覆蓋 csv 檔案
package main import ( "encoding/csv" "fmt" "os" "github.com/spf13/cast" ) type User struct { ID int Name string Tel string Addr string } func StructToCsv(filename string, UsersDb []User) { newFile, err := os.Create(filename) if err != nil { fmt.Println(err) } defer func() { newFile.Close() }() // 寫入UTF-8 newFile.WriteString("\xEF\xBB\xBF") // 寫入UTF-8 BOM,防止中文亂碼 // 寫資料到csv檔案 w := csv.NewWriter(newFile) header := []string{"ID", "Name", "Tel", "Addr"} //標題 data := [][]string{ header, } for _, v := range UsersDb { context := []string{ cast.ToString(v.ID), v.Name, v.Tel, v.Addr, } data = append(data, context) } w.WriteAll(data) // WriteAll方法使用Write方法向w寫入多條記錄,並在最後呼叫Flush方法清空快取。 w.Flush() } func main() { Users1 := []User{ {1, "admin", "adminTel", "adminAddr"}, {2, "test", "testTel", "testAddr"}, } StructToCsv("user.csv", Users1) }
1.1.3 執行結果
ID,Name,Tel,Addr
1,admin,adminTel,adminAddr
2,test,testTel,testAddr
1.2 讀取 csv 檔案
1.2.1 Read,逐條讀取為[]string
格式的資料
package main import ( "encoding/csv" "fmt" "io" "log" "os" "github.com/spf13/cast" ) type User struct { ID int Name string Tel string Addr string } var Users []*User func CsvToDb(filename string) { f, err := os.Open(filename) if err != nil { fmt.Println("Error: ", err) } reader := csv.NewReader(f) result1 := make([][]string, 0) result2 := make([][]string, 0) for { record, err := reader.Read() if err == io.EOF { break } if err != nil { log.Fatal(err) } result1 = append(result1, record) } for k, _ := range result1 { if result1[k][1] == "Name" && result1[k][2] == "Tel" && result1[k][3] == "Addr" { result2 = append(result1[:k], result1[k+1:]...) } } for _, v := range result2 { user := &User{ ID: cast.ToInt(v[0]), Name: v[1], Addr: v[2], Tel: v[3], } Users = append(Users, user) } for _, v := range Users { fmt.Println(v) } } func main() { CsvToDb("user.csv") }
1.2.2 ReadAll,一次性讀取為[][]string
格式的資料
package main
import (
"encoding/csv"
"fmt"
"os"
"github.com/spf13/cast"
)
type User struct {
ID int
Name string
Tel string
Addr string
}
var Users []*User
func CsvToDb(filename string) {
f, err := os.Open(filename)
if err != nil {
fmt.Println("Error: ", err)
}
reader := csv.NewReader(f)
// 可以一次性讀完
result, err := reader.ReadAll()
if err != nil {
fmt.Println("Error: ", err)
}
result1 := make([][]string, 0)
for k, _ := range result {
if result[k][1] == "Name" && result[k][2] == "Tel" && result[k][3] == "Addr" {
result1 = append(result[:k], result[k+1:]...)
}
}
for _, v := range result1 {
user := &User{
ID: cast.ToInt(v[0]),
Name: v[1],
Addr: v[2],
Tel: v[3],
}
Users = append(Users, user)
}
for _, v := range Users {
fmt.Println(v)
}
}
func main() {
CsvToDb("user.csv")
}
2. github.com/gocarina/gocsv
簡單案例:
package main
import (
"fmt"
"os"
"github.com/gocarina/gocsv"
)
type Client struct { // Our example struct, you can use "-" to ignore a field
ID string `csv:"ID"`
Name string `csv:"Name"`
Tel string `csv:"Tel"`
Addr string `csv:"-"`
}
// type Client struct { // Our example struct, you can use "-" to ignore a field
// ID string "ID"
// Name string "Name"
// Tel string "Tel"
// Addr string "-"
// }
func main() {
clientsFile, err := os.OpenFile("user.csv", os.O_RDWR|os.O_CREATE, os.ModePerm)
if err != nil {
panic(err)
}
defer clientsFile.Close()
clients := []*Client{}
if err := gocsv.UnmarshalFile(clientsFile, &clients); err != nil { // Load clients from file
panic(err)
}
for _, client := range clients {
fmt.Println("Hello", client.Name)
}
if _, err := clientsFile.Seek(0, 0); err != nil { // Go to the start of the file
panic(err)
}
clients = append(clients, &Client{ID: "12", Name: "John", Tel: "21"}) // Add clients
clients = append(clients, &Client{ID: "13", Name: "Fred"})
clients = append(clients, &Client{ID: "14", Name: "James", Tel: "32"})
clients = append(clients, &Client{ID: "15", Name: "Danny"})
csvContent, err := gocsv.MarshalString(&clients) // Get all clients as CSV string
//err = gocsv.MarshalFile(&clients, clientsFile) // Use this to save the CSV back to the file
if err != nil {
panic(err)
}
fmt.Println(csvContent) // Display all clients as CSV string
}
執行結果:
~/Documents/projects/scripts/go/eg cat user.csv
ID,Name,Tel,Addr
1,admin,adminTel,adminAddr
2,test,testTel,testAddr
~/Documents/projects/scripts/go/eg go run 2.go
Hello admin
Hello test
ID,Name,Tel
,admin,adminTel
,test,testTel
12,John,21
13,Fred,
14,James,32
15,Danny,