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