Categorygithub.com/booyangcc/excelstructure
modulepackage
0.0.0-20240307031602-250d8adf6066
Repository: https://github.com/booyangcc/excelstructure.git
Documentation: pkg.go.dev

# README

中文文档

Introduction

excelstructure is a tool for converting between Excel and Go struct. It can convert a struct to Excel and vice versa. It also supports getting the value of a single field from a row.

Basic Usage

Installation

go get github.com/booyangcc/excelstructure

Simple Usage

infos := []*Info{
    {
        Name:    "booyang",
        Phone:   convutil.String("123456789"),
    },
}

p := NewParser()
// Because the struct fields have comment tags, the data starts from the third row when writing, so the data offset when reading is 2
p.DataIndexOffset = 2
// Write
err = p.Write("./test_excel_file/test_write.xlsx", "Infos", infos)
if err != nil {
    fmt.Println(err)
}

var newInfo []*Info
// Read
err = p.Read("./test_excel_file/test_write.xlsx", &newInfo)
if err != nil {
    fmt.Println(err)
}

Complete Example

package main

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


type Detail struct {
	Height int    `json:"height"`
	Weight int    `json:"weight"`
	Nation string `json:"nation"`
}

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;serializer:mySerializer"`
	Detail  Detail   `excel:"column:details;serializer:mySerializer"` // You can use custom serializer, default use json, here we use our custom serializer mySerializer
}

var (
	// Custom serializer
	mySerializer = Serializer{
		Marshal: func(v interface{}) (string, error) {
			bs, err := json.Marshal(v)
			if err != nil {
				return "", err
			}
			return string(bs), nil
		},
		Unmarshal: func(s string, v interface{}) error {
			return json.Unmarshal([]byte(s), v)
		},
	}
)

// TestWriteRead Usage 1, write and read to struct
func TestWriteRead() {
	infos := []*Info{
		{
			Name:    "booyang",
			Phone:   convutil.String("123456789"),
			Age:     "18",
			Man:     true,
			Address: []string{"beijing", "shanghai"},
			Detail: Detail{
				Height: 180,
				Weight: 70,
				Nation: "China",
			},
		},
		{
			Name:    "booyang1",
			Phone:   convutil.String("123456789"),
			Age:     "14",
			Man:     false,
			Address: []string{"guangzhou", "xian"},
			Detail: Detail{
				Height: 181,
				Weight: 60,
				Nation: "Britain",
			},
		},
	}
	p := NewParser()
	// Register custom serializer
	err := p.RegisterSerializer("mySerializer", mySerializer)
	if err != nil {
		return
	}
	// Write to single sheet
	err = p.Write("./test_excel_file/test_write.xlsx", "Infos", infos)
	if err != nil {
		fmt.Println(err)
	}

	/*
		// Write to two sheets, Info1 and Info2, with the same data
		err = p.WriteWithMultiSheet("./test_excel_file/test_write_multi.xlsx", map[string]interface{}{
			"Info1": infos,
			"Info2": infos,
		})
		if err != nil {
			fmt.Println(err)
		}
	*/
	// Because the struct fields have comment tags, the data starts from the third row when writing, so the data offset when reading is 2
	p.DataIndexOffset = 2
	var newInfo []*Info

	err = p.Read("./test_excel_file/test_write.xlsx", &newInfo)
	if err != nil {
		fmt.Println(err)
	}
	/*
		// Read from multiple sheets, read Info1 and Info2 to newInfo1 and newInfo2
		var newInfo1 []*Info
		var newInfo2 []*Info
		err = p.ReadWithMultiSheet("./test_excel_file/test_write_multi.xlsx", map[string]interface{}{
			"Info1": &newInfo1,
			"Info2": &newInfo2,
		})
	*/
	if err != nil {
		fmt.Println(err)
	}

	fmt.Printf("oldInfo: %+v, newInfo: %+v", infos, newInfo)
}

// TestParse Usage 2, directly get the data of a column in a row
func TestParse() {
	p := NewParser()
	// Use custom serializer
	err := p.RegisterSerializer("mySerializer", mySerializer)
	if err != nil {
		return
	}
	// Because the struct fields have comment tags, the data starts from the third row when writing, so the data offset when reading is 2
	p.DataIndexOffset = 2
	excelData, err := p.Parse("./test_excel_file/test_write.xlsx")
	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)
}

excel data output excel 输出数据

Usage

Tag Configuration

The tag name is excel. The tag field configuration is as follows:

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

  • column: the header to parse or write to Excel
  • comment: if any field in the struct contains this configuration in the excel tag, the second row of the output Excel file will be a comment
  • skip: indicates that the current field is skipped and not parsed or written to Excel
  • default: if the field is zero-value, use the default value instead
  • serializer: serialization and deserialization of structures, slices, interfaces, and other types, supporting customization, default is json serializer

Parser Usage

Parser parameters:

  • FileName: the file to read
  • DataIndexOffset: the data index offset. If the first row is a header, the offset is 1. If there is a comment occupying a row, the offset is 2. The default value is 1.
  • BoolTrueValues: the optional values for true boolean values. The default values are [true,True,TRUE,1,是,yes,Yes,YES,y,Y]. You can specify them manually.
  • IsCheckEmpty: whether to check for empty values when serializing to a struct. If a value is empty, an error is thrown.
  • IsEmptyFunc: the callback function to check for empty values. The default function is func(v string) bool {return v==""}
  • IsCoordinatesABS: the type of cell coordinate value. If true, the coordinate is A1. If false, the coordinate is 1.
  • ExcelData: the parsed data values
  • AllowFieldRepeat: whether to allow duplicate fields. If true, the fields will be overwritten.

# Functions

DefaultMarshal default marshal, json marshal.
DefaultUnmarshal default unmarshal, json unmarshal.
IsDefaultSerializer is default serializer.
NewError new error.
NewParser 传入文件名 sheetIndex从1开始 ExcelTag excel tag: ExcelField: map the excel head field ExcelDefault: if excel field is empty, use this default value.
NewSerializer new serializer, to parse excel cell data to struct field.
TestParse 使用方式二,直接获取行的某一列数据.
TestWriteRead 使用方式1,解析写入到结构体.

# Constants

JSONSerializerName json serializer name.
SerializerName serializer name.
TagName tag name.

# Variables

DefaultSerializer default serializer.
ErrorDataRowOutOfRange data row out of range.
ErrorFieldInvalid pointer field invalid.
ErrorFieldNotExist Field invalid.
ErrorFieldNotMatch Field type not match.
ErrorFieldNotSet pointer field can not set.
ErrorFieldRepeat repeat field.
ErrorFieldTypeNotSupport field type not support.
ErrorFieldValueEmpty field empty.
ErrorInOutputType output type invalid.
ErrorNoData no data.
ErrorNoSheet no sheet.
ErrorRowIndexIsHeader row index is header.
ErrorSerializerHandlerEmpty serializer handler empty.
ErrorSerializerNameRepeat serializer name repeat.
ErrorSerializerNotExist serializer not exist.
ErrorSheetName sheet name invalid.
ErrorSliceElemType elem type must struct or struct pointer.
ErrorTypePointer output not pointer.

# Structs

Cell excel cell info.
Data excel data.
No description provided by the author
Error excel structure error.
No description provided by the author
Parser parser.
No description provided by the author
SheetData sheet data.
TagSetting tag setting.

# Type aliases

MarshalFunc marshal func.
UnmarshalFunc unmarshal func.