使用Golang导出CSV数据并解决数据乱码问题

总结摘要
本文介绍了如何使用 Golang 导出 CSV 数据并解决乱码问题。CSV 是一种轻量级的数据导出格式,适合处理大数据量导出任务。文章展示了两种实现方式:一是将 CSV 数据写入本地文件,通过 os.Create 创建文件并使用 csv.NewWriter 写入数据;二是结合 Gin 框架实现 Web 端导出,将数据写入内存缓冲区并通过 HTTP 响应返回给客户端。为避免中文乱码,文章建议在文件开头写入 UTF-8 BOM()。

在日常开发中,针对数据导出,我们可以导出Excel格式,但是如果是针对大数据量的导出,直接导出为Excel格式可能需要占用大量内存,且导出速度很慢。这个时候我们就需要导出为CSV格式。

CSV 格式

CSV本质上是文本文件,该文件有以下要求:

  • 列之间用逗号分隔,行之间用换行分隔
  • 单元格如果有逗号、引号之类的字符,该单元格需要使用双引号括起来
  • 如果内容包含中文,直接输出可能会乱码

golang导出CSV

实现方式

golang 官方有csv的库,可以很容易的实现csv数据的写入。

golang实现csv数据写文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
func main() {
	f, err := os.Create("data.csv")
	if err != nil {
		panic(err)
	}
	defer f.Close()

	f.WriteString("\xEF\xBB\xBF") // 写入UTF-8 BOM,避免使用Microsoft Excel打开乱码

	writer := csv.NewWriter(f)
	writer.Write([]string{"编号", "姓名", "年龄"})
	writer.Write([]string{"1", "张三", "23"})
	writer.Write([]string{"2", "李四", "24"})
	writer.Write([]string{"3", "王五", "25"})
	writer.Write([]string{"4", "赵六", "26"})
	writer.Flush() // 此时才会将缓冲区数据写入
}

golang实现web导出csv数据

此处以gin框架为例,如果用的go官方web库,其实差不多是一样的:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
func ExportCsv(c *gin.Context) {
	bytesBuffer := &bytes.Buffer{}
	bytesBuffer.WriteString("\xEF\xBB\xBF") // 写入UTF-8 BOM,避免使用Microsoft Excel打开乱码

	writer := csv.NewWriter(bytesBuffer)
	writer.Write([]string{"编号", "姓名", "年龄"})
	writer.Write([]string{"1", "张三", "23"})
	writer.Write([]string{"2", "李四", "24"})
	writer.Write([]string{"3", "王五", "25"})
	writer.Write([]string{"4", "赵六", "26"})

	writer.Flush() // 此时才会将缓冲区数据写入

	// 设置下载的文件名
	c.Writer.Header().Set("Content-Disposition", "attachment;filename=data.csv")
	// 设置文件类型以及输出数据
	c.Data(http.StatusOK, "text/csv", bytesBuffer.Bytes())
	return
}