使用 golang 操作 excel 表格,写了些示例代码,封装了几个常用的函数,特此记录,以备后查。
使用 excelize 库 来进行 excel 的操作,项目地址为:https://github.com/360EntSecGroup-Skylar/excelize
以下代码演示了创建 excel 表格并向其中添加数据的方法,其中用到的函数见下文。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
package main
import (
"fmt"
"strconv"
"time"
"github.com/360EntSecGroup-Skylar/excelize"
log "github.com/sirupsen/logrus"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Address string `json:"address"`
}
func main() {
users := []User{
{
ID: 1,
Name: "孔子",
Address: "山东曲阜",
},
{
ID: 2,
Name: "牛顿",
Address: "英国伦敦",
},
{
ID: 3,
Name: "凯撒",
Address: "罗马",
},
}
f := excelize.NewFile()
sheetName := "人物信息"
sheet := f.NewSheet(sheetName)
f.SetActiveSheet(sheet)
// 合并单元格
err := f.MergeCell(sheetName, "A1", "A5")
header := map[string]interface{}{"A1": "编号", "B1": "姓名", "C1":"地址"}
data := GenerateData(users, header)
err = Write2File("历史人物", sheetName, data, true)
if err != nil {
log.Errorln(err)
}
Read("/Users/wanghuan/GolandProjects/GoPath/src/github.com/xdhuxc/go-study-notes/历史人物_2019-10-22_.xlsx")
}
|
以下代码为读取 excel 表格的代码,要求:文件路径需要是绝对路径,excel 表格中不包含合并的单元格
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
func Read(fileFullPath string) {
f, err := excelize.OpenFile(fileFullPath)
if err != nil {
log.Fatal(err)
}
for sheetIndex, sheetName := range f.GetSheetMap() {
fmt.Println(sheetIndex, "--->", sheetName)
rows, err := f.Rows(sheetName)
if err != nil {
log.Errorln(err)
continue
}
for rows.Next() {
// 获取一行
cols, err := rows.Columns()
if err != nil {
log.Errorln(err)
continue
}
// 获取行数组中的值
for _, colCell := range cols {
fmt.Println(colCell)
}
}
}
}
|
我们将数据组织成 map 数组格式,每个数组元素为 excel 表格中的一行,map 中的每个键表示 excel 中的一个位置,比如A1,B2,C3等,其值为需要填充到该单元格中的值,如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
func GenerateData(users []User, header map[string]interface{}) []map[string]interface{} {
var maps []map[string]interface{}
var m map[string]interface{}
maps = append(maps, header)
rowCount := 1
for _, user := range users {
index := strconv.Itoa(rowCount)
m = map[string]interface{}{
"A"+index: user.ID,
"B"+index: user.Name,
"C"+index: user.Address,
}
maps = append(maps, m)
rowCount = rowCount + 1
}
return maps
}
|
将组织好的 map 数组写入文件中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
// 写数据到 excel 中,每个 map[string]interface{} 为一行数据,键为A1,B2,C3等等
func Write2File(fileName string, sheetName string, data []map[string]interface{}, dateContaining bool) error {
f := excelize.NewFile()
sheet := f.NewSheet(sheetName)
f.SetActiveSheet(sheet)
for _, item := range data {
for k, v := range item {
err := f.SetCellValue(sheetName, k, v)
if err != nil {
log.Errorln(err)
continue
}
}
}
// 删除 Sheet1
f.DeleteSheet("Sheet1")
if dateContaining {
return f.SaveAs(fileName + "_" + time.Now().Format("2006-01-02") + "_" + ".xlsx")
} else {
return f.SaveAs(fileName + ".xlsx")
}
}
|
使用 MergeCell 方法可以合并单元格
1
2
3
4
|
err := f.MergeCell(sheetName, "A1", "A5")
if err != nil {
log.Errorln(err)
}
|
以上代码将合并 A1~A5 的单元格,并以单元格 A5 的内容填充合并后的单元格。
https://github.com/360EntSecGroup-Skylar/excelize