csv.writer是go写csv唯一推荐方式,需显式flush、写bom防excel乱码、自动处理特殊字符,禁用字符串拼接;大文件应调大缓冲并分批flush。

用 csv.Writer 写 CSV 文件最稳妥
Go 标准库的 csv.Writer 是写 CSV 的唯一推荐方式,别自己拼字符串或用 fmt.Fprintf —— 遇到含逗号、换行、双引号的字段会直接崩,而且不兼容 RFC 4180。
实操要点:
-
csv.Writer默认不自动 flush,写完必须显式调用w.Flush(),否则最后一行可能丢数据 - 写入前建议先调用
w.Write([]string{"header1", "header2"})写表头,但注意:它不校验列数是否对齐后续数据行 - 每行数据必须是
[]string,不能传int或struct,得自己转成字符串(比如用strconv.Itoa) - 如果文件要被 Excel 打开,记得在开头写 UTF-8 BOM:
file.Write([]byte("uFEFF"))
处理含特殊字符的字段(换行、双引号、逗号)
csv.Writer 会自动加双引号并转义,但前提是字段里有 "、
或 , —— 它不会无脑包一层,所以别手动加引号,否则变成 """value"""。
常见错误现象:Excel 里某行突然错位、空行、或显示 #N/A —— 很可能是某字段含未转义的
,而你没走 csv.Writer 流程。
示例对比:
bad := "name,age
Alice,25" // ❌ 直接写字符串,CSV 解析器会认为这是两行
good := []string{"name", "age"}; w.Write(good) // ✅ 让 Writer 自己处理格式
写大文件时内存和性能怎么控
标准 csv.Writer 底层用 bufio.Writer 缓冲,默认缓冲区 4KB,对小文件够用;但写百万行时,频繁 flush 会拖慢速度,盲目加大缓冲又可能 OOM。
建议做法:
- 创建 writer 时传自定义
bufio.Writer,比如bufio.NewWriterSize(file, 1(64KB 缓冲) - 每写 1000 行主动
w.Flush()一次,避免 panic: "write buffer full"(尤其磁盘满或网络文件系统场景) - 别用
strings.Builder先攒所有内容再写 —— 内存占用线性增长,100 万行字符串轻松吃掉几百 MB - 如果字段来自数据库,别把整张表
rows.Scan到内存再循环写,应边查边写
中文乱码、Excel 打不开怎么办
Go 源文件和字符串默认 UTF-8,但 Windows 上 Excel 默认用 GBK 打开 CSV —— 这不是 Go 的问题,是 Excel 的老毛病。
解决路径只有两条:
- 强制让 Excel 识别为 UTF-8:写文件前加 BOM ——
file.Write([]byte("uFEFF")),然后写数据。这是最简单有效的方案 - 不加 BOM 但改用
UTF-8 with BOM编码保存(某些编辑器可设),但 Go 写文件时无法控制“带 BOM 的 UTF-8”这种编码名,只能靠字节头 - 别尝试写 GBK —— Go 标准库不支持,第三方库如
golang.org/x/text/encoding会增加依赖且易出错
另一个坑:Windows 路径里的反斜杠 如果硬编码进文件名,比如 "C:dataout.csv",会被当转义符,得写成 "C:\data\out.csv" 或用 raw string `C:dataout.csv`。
事情说清了就结束
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











