可能是golang最好的excel转struct, struct转excel的库

652 阅读2分钟

excelstructure是一个能够将excel解析到struct,同时将struct解析到excel库。 支持注释,字段忽略,默认值赋值等特性,库地址 github.com/booyangcc/e…

安装

go get github.com/booyangcc/excelstructure

样例

package main

import (
    "fmt"
    "github.com/booyangcc/utils/convutil"
    "github.com/booyangcc/excelstructure"
)

type Info struct {
    Name    string  `excel:"column:user_name;comment:person name"`
    Phone   *string `excel:"column:phone;comment:phone number"`
    Age     string  `excel:"column:age;"`
    Man     bool    `excel:"column:man;default:true"`
    Address string  `excel:"column:address;skip"` // skip this field
}

var (
    infos = []*Info{
        {
            Name:    "booyang",
            Phone:   convutil.String("123456789"),
            Age:     "18",
            Man:     true,
            Address: "beijing",
        },
        {
            Name:    "booyang1",
            Phone:   convutil.String("123456789"),
            Age:     "14",
            Man:     false,
            Address: "shanghai",
        },
    }
)

func TestWriteRead() {
    p := excelstructure.NewParser("./test_write.xlsx")
    err := p.Write(infos)  
    if err != nil {  
        fmt.Println(err)  
    }  

    // because the struct field has comment tag, so the comment has been written to row 2, so when read, data offset is 2  
    p.DataIndexOffset = 2  
    var newInfo []*Info  
    err = p.Read(&newInfo)  
    if err != nil {  
        fmt.Println(err)  
    }  
    fmt.Printf("oldInfo: %+v, newInfo: %+v", infos, newInfo)
}

func TestParse() {
    p := excelstructure.NewParser("./test_write.xlsx")
    p.DataIndexOffset = 2  
    excelData, err := p.Parse()  
    if err != nil {  
    fmt.Println(err)  
    }  

    s := excelData.SheetNameData["Infos"]  
    row3UserName, err := s.GetStringValue(3, "user_name")  
    if err != nil {  
    fmt.Println(err)  
    }  

    row3age, err := s.GetIntValue(3, "age")  
    if err != nil {  
    fmt.Println(err)  
    }  
    fmt.Println(row3UserName, row3age)  

    row4UserName, err := s.GetStringValue(4, "user_name")  
    if err != nil {  
    fmt.Println(err)  
    }  

    row4age, err := s.GetIntValue(4, "age")  
    if err != nil {  
    fmt.Println(err)  
    }  
    fmt.Println(row4UserName, row4age)
}

输出

image.png

使用

tag配置

tag字段设置,tag名称excel

Name string excel:"column:user_name;comment:person name;skip;default:boo"

  • column:解析或写入excel的head头
  • comment:任意一结构体的字段exceltag 包含了这个配置,则输出excel的时候第二行为comment
  • skip:标注当前字段跳过,不解析也不写入excel
  • default:解析或设置如果字段为零值则使用default替换

writer使用

    w := excelstructure.NewWriter("./test_write.xlsx")
    err := w.Write(infos)
    if err != nil {
            fmt.Println(err)
    }

read使用

reader参数

  • FileName 读的文件
  • DataIndexOffset 数据索引偏移量,第一行可能为表头,则偏移量为1,如果有注释占用一行,则为2。默认为1
  • BoolTrueValues bool值为true的可选项,默认为[true,True,TRUE,1,是,yes,Yes,YES,y,Y]。使用时可以手动指定
  • IsCheckEmpty 序列化到结构提的时候是否检测空值如果为空值则报错
  • IsEmptyFunc 检测是否为空的回调函数,默认为 func(v string) bool {return v==""}
  • IsCoordinatesABS cell坐标值类型 ,ture返回坐标A1, false为AA1
  • ExcelData 解析出来的数据值
  • AllowFieldRepeat 是否允许重复字段允许则覆盖

使用方式一,直接解析到结构体

r := excelstructure.NewReader("./test_excel_file/test_write.xlsx")
// because the struct field has comment tag, so the comment has been written to row 2, so when read, data offset is 2
r.DataIndexOffset = 2
var newInfo []*Info
err = r.Read(&newInfo)
if err != nil {
        fmt.Println(err)
}

使用方式二,获取单行某个字段的值

p := NewParser("./test_write.xlsx")  
// because the struct field has comment tag, so the comment has been written to row 2, so when read, data offset is 2  
p.DataIndexOffset = 2  
excelData, err := p.Parse()  
if err != nil {  
fmt.Println(err)  
}  
  
s := excelData.SheetNameData["Infos"]  
row3UserName, err := s.GetStringValue(3, "user_name")  
if err != nil {  
fmt.Println(err)  
}  
  
row3age, err := s.GetIntValue(3, "age")  
if err != nil {  
fmt.Println(err)  
}  
fmt.Println(row3UserName, row3age)