必须显式调用w.Flush(),否则缓冲区数据丢失;写Excel需加UTF-8 BOM;csv.Writer自动转义特殊字符;大文件应增大bufio缓冲并分批Flush。

csv.Writer 必须显式 Flush(),否则最后一块数据大概率丢在内存里——这不是 bug,是缓冲设计的必然结果。
为什么写完文件却是空的或少几行?
根本原因:你调了 w.Write(),但没调 w.Flush()。标准库的 csv.Writer 底层用 bufio.Writer 缓冲,默认 4KB,不 flush 就退出,缓冲区内容直接被丢弃。
- 常见错误现象:程序运行无报错,打开 CSV 文件发现最后一行缺失、空文件、或 Excel 提示“文件损坏”
-
defer w.Flush()不够可靠——如果中间 panic,defer 可能不执行;建议每批写完后主动调一次,最后再补一次 -
w.WriteAll()内部会 flush,但仅限本次调用范围;后续追加写仍需自己Flush() - 检查错误不能只看
Write()返回值,必须在Flush()后查w.Error(),它汇总了整个缓冲期内所有写失败
中文在 Excel 里显示乱码?加 BOM 是最简单解法
Go 字符串原生 UTF-8,写入本身没问题。Windows Excel 默认用 ANSI(如 GBK)打开无 BOM 的 UTF-8 文件,才导致乱码。
- 解决方案:在创建
csv.Writer前,先向文件写入 UTF-8 BOM:file.Write([]byte("\xef\xbb\xbf")) - 只写一次,且必须在
w.Write(header)之前,否则 Excel 会把 BOM 当作第一列内容 - 别尝试写 GBK —— Go 标准库不支持,第三方编码库转换成本高、易出错
- 不用 BOM 的场景(如 Linux 服务间传输),确保接收方明确按 UTF-8 解析即可
字段含逗号、换行、双引号,怎么安全写入?
csv.Writer 会自动处理,前提是别插手——不要手动加引号、不要拼字符串、不要用 fmt.Fprintf。
从 CSV 数据集生成图数据库加载器和三元组映射。将表格 CSV 数据转换为图数据库可直接使用的节点、边和三元组。
- 正确做法:直接传
[]string{"Alice", "25", "Beijing, China", "line1\nline2", `She said "hi"`} - Writer 检测到字段含
,、"或换行符时,自动包裹双引号,并将内部"转义为"" - 错误做法:手动写
"\"Beijing, China\""→ 结果变成"""Beijing, China""",Excel 解析失败 - 结构体字段要写入,必须手动提取并转成字符串:
strconv.Itoa(u.Age)、u.CreatedAt.Format("2006-01-02"),标准库完全忽略csv:"name"tag
写百万行 CSV 怎么避免 OOM 或卡死?
默认 4KB 缓冲 + 频繁 flush 是小文件友好型配置,大文件得调优。
立即学习“go语言免费学习笔记(深入)”;
- 创建 writer 时传自定义缓冲:
csv.NewWriter(bufio.NewWriterSize(file, 1(64KB) - 每写 1000 行主动
w.Flush()一次,既防 buffer full panic,又控内存峰值 - 别用
strings.Builder先攒全部内容再写——100 万行轻松吃掉几百 MB 内存 - 数据库导出场景,别
rows.Scan全部到内存再循环写,应边Scan边w.Write()
Flush() 是两个最常被跳过的步骤,但它们恰恰决定了文件能否被 Excel 正确打开、数据是否完整落盘——其他逻辑再严谨,漏掉这两点,就等于没写。

















