警告
本文最后更新于 2020-11-25,文中内容可能已过时。
1.1 写数据到csv文件
知识点: Write 方法使用[]string
的切片格式追加方式写入数据
1.1.1 追加写入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
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 文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
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 执行结果
1
2
3
|
ID,Name,Tel,Addr
1,admin,adminTel,adminAddr
2,test,testTel,testAddr
|
1.2 读取 csv 文件
1.2.1 Read,逐条读取为[]string
格式的数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
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
格式的数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
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")
}
|
简单案例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
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
}
|
执行结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
~/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,
|