一個自己實現的Excel as relate db讀取庫go-excel

yhf_szb發表於2017-09-18

在複雜的系統中(例如遊戲),有時候為了便於非專業人員(策劃)設定一些配置,會使用Excel作為一種輕量級的關聯式資料庫或者配置檔案,畢竟對於很多非開發人員來說,配個Excel要比寫json或者yaml什麼簡單得多。

而且Excel可以寫入各種格式和字型標紅單元格,維護成本大大降低。

這種場景下,讀取特定格式(符合關聯式資料庫特點的表格)的資料會比各種花式寫入Excel的功能更重要,畢竟從編輯上來說微軟提供的Excel本身功能就非常強大了,而現在我找到的Excel庫的功能都過於強大了,用起來有點浪費,於是寫了這個簡化庫。

這個庫的工作參考了tealeg/xlsx的部分實現和讀取邏輯。

假設有一個xlsx檔案,裡邊有個Sheet叫“Standard”,它的資料結構如下:

ID NameOf Age Slice UnmarshalString
1 Andy 1 1|2 {"Foo":"Andy"}
2 Leo 2 2|3|4 {"Foo":"Leo"}
3 Ben 3 3|4|5|6 {"Foo":"Ben"}
4 Ming 4 1 {"Foo":"Ming"}
  • 第0行是標題行。
  • 第1行開始是資料行。

以下是最簡單的寫法

// defined a struct
type Standard struct {
    // use field name as default column name
    ID            int
    // column means to map the column name
    Name      string `xlsx:"column(NameOf)"`
    // you can map a column into more than one field
    NamePtr *string `xlsx:"column(NameOf)"`
    // omit `column` if only want to map to column name, it's equal to `column(AgeOf)`
    Age         int     `xlsx:"AgeOf"`
    // split means to split the string into slice by the `|`
    Slice       []int `xlsx:"split(|)"`
    // *Temp implement the `encoding.BinaryUnmarshaler`
    Temp      *Temp `xlsx:"column(UnmarshalString)"`
    // use '-' to ignore.
    Ignored   string `xlsx:"-"`
}

// func (this Standard) GetXLSXSheetName() string {
//  return "Some other sheet name if need"
// }

type Temp struct {
    Foo string
}

// self define a unmarshal interface to unmarshal string.
func (this *Temp) UnmarshalBinary(d []byte) error {
    return json.Unmarshal(d, this)
}

func main() {
    // will assume the sheet name as "Standard" from the struct name.
    var stdList []Standard
    err := excel.UnmarshalXLSX("./testdata/simple.xlsx", &stdList)
    if err != nil {
        panic(err)
    }
}

提供一些更復雜的讀取邏輯,詳細看文件:https://github.com/szyhf/go-excel

時間關係,可能看test目錄裡的程式碼更好理解……

歡迎捉蟲提bug。

相關文章