feat:完善表格导入功能
This commit is contained in:
113
lib/excel.go
113
lib/excel.go
@ -5,6 +5,8 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/tealeg/xlsx"
|
"github.com/tealeg/xlsx"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Excel struct {
|
type Excel struct {
|
||||||
@ -12,9 +14,11 @@ type Excel struct {
|
|||||||
|
|
||||||
name string
|
name string
|
||||||
sheet string
|
sheet string
|
||||||
|
header string
|
||||||
title []string
|
title []string
|
||||||
content *ExcelContent
|
content *ExcelContent
|
||||||
//Style
|
|
||||||
|
body map[string][]map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExcelContent struct {
|
type ExcelContent struct {
|
||||||
@ -44,6 +48,12 @@ func WithExcelSheet(sheet string) OptionExcel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithExcelHeader(header string) OptionExcel {
|
||||||
|
return func(excel *Excel) {
|
||||||
|
excel.header = header
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func WithExcelTitle(title []string) OptionExcel {
|
func WithExcelTitle(title []string) OptionExcel {
|
||||||
return func(excel *Excel) {
|
return func(excel *Excel) {
|
||||||
excel.title = title
|
excel.title = title
|
||||||
@ -56,28 +66,38 @@ func WithExcelContent(content *ExcelContent) OptionExcel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithExcelStyle() OptionExcel {
|
|
||||||
return func(excel *Excel) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Export 导出
|
// Export 导出
|
||||||
func (this *Excel) Export() error {
|
func (this *Excel) Export() error {
|
||||||
this.File = xlsx.NewFile()
|
this.File = xlsx.NewFile()
|
||||||
sheet, _ := this.File.AddSheet(this.sheet)
|
sheet, _ := this.File.AddSheet(this.sheet)
|
||||||
row := sheet.AddRow()
|
row := new(xlsx.Row)
|
||||||
cell := new(xlsx.Cell)
|
cell := new(xlsx.Cell)
|
||||||
|
|
||||||
style := &xlsx.Style{
|
style := xlsx.NewStyle()
|
||||||
//Fill: *xlsx.NewFill("solid", "EFEFDE", "EFEFDE"),
|
|
||||||
Border: xlsx.Border{RightColor: "FF"},
|
style.Alignment = xlsx.Alignment{
|
||||||
|
Horizontal: "center",
|
||||||
|
Vertical: "center",
|
||||||
|
}
|
||||||
|
if this.header != "" {
|
||||||
|
row = sheet.AddRow()
|
||||||
|
row.SetHeight(28.0)
|
||||||
|
cell = row.AddCell()
|
||||||
|
cell.HMerge = 1 // 横向合并
|
||||||
|
//cell.VMerge = 1 // 纵向合并
|
||||||
|
cell.Value = this.header
|
||||||
|
cell.SetStyle(style)
|
||||||
|
|
||||||
|
if this.title != nil && len(this.title) > 0 {
|
||||||
|
cell.HMerge = len(this.title) - 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if this.title != nil && len(this.title) > 0 {
|
if this.title != nil && len(this.title) > 0 {
|
||||||
|
row = sheet.AddRow()
|
||||||
|
|
||||||
for _, v := range this.title {
|
for _, v := range this.title {
|
||||||
cell = row.AddCell()
|
cell = row.AddCell()
|
||||||
cell.Value = v
|
cell.Value = v
|
||||||
cell.SetStyle(style)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if this.content != nil {
|
if this.content != nil {
|
||||||
@ -114,6 +134,41 @@ func (this *Excel) Export() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Import 导入
|
||||||
|
// @file:文件信息
|
||||||
|
// @headers:标题数量
|
||||||
|
func (this *Excel) Import(file string, headers int) error {
|
||||||
|
_file, err := xlsx.OpenFile(file)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
out := make(map[string][]map[string]string, 0)
|
||||||
|
// 循环Sheet
|
||||||
|
for _, sheet := range _file.Sheets {
|
||||||
|
data := make([]map[string]string, 0)
|
||||||
|
|
||||||
|
local := 0
|
||||||
|
|
||||||
|
if headers > 0 {
|
||||||
|
local += headers
|
||||||
|
}
|
||||||
|
for i := local + 1; i < len(sheet.Rows); i++ {
|
||||||
|
body := sheet.Rows[i].Cells
|
||||||
|
_data := make(map[string]string, 0)
|
||||||
|
|
||||||
|
for key, cell := range sheet.Rows[local].Cells {
|
||||||
|
_data[cell.String()] = body[key].String()
|
||||||
|
}
|
||||||
|
data = append(data, _data)
|
||||||
|
}
|
||||||
|
out[sheet.Name] = data
|
||||||
|
}
|
||||||
|
this.body = out
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Save 保存
|
// Save 保存
|
||||||
func (this *Excel) Save(path string) error {
|
func (this *Excel) Save(path string) error {
|
||||||
return this.File.Save(this.name + ".xlsx")
|
return this.File.Save(this.name + ".xlsx")
|
||||||
@ -132,6 +187,40 @@ func (this *Excel) Save(path string) error {
|
|||||||
//return this.Save(fmt.Sprintf("%s\%s.xlsx", path, this.name))
|
//return this.Save(fmt.Sprintf("%s\%s.xlsx", path, this.name))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Analysis 解析
|
||||||
|
func (this *Excel) Analysis(sheet string, src interface{}) error {
|
||||||
|
for k, v := range this.body["专家信息"][0] {
|
||||||
|
|
||||||
|
tRef := reflect.TypeOf(src).Elem()
|
||||||
|
|
||||||
|
fieldNum := tRef.NumField()
|
||||||
|
|
||||||
|
for i := 0; i < fieldNum; i++ {
|
||||||
|
// 匹配结构字段名称
|
||||||
|
if k != strings.ToLower(tRef.Field(i).Tag.Get("xlsx")) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
vRef := reflect.ValueOf(src).Elem().FieldByName(tRef.Field(i).Name)
|
||||||
|
|
||||||
|
if !vRef.CanSet() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch vRef.Type().String() {
|
||||||
|
case "string":
|
||||||
|
vRef.SetString(v)
|
||||||
|
break
|
||||||
|
case "int", "int64":
|
||||||
|
vRef.SetInt(utils.StringToInt64(v))
|
||||||
|
break
|
||||||
|
case "uint", "uint64":
|
||||||
|
vRef.SetUint(utils.StringToUnit64(v))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func NewExcel(options ...OptionExcel) *Excel {
|
func NewExcel(options ...OptionExcel) *Excel {
|
||||||
out := new(Excel)
|
out := new(Excel)
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ func TestNewExcel(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
excel := NewExcel(WithExcelName("测试"), WithExcelSheet("专家信息"),
|
excel := NewExcel(WithExcelName("测试"), WithExcelSheet("专家信息"),
|
||||||
|
WithExcelHeader("人员信息"),
|
||||||
WithExcelTitle([]string{"姓名", "年龄"}), WithExcelContent(&ExcelContent{
|
WithExcelTitle([]string{"姓名", "年龄"}), WithExcelContent(&ExcelContent{
|
||||||
Kind: 0,
|
Kind: 0,
|
||||||
Content: content,
|
Content: content,
|
||||||
@ -24,3 +25,22 @@ func TestNewExcel(t *testing.T) {
|
|||||||
err = excel.Save("./lib")
|
err = excel.Save("./lib")
|
||||||
t.Log(err)
|
t.Log(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Data struct {
|
||||||
|
Name string `json:"name" xlsx:"姓名"`
|
||||||
|
Age int `json:"age" xlsx:"年龄"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewExcelImport(t *testing.T) {
|
||||||
|
excel := NewExcel()
|
||||||
|
|
||||||
|
err := excel.Import("测试.xlsx", 1)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Log(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data := new(Data)
|
||||||
|
excel.Analysis("", data)
|
||||||
|
t.Log(data)
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user