CSV/Excel导入导出应使用encoding/csv和excelize库,避免手动拼接;注意UTF-8编码、流式处理大文件、字段清洗、错误精确定位、批量插入及格式标准化。

CSV 导入导出:用 encoding/csv 读写,别自己拼字符串
Go 标准库的 encoding/csv 足够可靠,但很多人误以为“逗号分隔=简单字符串拼接”,结果遇到字段含逗号、换行、引号就崩溃。真正导入时,必须用 csv.NewReader 解析;导出必须用 csv.NewWriter 写入,它会自动处理转义和引号包裹。
- 读 CSV 时,
reader.Read()返回的是[]string,每行字段已解码,不用再strings.Split - 写 CSV 时,调用
writer.Write([]string{"a", "b,c", "d\nf"})即可,csv.Writer自动加引号、转义 - 注意编码:标准库只支持 UTF-8;如果源文件是 GBK,得先用
golang.org/x/text/encoding转码,否则中文全变??? - 大文件别一次性
ReadAll,用循环Read+ 批量入库(比如每 1000 行Exec一次),否则内存爆掉
Excel 导入导出:选 tealeg/xlsx 还是 qax-os/excelize?
tealeg/xlsx 已停止维护,且不支持 .xlsx 的流式读写;生产环境强烈推荐 excelize —— 它支持读写、公式、样式、大数据量流式处理,而且无 CGO 依赖。
- 导入:用
f, err := excelize.OpenFile("data.xlsx"),再f.GetSheetList()查表名,f.GetRows("Sheet1")拿二维字符串切片 - 导出:新建
f := excelize.NewFile(),用f.SetCellValue("Sheet1", "A1", "标题")写单元格,最后f.SaveAs("out.xlsx") - 性能关键:读大 Excel 时,用
f.ReadSheet("Sheet1", func(row []string) error { ... })流式回调,避免全加载进内存 - 注意日期:Excel 存的是浮点数天数(从 1900-01-01 起),
excelize提供f.GetCellValue("Sheet1", "A1")会自动转成time.Time,但前提是单元格格式设为“日期”;否则拿到的是原始数字,得手动time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC).AddDate(0,0,int(days))
导入失败怎么定位?别只看 err != nil
CSV 或 Excel 导入常卡在某一行,但错误信息只说 “parse error at line 123”,实际可能是第 123 行某个字段类型不对(比如期望 int 却写了空字符串),或时间格式不匹配。光靠 err 不够,得结合上下文。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 在循环读取时,把当前行号、原始行内容(
fmt.Sprintf("%q", row))、结构体绑定错误一起打日志,例如:log.Printf("line %d: raw=%s, err=%v", i, row, err) - 用
strconv.Atoi转数字前,先strings.TrimSpace去首尾空格,否则" 123 "直接报错 - Excel 里看似空的单元格,
GetCellValue可能返回空字符串""或" "(带空格),别直接== ""判断,用strings.TrimSpace(v) == "" - 数据库插入失败时,别只记
err.Error(),加上sql.ErrNoRows等具体判断,区分是数据问题还是约束冲突
并发导入要不要开 goroutine?小心连接池和顺序依赖
批量导入不是并发越多越快。尤其写数据库时,并发争抢连接、事务隔离、主键冲突都会让吞吐下降甚至出错。
立即学习“go语言免费学习笔记(深入)”;
- 单个文件导入,别对每行起 goroutine ——
db.Exec本身有网络延迟,并发反而压垮 MySQL 连接池 - 真要提速,用
sql.DB.SetMaxOpenConns(n)配合批量插入(INSERT INTO ... VALUES (...), (...), (...)),比单条插入快 10 倍以上 - 多个文件并行导入可以开 goroutine,但每个 goroutine 应独占一个
*sql.Tx或控制并发数(如semaphore := make(chan struct{}, 3)) - 注意顺序:如果业务要求“按文件顺序生效”,并发写入后可能 DB 中记录乱序,得加时间戳或序号字段来保序
最麻烦的其实是混合格式校验——CSV 里日期写成 2024/01/01,Excel 里却是 2024-01-01 14:30:00,而数据库字段只认一种 layout。这块没银弹,得在解析层统一做 normalize,别拖到入库时才转换。

















