Golang的csv库支持解析csv文件,导入encoding/csv就能够用了,但自己不太好用,特别是当CSV表列的顺序被打乱后,还得改动代码里面对应列在解析出的数据的索引,因此就这两个问题,简单封装了下,使之用起来更加方便,代码以下:git
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 string 13 Records []CsvRecord 14 } 15 16 type CsvRecord struct { 17 Record map[string]string 18 } 19 20 func (c *CsvRecord) GetInt(field string) int { 21 var r int 22 var err error 23 if r, err = strconv.Atoi(c.Record[field]); err != nil { 24 beego.Error(err) 25 panic(err) 26 } 27 return r 28 } 29 30 func (c *CsvRecord) GetString(field string) string { 31 data, ok := c.Record[field] 32 if ok { 33 return data 34 } 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 nil 45 } 46 defer file.Close() 47 48 reader := csv.NewReader(file) 49 if reader == nil { 50 beego.Error("NewReader return nil, file:", file) 51 return nil 52 } 53 records, err := reader.ReadAll() 54 if err != nil { 55 beego.Error(err) 56 return nil 57 } 58 if len(records) < row { 59 beego.Warning(filename, " is empty") 60 return nil 61 } 62 colNum := len(records[0]) 63 recordNum := len(records) 64 var allRecords []CsvRecord 65 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 result 77 }
使用示例:github
有一张Award表,结构以下:golang
定义一个结构体来表示这个配置表的一行数据app
1 type AwardCfg struct { 2 Id int 3 Type int 4 Val int 5 Text string 6 }
使用上面的封装解析代码以下:spa
var g_allAwardCfg map[int]*AwardCfg func 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会致使第一个字段解析不出来。code