问题复现
package main
import (
"encoding/csv"
"log"
"os"
"strconv"
)
func main() {
// 创建文件
file, _ := os.Create("test.csv")
defer file.Close()
// 创建一个csv.Writer对象
writer := csv.NewWriter(file)
defer writer.Flush()
// 写入数据到CSV文件中
data := [][]string{
{"序号", "姓名", "年龄"},
{"1", "张三", strconv.Itoa(25)},
{"2", "李四", strconv.Itoa(30)},
{"3", "王五", strconv.Itoa(28)},
}
writer.WriteAll(data)
writer.Flush()
if err := writer.Error(); err != nil {
log.Fatal(err)
}
}
通过这个代码生成的csv文件,由于存在中文字符串,所以使用excel表打开是乱码的。 具体可以通过developer.aliyun.com/article/539… 来告知excel对应的编码格式从而打开不是乱码的文件。
原因
这是因为golang是使用utf-8对csv文件进行编码的,但是excel默认是使用ANSI编码格式来打开文件的,excel表无法打开即识别utf-8编码的文件,所以就出现了乱码。
解决办法
知道了原因,就能知道解决办法了,通过测试,发现excel表能打开即识别utf-8 bom、GBK(向下兼容ANSI)、ANSI等编码的文件,所以只要在写入文件时改为对应的编码方式就好了。
解决办法一:使用utf-8 bom编码
只需要在文件开头写入对应的字节顺序标记就好了。
package main
import (
"encoding/csv"
"log"
"os"
"strconv"
)
func main() {
// 创建文件
file, _ := os.Create("test.csv")
defer file.Close()
//标记为utf-8 bom编码
file.WriteString("xEFxBBxBF")
// 创建一个csv.Writer对象
writer := csv.NewWriter(file)
defer writer.Flush()
// 写入数据到CSV文件中
data := [][]string{
{"序号", "姓名", "年龄"},
{"1", "张三", strconv.Itoa(25)},
{"2", "李四", strconv.Itoa(30)},
{"3", "王五", strconv.Itoa(28)},
}
writer.WriteAll(data)
writer.Flush()
if err := writer.Error(); err != nil {
log.Fatal(err)
}
}
解决办法二:使用GBK编码
package main
import (
"encoding/csv"
"log"
"os"
"strconv"
"golang.org/x/text/encoding/simplifiedchinese"
"golang.org/x/text/transform"
)
func main() {
// 创建文件
file, _ := os.Create("test.csv")
defer file.Close()
// 创建一个csv.Writer对象 (使用gbk编码)
writer := csv.NewWriter(transform.NewWriter(file, simplifiedchinese.GBK.NewEncoder()))
defer writer.Flush()
// 写入数据到CSV文件中
data := [][]string{
{"序号", "姓名", "年龄"},
{"1", "张三", strconv.Itoa(25)},
{"2", "李四", strconv.Itoa(30)},
{"3", "王五", strconv.Itoa(28)},
}
writer.WriteAll(data)
writer.Flush()
if err := writer.Error(); err != nil {
log.Fatal(err)
}
}