必须用multipart/form-data,gin的c.formfile()是入口;前端需设enctype且name与参数严格一致,否则返回nil,err;解析excel推荐tealeg/xlsx或qax92/xlsx,避免excelize因不支持seek()报错。

上传文件时必须用 multipart/form-data,Gin 的 c.FormFile() 是入口
Gin 本身不处理文件上传逻辑,只提供对标准 http.Request 的封装。上传 Excel 文件必须走表单 multipart 方式,前端 <input type="file"> 要确保 enctype="multipart/form-data",否则 c.FormFile("file") 会返回 nil, err。
常见错误是前端漏写 enctype 或后端用错 key 名(比如传了 excelFile 却调 c.FormFile("file")):
-
c.FormFile("file")第二个返回值是error,务必检查,空文件或字段名不匹配都会报错 - 拿到
*multipart.FileHeader后,不要直接用Open()读取多次 —— 它是一次性流,重复Open()会失败 - 如果只是临时读取内容、不存盘,建议用
header.Open()得到io.ReadCloser,直接传给 Excel 解析库
读取 Excel 推荐用 tealeg/xlsx 或 qax92/xlsx,别碰 excelize 的上传解析路径
excelize 对上传流支持不友好:它的 OpenReader() 要求 io.Reader 支持 Seek(),而 multipart.FileHeader.Open() 返回的 io.ReadCloser 不支持 Seek()(底层是 pipe)。强行用会报 "seeker is not supported"。
更稳妥的选择是:
-
tealeg/xlsx:老但稳定,xlsx.OpenBinary()接收[]byte,可先header.Open()+io.ReadAll()加载进内存(适合小文件) -
qax92/xlsx:tealeg/xlsx的维护分支,修复了部分 panic 和日期解析问题 - 若文件很大(>10MB),需流式解析,得改用
tarantak/xlsx或自己基于encoding/xml解 zip 内的xl/worksheets/sheet1.xml
示例片段:
f, err := header.Open()
if err != nil {
return
}
data, err := io.ReadAll(f)
if err != nil {
return
}
xlsx, err := xlsx.OpenBinary(data) // tealeg/xlsx
c.SaveUploadedFile() 只适合调试,生产环境别直接存盘再读
很多教程教先 c.SaveUploadedFile(header, "tmp.xlsx"),再用 xlsx.OpenFile() 打开 —— 这在并发场景下容易冲突(同名覆盖、权限问题),且多一次磁盘 I/O,性能差。
除非你明确需要审计原始文件、做病毒扫描或异步处理,否则没必要落盘。上传即解析是最简路径:
- 用
header.Open()获取 reader - 用
io.LimitReader()控制最大读取量(防恶意超大文件) - 解析前校验
header.Header.Get("Content-Type")是否为application/vnd.openxmlformats-officedocument.spreadsheetml.sheet(仅作参考,不可靠)或检查 magic bytes - Excel 文件开头 8 字节通常是
PK\x03\x04\x14\x00\x06\x00,可用bytes.HasPrefix(data[:8], []byte("PK"))粗筛
中文乱码、日期变数字、合并单元格丢失 —— 这些不是 Gin 的锅,是 Excel 库的解析限制
Gin 只管把字节流交出去,后续全是 Excel 解析库的事。常见现象对应原因:
- 中文显示成
???:不是编码问题,是tealeg/xlsx默认用strconv.Unquote处理字符串,某些版本对 UTF-8 BOM 处理异常;升级到qax92/xlsx或手动 strip BOM - 日期变成一串数字(如
44562):Excel 内部用“自 1900-01-01 起的天数”存日期,需调用cell.GetTime()(qax92/xlsx支持)或自己转换:time.Date(1899, 12, 30, 0, 0, 0, 0, time.UTC).AddDate(0,0,44562) - 合并单元格内容只在左上角单元格有值:这是 Excel 标准行为,
tealeg系列库不会自动填充合并区域,需遍历Sheet.MergeCells手动补值
这些细节一旦漏掉,前端看到的就是空数据或错乱时间 —— 解析 Excel 永远比上传难得多。











