一.声明路由
superadmin := e.Group("/api/super管理员")
{
superadmin.GET("/download_用户", s.Download用户)
}
用户点击前端按钮url->路由查找相应的函数->调用函数返回
所以一定要先定义路由
二.函数的具体实现
总体步骤就是 找文件->按照格式写入缓冲区->然后写个头部告诉浏览器是下载操作
二.1首先获取数据库中的文件 或者data
list, err := s.store.用户()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "服务器繁忙", "data": err})
return
}
具体的实现就不给了 从mysql里面取数据 拿出来存到相应的结构体 不是本文章的重点
二.2 创建写入csv文件的buffer
// 创建CSV文件
b := &bytes.Buffer{} // 创建一个Buffer来写入CSV数据
// 写入UTF-8 BOM
b.Write([]byte{0xEF, 0xBB, 0xBF})
-
用
bytes.Buffer{}
创建一个新的缓冲区b
,用于临时存储CSV文件的内容。 -
向缓冲区写入UTF-8的BOM,确保生成的CSV文件在各种文本编辑器和表格处理软件中能正确识别为UTF-8编码。(也可以不写)
这里的CSV是数据库导入文件的一种格式
二.3 写入表的列名
writer := csv.NewWriter(b)
// 写入CSV头部,包括所有字段名
headers := []string{
"用户_id", "用户_name", "用户_token", ......
}
if err := writer.Write(headers); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "创建CSV失败", "data": err})
return
}
-
使用
csv.NewWriter(b)
创建一个新的CSV writer对象,它会将数据写入之前创建的缓冲区b
。 -
创建一个字符串切片
headers
,包含了CSV文件的所有列名。 -
通过
writer.Write(headers)
将列名写入。
二.4 写入每个对象的信息
for _, user := range list {
record := []string{
strconv.FormatInt(用户.ID, 10),
strconv.FormatBool(用户.Active),
用户.用户IP,
strconv.FormatInt(int64(用户.UserType), 10),
strconv.FormatInt(int64(用户.SlaveAuthority), 10),
strconv.FormatInt(用户.MasterID, 10),
......
}
if err := writer.Write(record); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "写入CSV失败", "data": err})
return
}
}
-
遍历
list
,对于列表中的每个用户,将其信息格式化为字符串并添加到一个新的切片record
中。(注意各种数字,bool类型的转换,因为golang是强类型语言) -
使用
writer.Write(record)
将每个用户的信息写入CSV文件。
二.5结束写入
writer.Flush()
// 检查是否有写入错误
if err := writer.Error(); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "写入CSV失败", "data": err})
return
}
-
调用
writer.Flush()
结束写入操作,并确保所有缓冲的数据都被写入到b
中。 -
通过
writer.Error()
检查写入过程中是否有错误发生。
二.6 设置响应头部告诉浏览器是下载操作
// 设置响应头部,使浏览器下载文件
c.Header("Content-Description", "File Transfer")
c.Header("Content-Disposition", "attachment; filename=users.csv")
c.Data(http.StatusOK, "text/csv", b.Bytes())
-
设置响应头部,包括
Content-Description
和Content-Disposition
,后者指示浏览器这是一个文件下载操作,文件名为users.csv
。 -
最后,使用
c.Data(http.StatusOK, "text/csv", b.Bytes())
发送CSV数据。这里,http.StatusOK
表示HTTP状态码200,"text/csv"
是MIME类型,b.Bytes()
是CSV文件的内容。
三.整个代码
func (s *APIServer) Download用户(c *gin.Context) {
list, err := s.store.用户()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "服务器繁忙", "data": err})
return
}
// 创建CSV文件
b := &bytes.Buffer{} // 创建一个Buffer来写入CSV数据
// 写入UTF-8 BOM
b.Write([]byte{0xEF, 0xBB, 0xBF})
writer := csv.NewWriter(b)
// 写入CSV头部,包括所有字段名
headers := []string{
"用户id",....
}
if err := writer.Write(headers); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "创建CSV失败", "data": err})
return
}
// 写入用户数据
for _, user := range list {
record := []string{
strconv.FormatInt(用户.ID, 10),
.....
}
if err := writer.Write(record); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "写入CSV失败", "data": err})
return
}
}
writer.Flush()
// 检查是否有写入错误
if err := writer.Error(); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "写入CSV失败", "data": err})
return
}
// 设置响应头部,使浏览器下载文件
c.Header("Content-Description", "File Transfer")
c.Header("Content-Disposition", "attachment; filename=users.csv")
c.Data(http.StatusOK, "text/csv", b.Bytes())
}
四.如何查看下载的csv文件
下载到的csv文件用记事本查看不会乱码
如果你想用Excel查看按照以下步骤
点击从文本/csv
点导入
选择UTF-8格式即可