这个案例主要是读取excel中单元格的数据
打开指定的文件(TMP_01.xlsx),读取文件内容,并输出为go的数据格式
func OpenFile(filename string, opt ...Options) (*File, error)
func (f *File) GetRows(sheet string) ([][]string, error)
func (f *File) Rows(sheet string) (*Rows, error)
func (rows *Rows) Next() bool
func (rows *Rows) Columns() ([]string, error)
rows,err := file.Rows("Sheet1")
if err != nil {
fmt.Println(err)
return
}
for rows.Next(){
s,err := rows.Columns
if err != nil {
fmt.Println(err)
return
}
fmt.Println(s) // 字符串切片,一行的所有数据
}
按行读取数据,用于循环读取每一行 与rows方法类似
func (f *File) Cols(sheet string) (*Cols, error)
func (cols *Cols) Next() bool
func (cols *Cols) Rows() ([]string, error)
指定单元格的值
func (f *File) GetCellValue(sheet, axis string) (string, error)
指定单元格的公式
func (f *File) GetCellFormula(sheet, axis string) (string, error)
指定单元格的链接
HYPERLINK 创建的链接只能通过获取公式得到
func (f *File) GetCellHyperLink(sheet, axis string) (bool, string, error)
func (f *File) GetMergeCells(sheet string) ([]MergeCell, error)
func (m *MergeCell) GetStartAxis() string
func (m *MergeCell) GetEndAxis() string
func (m *MergeCell) GetCellValue() string
合并单元格范围内的所有单元格的值都是一样的,也可以直接使用 GetCellValue 获取值
代码:main.go
package main
import (
"fmt"
"strconv"
"github.com/xuri/excelize/v2"
)
func main() {
f, err := excelize.OpenFile("../excel_files/TMP_01.xlsx")
if err != nil {
fmt.Println("打开文件失败,错误信息:", err)
return
}
// 指定sheet页数据
fmt.Println("step1")
rows, err := f.GetRows("基础的表格")
if err != nil {
fmt.Println("获取行信息失败,错误信息:", err)
return
}
// 输出为切片类型
fmt.Println(rows)
// 注意:输出的是切片,当前行有多少列数据切片的长度就是几,就是说每一行的数据个数与整个表格的没有关系
fmt.Printf("按行获取的数据类型是:%T\n", rows)
// 输出为map
var users []map[string]interface{}
// 表头数据
var columns []string = rows[0]
for _, row := range rows[1:] {
user := make(map[string]interface{}, 1)
for idx, col := range columns {
if len(row)-1 < idx {
user[col] = ""
} else {
user[col] = row[idx]
// fmt.Printf("当前单元格的数据类型是%T\n", row[idx]) // 所有的都默认是string
}
}
users = append(users, user)
}
fmt.Println(users)
fmt.Printf("数据类型是 %T\n", users)
var users2 = make([]User, 0)
for _, row := range rows[1:] {
if len(row) < 4 {
row = append(row, make([]string, 4-len(row))...)
}
u := new(User)
u.Name = row[0]
u.Gender = row[1]
age, err := strconv.ParseUint(row[2], 10, 8)
if err != nil {
fmt.Println(err)
return
}
u.Age = uint8(age)
u.Worker = row[3]
users2 = append(users2, *u)
}
fmt.Println(users2)
// 按行获取数据
fmt.Println("step2")
r, err := f.Rows("基础的表格")
if err != nil {
fmt.Println(err)
}
// 按行循环取数据
for r.Next() {
s, err := r.Columns()
if err != nil {
fmt.Println(err)
}
fmt.Println(s, len(s))
}
// 按列获取数据
fmt.Println("step3")
cols, err := f.GetCols("基础的表格")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(cols)
// 某一列去重 性别列示例
cols1 := DeduplicateSlices(cols[1][1:])
fmt.Println(cols1)
// 按列获取数据
cols2, err := f.Cols("基础的表格")
if err != nil {
fmt.Println(err)
return
}
// 循环获取每一列的数
for cols2.Next() {
r, err := cols2.Rows()
if err != nil {
fmt.Println(err)
return
}
fmt.Println(r)
}
fmt.Println("step4")
// 获取指定单元格的数据
s, err := f.GetCellValue("基础的表格", "A1")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(s)
// 获取单元格的公式
formula1, err := f.GetCellFormula("sheet2", "C1")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(formula1)
formula2, _ := f.GetCellFormula("sheet2", "C2")
fmt.Println(formula2)
fmt.Println(f.GetCellValue("sheet2", "C2"))
formula3, _ := f.GetCellFormula("sheet2", "C3")
fmt.Println(formula3)
formula4, _ := f.GetCellFormula("sheet2", "C4") // 没有公式就为空
fmt.Println(formula4)
formula5, _ := f.GetCellFormula("sheet2", "C5")
fmt.Println(formula5)
// 指定单元格的链接 返回的第一个值是判断是否是链接,第二个值是链接的目标位置,第三个是错误
ok, target, err := f.GetCellHyperLink("sheet2", "D1")
fmt.Println(ok, target, err)
if err != nil || !ok {
fmt.Println(err)
}
fmt.Println(target)
fmt.Println(f.GetCellHyperLink("sheet2", "A1"))
fmt.Println(f.GetCellHyperLink("sheet2", "D2")) // 不适用于使用HYPERLINK 公式创建的链接
fmt.Println(f.GetCellFormula("sheet2", "D2")) // HYPERLINK 创建的链接只能通过获取公式得到
// 获取合并单元格
fmt.Println("step5")
merge_cells, err := f.GetMergeCells("sheet2")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(merge_cells)
for _, c := range merge_cells {
fmt.Println(c.GetStartAxis()) // 合并单元格开始的单元格
fmt.Println(c.GetEndAxis()) // 合并单元格结束的单元格
fmt.Println(c.GetCellValue()) // 合并单元格的值
}
fmt.Println(f.GetCellValue("sheet2", "A9")) // 合并单元格的所有单元格的值都一样
fmt.Println(f.GetCellValue("sheet2", "B9"))
}
代码: func.go
package main
type User struct {
Name string `json:"name"`
Gender string `json:"gender"`
Age uint8 `json:"age"`
Worker string `json:"worker"`
}
func NewUser(name string, gender string, age uint8, worker string) *User {
return &User{
Name: name,
Age: age,
Gender: gender,
Worker: worker,
}
}
func (u *User) Work() string {
return u.Name + "目前正在从事" + u.Worker
}
// 根据中文名称获取对应的英文名称
func GetColName(col string) (t string) {
switch col {
case "姓名":
t = "Name"
case "性别":
t = "Gender"
case "工作":
t = "Worker"
case "年龄":
t = "Age"
}
return
}
// 切片去重
func DeduplicateSlices(slices []string) []string {
var tmp_map = make(map[string]uint)
for _, str := range slices {
_, ok := tmp_map[str]
if !ok {
tmp_map[str] = 1
continue
}
tmp_map[str] += 1
}
rst := make([]string, 0)
for idx := range tmp_map {
rst = append(rst, idx)
}
return rst
}
更多API请移驾作者大佬的文档 : https://xuri.me/excelize/zh-hans/
作者大佬的视频 : https://www.bilibili.com/video/BV1hU4y1F7wQ