go可以通过excelize
包实现对excel的操作
"github.com/xuri/excelize/v2"
导出示例
service层
批量导出数据的,我们可以在dao层中返回一个切片。在service中新建一个excelize对象,单独设置表头。遍历切片往excelize上修改即可。
func (s *Service) ExcelDown(req model.ReleaseRecordRequest) (*excelize.File, error) {
// 从数据库拿到自己想要的数据
data, err := s.dao.QueryData(req)
if err != nil {
return nil, err
}
if len(data) == 0 {
return nil, errors.New("数据为空")
}
// 设置模版
f := excelize.NewFile() // 新建一个.xlsx文件
f.SetCellValue("Sheet1", "A1", "project_name") // 设置Sheet1中对应位置的值
f.SetCellValue("Sheet1", "B1", "env_name")
f.SetCellValue("Sheet1", "C1", "cluster_name")
f.SetCellValue("Sheet1", "D1", "mode")
f.SetCellValue("Sheet1", "E1", "remark")
f.SetCellValue("Sheet1", "F1", "status")
f.SetCellValue("Sheet1", "G1", "username")
f.SetCellValue("Sheet1", "H1", "start_time")
for i, datum := range data {
f.SetCellValue("Sheet1", fmt.Sprintf("A%d", i+2), datum.ProjectName)
f.SetCellValue("Sheet1", fmt.Sprintf("B%d", i+2), datum.EnvName)
f.SetCellValue("Sheet1", fmt.Sprintf("C%d", i+2), datum.ClusterName)
f.SetCellValue("Sheet1", fmt.Sprintf("D%d", i+2), datum.Mode)
f.SetCellValue("Sheet1", fmt.Sprintf("E%d", i+2), datum.Remark)
f.SetCellValue("Sheet1", fmt.Sprintf("F%d", i+2), datum.Status)
f.SetCellValue("Sheet1", fmt.Sprintf("G%d", i+2), datum.Username)
f.SetCellValue("Sheet1", fmt.Sprintf("H%d", i+2), datum.StartTime)
}
return f, err
}
controller层
这里跟普通的返回有点区别,需要给响应头添加参数
func export(ctx *gin.Context) {
file, err := s.ExportDown(req)
if err != nil {
...
return
}
buffer := new(bytes.Buffer)
if err := file.Write(buffer); err != nil {
...
return
}
excelData := buffer.Bytes()
ctx.Header("Content-Disposition", "attachment;filename="+"xxx.xlsx")
ctx.Data(http.StatusOK, "application/octet-stream", excelData)
}
cvs
如果一切顺利的话,导出到这里结束了,但我今天偏偏就遇到了不正常的。
在本地、测试环境下载文件均正常,在生产环境下载文件无法打开。
中间我查了很多资料,但是都没解决(我怀疑是生产环境的问题,但是由于是生产环境,也没有办法)
条条大陆通罗马,我们的目的是导出,至于具体是什么类型的文件,并没有要求
终于我找到了 cvs
文件
CSV(逗号分隔值)文件是一种特殊的文件类型,可在 Excel 中创建或编辑。 CSV 文件不是采用多列的形式存储信息,而是使用逗号分隔的形式存储信息。 将文本和数字保存在 CSV 文件中时,可轻松将它们从一个程序移动至另一个程序。
简直一摸一样,操作也十分简单,只需要对上面代码简单修改即可
server层
func (s *Service) ExcelDown(req model.ReleaseRecordRequest) (string, error) {
// 查
data, err := s.dao.QueryData(req)
if err != nil {
return "", err
}
if len(data) == 0 {
return "", errors.New("数据为空")
}
var b strings.Builder
writer := csv.NewWriter(&b)
// 写入标题行
err = writer.Write([]string{"project_name", "env_name", "cluster_name", "mode", "remark", "status", "username", "start_time"})
if err != nil {
return "", err
}
// 写入数据
for _, datum := range data {
err = writer.Write([]string{datum.ProjectName, datum.EnvName, datum.ClusterName, datum.Mode, datum.Remark, datum.Status, datum.Username, datum.StartTime})
if err != nil {
return "", err
}
}
writer.Flush()
return b.String(), nil
}
controller层
func export(ctx *gin.Context) {
data, err := s.ExportDown(req)
if err != nil {
...
return
}
c.Header("Content-Type", "text/csv")
c.Header("Content-Disposition", "attachment;filename=export.csv")
c.String(http.StatusOK, "\xEF\xBB\xBF"+data) // "\xEF\xBB\xBF 解决乱码问题"
}
最后成功导出,打开和excel一摸一样(公司的数据,这里我就不打开演示了)