Golang解析CSV

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

相關文章
相關標籤/搜索