工作中,使用到CSV文件的场景还是比较多的,比如:
- 脚本使用:有一份名单之类的数据,需要对其进行某种操作,如发现需要对某十个用户补发站内信,此时可能就需要提供一份
CSV
表格文件,每行就是需要补发的信息,如用户名,用户ID
,站内信内容等。读取CSV
文件后,进行站内信的下发。 - 文件下载:如在某个界面上,用户查看到的数据,想要下载下来,此时我们会将数据作为
CSV
文件存入文件存储系统,而后返回下载链接,让用户可以下载。
不管怎么样,我们需要知道最基本的CSV
文件的写入与读取操作。
代码如下
package main
import (
"encoding/csv"
"fmt"
"os"
"strings"
)
func CreateCsv() {
//创建文件
f, err := os.Create("test.csv")
if err != nil {
fmt.Println(err)
}
defer f.Close()
// 写入UTF-8 BOM(byte order mark / 字节顺序标记)
f.WriteString("\xEF\xBB\xBF")
//创建一个新的写入文件流
w := csv.NewWriter(f)
//这个二维数组,外层几个元素就代表几行,内层几个元素就代表几列
data := [][]string{
{"序号", "姓名", "年龄"}, //三列
{"1", "刘备", "23"},
{"2", "张飞", "23"},
{"3", "关羽", "23"},
{"4", "赵云", "23"},
{"5", "黄忠", "23"},
{"6", "马超", "23"},
} //6行
//写入数据
w.WriteAll(data)
w.Flush()
}
func ReadCsv(filePath string) {
byteContent, err := os.ReadFile(filePath)
if err != nil {
panic(err)
}
csvR := csv.NewReader(strings.NewReader(string(byteContent)))
records, err := csvR.ReadAll()
if err != nil {
panic(err)
}
fmt.Println(len(records[0][0])) // "\xEF\xBB\xBF" 3字节 + 序号 6字节 = 9字节
// 针对大文件,一行一行的读取文件
for i, record := range records {
if i == 0 {
continue // 跳过表头
}
fmt.Println(record)
}
}
func main() {
CreateCsv()
ReadCsv("test.csv")
}
运行后会在项目路径下产生test.csv
文件
控制台打印输出的结果如下:
注意点:
- 创建文件后,我们首先使用了
f.WriteString("\xEF\xBB\xBF")
向文件中写入了三个字节,它是一个utf8
的BOM
,也即byte order mark / 字节顺序标记
- 因为
BOM
的存在,所以打印表头第一列时,是9
个字节,"\xEF\xBB\xBF" 3字节 + 序号 6字节 = 9字节
- 写完后需要调用
Flush
方法保证最后的内容也写入到了文件中 - 读取时,一般表头我们是不需要的,所以过滤掉,然后就是读取二维
string
数组取出数据即可,每个元素都是字符串,可以根据需要使用strconv
包的ParseXXX
方法解析为期望的数据类型。