go读csv中文乱码需先用golang.org/x/text/encoding转码为utf-8再交由csv.newreader;批量插入应分批+预处理语句,pg可用copy from提速;导出excel优先选excelize(支持流式写入);json字段名不一致须显式加json:"xxx"标签。

Go 读 CSV 文件时中文乱码怎么破
Go 标准库 encoding/csv 默认只处理 UTF-8,遇到 GBK、GB2312 等编码的 Excel 导出 CSV,ReadAll() 会直接报 invalid UTF-8 sequence 或读出乱码。
别硬解——先转码再交给 csv.NewReader:
- 用
golang.org/x/text/encoding包识别并转换编码,比如 GB18030(兼容 GBK/GB2312) - 把原始
[]byte用transform.NewReader包一层,再传给csv.NewReader - 注意:不能对字符串做转码后再传入,因为
csv.Reader内部会按字节切分,必须在 Reader 层就完成字节流转换
enc := gbk.Encoder() reader := transform.NewReader(file, enc) csvReader := csv.NewReader(reader) records, _ := csvReader.ReadAll() // 这时 records 就是干净的 UTF-8 字符串
用 database/sql 批量插入百万级数据太慢怎么办
逐条 Exec 插入,哪怕加了事务,也会因网络往返和语句解析拖垮性能;用 INSERT INTO ... VALUES (...), (...), ... 拼大 SQL 是常见思路,但容易触发 MySQL 的 max_allowed_packet 限制或内存溢出。
更稳的做法是分批 + 预处理语句:
- 每 1000–5000 行为一批,用
tx.Stmt(prepareSQL).Exec(args...)复用执行计划 - 避免拼接 SQL 字符串,尤其含用户输入时;预处理天然防注入
- PostgreSQL 可用
COPY FROM STDIN(通过pgx的CopyFrom),比批量 INSERT 快 5–10 倍;MySQL 没原生等价物,别信“LOAD DATA LOCAL INFILE 在 Go 里能安全用”的说法——多数驱动默认禁用,且需服务端显式开启
导出 Excel(.xlsx)为什么选 tealeg/xlsx 而不是 excelize
tealeg/xlsx 已归档停更,excelize 是当前事实标准,但新手常因文档命名混淆而误选旧库,导致编译失败或缺失关键功能(如样式、公式、大数据写入)。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
真实差异点很实在:
-
excelize支持流式写入(f.NewStreamWriter),导出 10 万行不爆内存;tealeg/xlsx全部加载进内存,稍大文件就 panic -
excelize的单元格样式、条件格式、图表都可用,tealeg/xlsx样式支持残缺且无维护 - 导入时,
excelize的f.GetSheetList()和f.GetRows()更稳定,尤其处理 Excel 自动合并的空行/空列时容错更强
别被旧教程带偏,直接上 github.com/xuri/excelize/v2。
JSON 导入导出字段名大小写不一致导致解析失败
前端传 user_name,后端结构体字段叫 UserName 却没加 tag,json.Unmarshal 就会忽略该字段——Go 的 JSON 解析器严格依赖 struct tag 或首字母大小写规则,不会自动下划线转驼峰。
两个务实选择:
- 统一用
json:"user_name"tag 显式声明,别依赖默认行为;所有导出结构体都加,导入结构体也加(即使字段名碰巧匹配) - 如果字段极多且命名风格混杂,用
map[string]interface{}先接住原始数据,再手动映射到结构体,可控但繁琐 - 警惕
json.RawMessage误用:它只是延迟解析,不解决字段名映射问题;真正要的是 tag 对齐,不是绕开解析
字段名映射不是“语法糖”,是数据契约。少一个 tag,就可能漏掉一整列业务数据。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










