excelize 是当前 go 操作 excel 的事实标准,tealeg/xlsx 已归档、不维护,且对中文路径、样式、公式支持弱;常见错误包括 panic、中文乱码、合并单元格越界、大文件 oom 等。

用 tealeg/xlsx 还是 excelize?选错库会卡在中文和大文件上
直接说结论:excelize 是当前 Go 操作 Excel 的事实标准,tealeg/xlsx 已归档、不维护,且对中文路径、样式、公式支持弱。你如果刚写几行就遇到 panic: runtime error: invalid memory address 或中文乱码,大概率是用了老库。
常见错误现象:用 tealeg/xlsx 读取含合并单元格的 Excel 报 index out of range;写入中文列名后 Excel 打开提示“文件已损坏”;导出 10 万行数据内存暴涨到 2GB。
-
excelize原生支持 .xlsx(不支持 .xls),纯 Go 实现,无 CGO 依赖,适合容器部署 - 对中文路径、UTF-8 字符、日期格式、条件格式、图表等支持更稳,官方文档示例也全
- 性能上,用
f.NewSheet()+f.SetCellValue()写入 5 万行耗时约 1.2s(i7-11800H),而tealeg/xlsx同样操作可能卡住或 OOM
f.SetCellValue() 和 f.SetRow() 性能差 10 倍,别无脑循环设单元格
很多人一上来就写 for 循环调 f.SetCellValue("Sheet1", fmt.Sprintf("A%d", i), data[i]),数据量一过 1 万行就明显变慢——因为每次调用都触发内部坐标解析、样式继承检查、XML 节点重建。
正确做法是批量写入:
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
- 用
f.SetRow("Sheet1", 1, &[]interface{}{"姓名", "年龄", "城市"})一次性写整行,比单单元格快 5–8 倍 - 若需动态列数,先构造
[]interface{}切片再传入,避免在循环里反复append+SetCellValue - 写大量数据时,关掉自动计算:
f.Calculation = &excelize.Calculation{CalcMode: "manual"},否则每设一个带公式的单元格都会触发重算
读 Excel 时 f.GetSheetMap() 返回空?检查文件是否被 Excel 进程锁住
本地开发常遇到:代码明明能打开文件,但 f.GetSheetMap() 返回空 map,或 f.GetSheetName(0) panic —— 其实不是代码问题,而是 Excel 应用正在后台挂着并锁了该文件。
Windows 下尤其明显,哪怕你只是双击打开过一次没关,Go 进程就无法获取完整 ZIP 结构(Excel 文件本质是 ZIP 包)。
- 用
os.OpenFile(path, os.O_RDONLY, 0)手动测试能否打开,如果报permission denied,八成是被占用了 - 不要依赖
f.GetSheetList()前先调f.Close(),它必须在读完所有数据后才调,提前关会导致后续GetCellValuepanic - 生产环境建议加一层校验:
if len(f.GetSheetMap()) == 0 { return errors.New("sheet map empty: file may be locked or corrupted") }
导出后 Excel 提示“发现不可读取的内容”,90% 是 Style ID 错配或字体名含空格
这个错误不报 panic,但用户打不开文件或样式全丢。根本原因是 excelize 的样式系统依赖 ID 引用,而手动创建样式时若漏设 Font.Name 或用了系统不存在的字体(比如填了 "Microsoft YaHei" 但在 Linux 容器里没装),Excel 就会降级失败。
- 安全写法:统一用
"Arial"或"Calibri",避免中文字体名;如必须用宋体,改用"SimSun"(英文名),且确保目标环境有该字体 - 创建样式后务必保存返回的 ID:
styleID, err := f.NewStyle(&excelize.Style{Font: &excelize.Font{Bold: true}}),别直接传结构体字面量进SetCellStyle - 合并单元格前确认行列范围合法:
f.MergeCell("Sheet1", "A1", "B1")比f.MergeCell("Sheet1", "A1", "A0")安全得多,后者不会报错但导出后文件损坏
最麻烦的其实是样式复用逻辑——同一个 styleID 可以跨 sheet 复用,但如果你在不同 sheet 里分别 NewStyle 出两个 ID 相同的样式,Excel 会混乱。所以风格定义最好集中初始化,别散落在各个函数里。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










