概要 †xlsx を使用して Excel のデータ読み込みを行う。 目次 †パッケージのインストール †go get github.com/tealeg/xlsx ※ github.com/tealeg/xlsx/v3 v3.2.0 Excel作成 †利用しているパッケージの(xlsx)の特性上、数値の int or float の判別が正確にできない為、1行目に項目名、2行目にデータ型を入力する方式とした。 sample1.xlsx ソース作成 †package main import ( "fmt" "errors" "github.com/tealeg/xlsx/v3" ) func ReadSheets(filePath string) (map[string][]map[string]interface{}, error){ data := make(map[string][]map[string]interface{}) wb, err := xlsx.OpenFile(filePath) if err != nil { return data, err } // シート名の一覧 for _, sh := range wb.Sheets { //sh.Close() sheetData, err := ReadSheet(filePath, sh.Name) if err != nil { return data, nil } data[sh.Name] = sheetData } return data, nil } func ReadSheet(filePath string, sheetName string) ([]map[string]interface{}, error){ rows := make([]map[string]interface{}, 0) wb, err := xlsx.OpenFile(filePath) if err != nil { return rows, err } sh, ok := wb.Sheet[sheetName] if !ok { return rows, errors.New(fmt.Sprintf("Sheet %s does not exist", sheetName)) } defer sh.Close() colNames := make([]string, 0) getColNames := func(c *xlsx.Cell) error { value, err := c.FormattedValue() if err != nil { return err } colNames = append(colNames, value) return nil } typeNames := make([]string, 0) getTypeNames := func(c *xlsx.Cell) error { value, err := c.FormattedValue() if err != nil { return err } typeNames = append(typeNames, value) return nil } getValues := func(c *xlsx.Cell) error { value, err := c.FormattedValue() if err != nil { return err } cellNo, rowNo := c.GetCoordinates() rowNo = rowNo - 2 if len(rows) < rowNo + 1 { rec := make(map[string]interface{}) rows = append(rows, rec) } colname := colNames[cellNo] rec := &(rows[rowNo]) if typeNames[cellNo] == "int" { intVal, _ := c.Int64() (*rec)[colname] = intVal } else if typeNames[cellNo] == "float" { floatVal, _ := c.Float() (*rec)[colname] = floatVal } else { (*rec)[colname] = value } return nil } for i := 0; i < sh.MaxRow; i++ { r, err := sh.Row(i) if err != nil { break } if i == 0 { r.ForEachCell(getColNames) } else if i == 1 { r.ForEachCell(getTypeNames) } else { r.ForEachCell(getValues) } } return rows, nil } func main(){ filePath := "/path/to/sample1.xlsx" data, err := ReadSheets(filePath) if err != nil { fmt.Printf("Error! %v", err) panic(err) } // 全シート読み込み for sheetName, rows := range data { fmt.Printf("### %s ###\n", sheetName) for i, rec := range rows { for colname, colvalue := range rec { fmt.Printf("%d, %v: %v\n", i, colname, colvalue) } } } // シート名を指定して読み込み //rows, err := ReadSheet(filePath, sheetName) //for i, rec := range rows { // for colname, colvalue := range rec { // fmt.Printf("%d, %v: %v\n", i, colname, colvalue) // } //} } 動作確認 †go run main.go ### Sheet1 ### 0, col2: abc 0, col3: abc1.23 0, col1: 1.23 1, col1: 4.56 1, col2: def 1, col3: def4.56 2, col1: 7.89 2, col2: ghi 2, col3: ghi7.89 ### Sheet2 ### 0, field1: 1 0, field2: 4 0, field3: 1.2 0, field4: 5.6 1, field4: 7.8 1, field1: 2 1, field2: 5 1, field3: 2.3 2, field3: 3.4 2, field4: 8.9 2, field1: 3 2, field2: 6 |