- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2021-01-17T09:14:33+00:00","","")
#mynabvi(Go言語)
#mynavi(Go言語)
#setlinebreak(on);
* 概要 [#de109c52]
#html(<div class="pl10">)
xlsx を使用して Excel のデータ読み込みを行う。
https://github.com/tealeg/xlsx
#html(</div>)
* 目次 [#g4f66403]
#contents
* 概要 [#de109c52]
* パッケージのインストール [#t1b7468c]
#html(<div class="pl10">)
#TODO
#myterm2(){{
go get github.com/tealeg/xlsx
}}
※ github.com/tealeg/xlsx/v3 v3.2.0
#html(</div>)
* Excel作成 [#fd62442d]
#html(<div class="pl10">)
利用しているパッケージの(xlsx)の特性上、数値の int or float の判別が正確にできない為、1行目に項目名、2行目にデータ型を入力する方式とした。
sample1.xlsx
#html(){{
<div id="tabs1">
<ul>
<li><a href="#tabs1-1">Sheet1</a></li>
<li><a href="#tabs1-2">Sheet2</a></li>
</ul>
}}
#html(<div id="tabs1-1">)
| col1 | col2 | col2 | col3 |h
|float | int | string | formula |
|1.23 | 1 | abc | abc1.23 |
|4.56 | 2 | def | def4.56 |
|7.89 | 3 | ghi | ghi7.89 |
#html(</div>)
#html(<div id="tabs1-2">)
| field1 | field2 | field3 | field4 |h
| int | int | float | float |
| 1 | 4 | 1.2 | 5.6 |
| 2 | 5 | 2.3 | 7.8 |
| 3 | 6 | 3.4 | 8.9 |
#html(</div>)
#html(</div>)
#html(<script>$(function() { $("#tabs1").tabs(); });</script>)
#html(</div>)
* ソース作成 [#f9683538]
#html(<div class="pl10">)
#TODO
#mycode2(){{
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)
// }
//}
}
}}
#html(</div>)
* 動作確認 [#sffa5857]
#html(<div class="pl10">)
#TODO
#myterm2(){{
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
}}
#html(</div>)