buffalo 本身不支持 excel 导入导出,需借助 excelize 等第三方库手动实现;上传时通过 c.request().formfile 获取文件句柄并校验类型,导出时用 excelize.newfile 构造响应流式写入,注意中文、日期、模板及并发安全等细节。

Buffalo 本身不提供 Excel 导入导出能力,必须搭配第三方库(如 github.com/xuri/excelize/v2 或 github.com/360EntSecGroup-Skylar/excelize)手动实现。 它只负责 HTTP 请求路由、参数解析和响应返回,Excel 的读写逻辑完全由你控制。
怎么在 Buffalo action 中读取上传的 Excel 文件
Buffalo 使用标准 http.Request,文件上传走 multipart/form-data,需手动调用 r.MultipartForm 或 r.FormFile 获取 *multipart.FileHeader:
- 确保前端表单
<form enctype="multipart/form-data"></form>,且<input type="file" name="file"> - 在 action 中用
c.Request().FormFile("file")获取文件句柄,不要直接读c.Request().Body - 传给
excelize.OpenReader或excelize.OpenFile(后者需先保存临时文件) - 注意校验文件后缀和 MIME 类型,防止恶意上传:
header.Header.Get("Content-Type")应为application/vnd.openxmlformats-officedocument.spreadsheetml.sheet或application/vnd.ms-excel
怎么从数据库查数据并导出为 Excel 下载
导出本质是构造一个 Content-Disposition: attachment; filename="xxx.xlsx" 响应,把 Excel 写入 c.Response() 的 io.Writer:
- 用
excelize.NewFile()创建新工作簿,f.SetSheetRow或f.AppendRow写入数据 - 设置响应头:
c.Response().Header().Set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"),再加Content-Disposition - 调用
f.Write(c.Response())直接流式写入响应体 —— 不要先生成本地文件再读取,会吃内存 - 若数据量大(>10 万行),避免一次性加载进内存;改用
f.StreamWriteRow+ 分批查询
常见坑:中文乱码、日期错位、模板填充失败
这些不是 Buffalo 的问题,而是 excelize 使用细节没处理好:
- 中文乱码:确保 Go 源码文件保存为 UTF-8,且
excelize版本 ≥ v2.7.0(旧版对中文样式支持差) - 日期变成数字:Excel 存的是浮点数天数,需用
f.SetCellDateTime而非SetCellValue,并配合f.SetCellStyle设置日期格式 - 模板填充失败:用
f.CloneSheet或f.GetSheetMap确认目标 sheet 名/索引;模板中占位符建议用{{.Name}}风格,再用text/template渲染后写入,别硬编码坐标 - 并发导出时 panic:
*excelize.File不是 goroutine-safe,每个请求必须新建实例
真正难的不是“怎么连上 Buffalo”,而是 Excel 格式本身的边界情况:合并单元格跨行、公式引用、条件格式、富文本换行——这些都得靠 excelize 一层层手动设,Buffalo 只是帮你把请求和响应串起来而已。











