Golang的csv库支持解析csv文件,导入encoding/csv就可以用了,但本身不太好用,特别是当CSV表列的顺序被打乱后,还得改动代码里面对应列在解析出的数据的索引,所以就这两个问题,简单封装了下,使之用起来更加方便,代码如下:
1 package csvMgr 2 3 import ( 4 "encoding/csv" 5 "os" 6 "strconv" 7 8 "github.com/astaxie/beego" 9 )10 11 type CsvTable struct {12 FileName string13 Records []CsvRecord14 }15 16 type CsvRecord struct {17 Record map[string]string18 }19 20 func (c *CsvRecord) GetInt(field string) int {21 var r int22 var err error23 if r, err = strconv.Atoi(c.Record[field]); err != nil {24 beego.Error(err)25 panic(err)26 }27 return r28 }29 30 func (c *CsvRecord) GetString(field string) string {31 data, ok := c.Record[field]32 if ok {33 return data34 } else {35 beego.Warning("Get fileld failed! fileld:", field)36 return ""37 }38 }39 40 func LoadCsvCfg(filename string, row int) *CsvTable {41 file, err := os.Open(filename)42 if err != nil {43 beego.Error(err)44 return nil45 }46 defer file.Close()47 48 reader := csv.NewReader(file)49 if reader == nil {50 beego.Error("NewReader return nil, file:", file)51 return nil52 }53 records, err := reader.ReadAll()54 if err != nil {55 beego.Error(err)56 return nil57 }58 if len(records) < row {59 beego.Warning(filename, " is empty")60 return nil61 }62 colNum := len(records[0])63 recordNum := len(records)64 var allRecords []CsvRecord65 for i := row; i < recordNum; i++ {66 record := &CsvRecord{make(map[string]string)}67 for k := 0; k < colNum; k++ {68 record.Record[records[0][k]] = records[i][k]69 }70 allRecords = append(allRecords, *record)71 }72 var result = &CsvTable{73 filename,74 allRecords,75 }76 return result77 }
使用示例:
有一张Award表,结构如下:
定义一个结构体来表示这个配置表的一行数据
1 type AwardCfg struct {2 Id int3 Type int4 Val int5 Text string6 }
使用上面的封装解析代码如下:
var g_allAwardCfg map[int]*AwardCfgfunc LoadAwardCfg() bool { var result = LoadCsvCfg("csvmgr/award.csv", 2) if result == nil { return false } g_allAwardCfg = make(map[int]*AwardCfg) for _, record := range result.Records { id := record.GetInt("Id") aWard := &AwardCfg{ id, record.GetInt("Type"), record.GetInt("Value"), record.GetString("Text"), } g_allAwardCfg[id] = aWard } return true}
另外,用golang的CSV库解析CSV文件有特别注意一个问题,文档的格式一定要是不带BOM的UTF-8格式,不用UTF-8解析中文会乱码,带了BOM会导致第一个字段解析不出来。