根本原因是Go导出Excel时未正确设置中文字体及单元格格式。需用SetCellStyle为中文列设SimSun等字体;时间字段须用TimeToExcelTime转换并配NumFmt=22;大数据量应游标读取+批量写入;响应头须正确设置Content-Type和URL编码的Content-Disposition。

导出时 Excel 文件乱码或中文显示为方块
根本原因是 Go 默认生成的 Excel(如用 excelize)未正确设置单元格字体,尤其在 Windows 环境下默认使用无中文字体的 Calibri 或 Arial。即使数据是 UTF-8 编码,Excel 渲染时仍会 fallback 到不支持中文的字体。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 创建工作表后,立即调用
f.SetCellStyle为目标列范围设置含中文字体的样式,例如:"SimSun"(宋体)、"Microsoft YaHei"(微软雅黑)或"Noto Sans CJK SC"(跨平台推荐) - 务必同时设置
font.Bold = true(可选)和font.Size = 11,避免某些版本 Excel 忽略纯字体名设置 - 若用
excelize.NewFile()后直接f.SetCellValue写入中文,必须在写入前或写入后批量应用样式,单个单元格设样式性能差且易遗漏
大数据量导出内存爆满或速度极慢
常见错误是把全部数据库结果一次性查到内存(rows.Scan 收集成 []map[string]interface{}),再逐行调用 f.SetCellValue —— 这会让 Go 进程内存占用翻数倍,且 Excel 写入本身是同步阻塞操作。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 用
database/sql的游标式遍历:for rows.Next() { ... rows.Scan(&v1, &v2) },边读边写,避免全量缓存 - 对
excelize.File,每写入 500–1000 行主动调用一次f.SetRow批量设高(可选)并触发内部缓冲 flush,降低内存驻留峰值 - 导出前调用
f.NewSheet("data")并立即f.SetActiveSheet,避免默认 sheet 被冗余计算影响性能 - 禁用自动计算与公式重算:
f.SetCalculation(&excelize.Calculation{CalcMode: "manual"})
时间字段导出后在 Excel 里变成数字而非日期格式
Go 的 time.Time 写入 Excel 单元格时,默认被转成 float64 类型的 Excel 序列号(从 1900-01-01 起的天数),但单元格格式仍是“常规”,导致显示为类似 45201.625 的数字。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 写入前将
time.Time转为 Excel 可识别的浮点值:excelize.TimeToExcelTime(t, false)(注意第二个参数为false表示 1900 日期系统) - 必须配套设置单元格数字格式:
style := excelize.Style{NumFmt: 22}(22 是 Excel 内置的yyyy-mm-dd h:mm:ss格式 ID),再用f.SetCellStyle绑定 - 不要依赖
f.SetCellValue("A1", t)自动转换 —— 它只存数值,不设格式,Excel 打开时无法自动识别为日期
导出文件下载时浏览器提示损坏或打不开
典型原因是 HTTP 响应头缺失或错误,尤其是 Content-Type 和 Content-Disposition 不匹配实际文件内容,或者写入响应体前已写 header 或发生 panic 导致 body 截断。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 响应头必须设为:
w.Header().Set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") -
Content-Disposition中文件名需 URL 编码(尤其含中文):w.Header().Set("Content-Disposition", "attachment; filename*=UTF-8''" + url.PathEscape("用户数据.xlsx")) - 务必用
f.Write(w)直接写入http.ResponseWriter,不要先f.WriteTo到bytes.Buffer再写——大文件会吃光内存 - 导出逻辑外层加
defer捕获 panic,并确保http.Error或日志记录,否则静默失败导致前端收空响应
最易被忽略的是样式与格式的绑定时机:Excel 的单元格值和格式是分离存储的,SetCellValue 不会自动关联样式,必须显式调用 SetCellStyle,且样式 ID 需通过 f.NewStyle 获取——漏掉这一步,所有格式设置都无效。

















