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

4 回复

啊,好的。抱歉,我忽略了这是一个编译器错误。很高兴看到你解决了这个问题。

更多关于Golang使用Gorm将Model数据导出为CSV文件的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你好 @Maodo_Diop

要开始调试这个问题,我建议首先检查以下几点:

  1. initializers.DB.Find() 是否返回一个错误值?如果是,请检查这个返回值是否为非 nil 错误。

  2. initializers.DB.Find() 是否确实填充了 employee 变量?

  3. 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 文件中,因此上述示例中已将其排除。如果需要包含,可以自行添加。

回到顶部