Golang使用Gorm将Model数据导出为CSV文件
Golang使用Gorm将Model数据导出为CSV文件 以下示例代码运行正常:
func GenerationCSV(c *gin.Context) {
items := [][]string{
{"UserID", "FullName", "Email"}, // 表头
{"1", "Jack Johnson", "jack@hotmail.com"}, // 数据项
{"2", "Jill Smith", "jill@hotmail.com"},
{"3", "James Murphy", "james@hotmail.com"},
}
// 设置响应头,使浏览器下载文件
c.Header("Content-Type", "text/csv")
c.Header("Content-Disposition", "attachment;filename=users.csv")
// 使用HTTP响应写入器作为io.Writer创建CSV写入器
wr := csv.NewWriter(c.Writer)
if err := wr.WriteAll(employees); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Failed to generate CSV file",
})
return
}
}
但使用以下代码时,我遇到了编译错误:
package models
import "gorm.io/gorm"
type Employee struct {
gorm.Model
Firstname string `json:"first_name"`
Lastname string `json:"last_name"`
Email string `json:"email"`
Gender string `json:"gender"`
Ipaddress string `json:"ip_address"`
Avatar string `json:"avatar"`
Phone string `json:"phone"`
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
Password string `json:"password"`
Socialmedia string `json:"social_media"`
}
CSV生成失败:
func GenerationCSV(c *gin.Context) {
fmt.Println("Start")
// 获取所有用户
var employees []models.Employee
initializers.DB.Find(&employees)
// 设置响应头,使浏览器下载文件
c.Header("Content-Type", "text/csv")
c.Header("Content-Disposition", "attachment;filename=users.csv")
// 使用HTTP响应写入器作为io.Writer创建CSV写入器
wr := csv.NewWriter(c.Writer)
if err := wr.WriteAll(employees); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Failed to generate CSV file",
})
return
}
fmt.Println("Step------------->")
fmt.Println("Stop")
}
需要帮助,因为此方法期望接收一个[][]string类型的参数:
// WriteAll 使用Write将多个CSV记录写入w,然后调用Flush,
// 并返回Flush过程中的任何错误。
func (w *Writer) WriteAll(records [][]string) error
更多关于Golang使用Gorm将Model数据导出为CSV文件的实战教程也可以访问 https://www.itying.com/category-94-b0.html
啊,好的。抱歉,我忽略了这是一个编译器错误。很高兴看到你解决了这个问题。
更多关于Golang使用Gorm将Model数据导出为CSV文件的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
你好 @Maodo_Diop,
要开始调试这个问题,我建议首先检查以下几点:
-
initializers.DB.Find()是否返回一个错误值?如果是,请检查这个返回值是否为非 nil 错误。 -
initializers.DB.Find()是否确实填充了employee变量? -
wr.WriteAll(employees)返回了什么错误?
这些检查应该有助于缩小根本原因的范围。
步骤1和2没问题,但我在VsCode中遇到了一个编译器错误,如下所示:*cannot use &employees (value of type []models.Employee) as [][]string value in argument to wr.WriteAllcompilerIncomp 请注意:我已经为给定的模型 models.Employee 实现了所有CRUD操作。
在带有热重载的控制台中,我得到了以下信息: 2022/07/28 19:46:39 正在运行构建命令! 2022/07/28 19:46:42 构建时出错:
go-jwwt/viz
*viz\generatorFile.go:25:24: cannot use &employees (type []models.Employee) as type [][]string in argument to wr.WriteAll
我创建了一个变量,并遍历了 employees 中的数据。
wr := csv.NewWriter(c.Writer)
//期望的数据格式:这里是解决方案
var data [][]string
for _, record := range employees {
row := []string{
record.Firstname,
record.Lastname,
record.Email,
record.Gender,
record.Ipaddress,
record.Avatar,
record.Phone,
strconv.FormatFloat(record.Latitude, 'f', -1, 64),
strconv.FormatFloat(record.Longitude, 'f', -1, 64),
record.Password,
record.Socialmedia,
}
data = append(data, row)
}
if err := wr.WriteAll(data); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Failed to generate CSV file",
})
return
}
问题在于 csv.Writer.WriteAll() 需要 [][]string 类型,但你传递的是 []models.Employee。你需要将 Employee 切片转换为字符串二维切片。以下是修正后的代码:
func GenerationCSV(c *gin.Context) {
fmt.Println("Start")
// 获取所有用户
var employees []models.Employee
initializers.DB.Find(&employees)
// 创建CSV数据
records := [][]string{
{"ID", "Firstname", "Lastname", "Email", "Gender", "Ipaddress", "Avatar", "Phone", "Latitude", "Longitude", "Socialmedia"},
}
for _, emp := range employees {
record := []string{
fmt.Sprintf("%d", emp.ID),
emp.Firstname,
emp.Lastname,
emp.Email,
emp.Gender,
emp.Ipaddress,
emp.Avatar,
emp.Phone,
fmt.Sprintf("%f", emp.Latitude),
fmt.Sprintf("%f", emp.Longitude),
emp.Socialmedia,
}
records = append(records, record)
}
// 设置响应头
c.Header("Content-Type", "text/csv")
c.Header("Content-Disposition", "attachment;filename=users.csv")
// 创建CSV写入器并写入数据
wr := csv.NewWriter(c.Writer)
if err := wr.WriteAll(records); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Failed to generate CSV file",
})
return
}
fmt.Println("CSV generation completed")
}
如果需要包含 gorm.Model 中的时间戳字段,可以这样处理:
func GenerationCSV(c *gin.Context) {
fmt.Println("Start")
var employees []models.Employee
initializers.DB.Find(&employees)
records := [][]string{
{"ID", "CreatedAt", "UpdatedAt", "DeletedAt", "Firstname", "Lastname", "Email", "Gender", "Ipaddress", "Avatar", "Phone", "Latitude", "Longitude", "Socialmedia"},
}
for _, emp := range employees {
record := []string{
fmt.Sprintf("%d", emp.ID),
emp.CreatedAt.Format("2006-01-02 15:04:05"),
emp.UpdatedAt.Format("2006-01-02 15:04:05"),
fmt.Sprintf("%v", emp.DeletedAt.Time),
emp.Firstname,
emp.Lastname,
emp.Email,
emp.Gender,
emp.Ipaddress,
emp.Avatar,
emp.Phone,
fmt.Sprintf("%f", emp.Latitude),
fmt.Sprintf("%f", emp.Longitude),
emp.Socialmedia,
}
records = append(records, record)
}
c.Header("Content-Type", "text/csv")
c.Header("Content-Disposition", "attachment;filename=users.csv")
wr := csv.NewWriter(c.Writer)
if err := wr.WriteAll(records); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Failed to generate CSV file",
})
return
}
fmt.Println("CSV generation completed")
}
注意:Password 字段通常不应导出到 CSV 文件中,因此上述示例中已将其排除。如果需要包含,可以自行添加。

