mirror of
https://github.com/skyle1995/NetworkAuth.git
synced 2026-05-25 02:24:05 +08:00
更新底层架构
This commit is contained in:
121
utils/excel/excel.go
Normal file
121
utils/excel/excel.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package excel
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/xuri/excelize/v2"
|
||||
)
|
||||
|
||||
// ExportData 导出数据配置
|
||||
type ExportData struct {
|
||||
Headers []string // 表头显示名称列表
|
||||
Fields []string // 对应结构体字段名或Map键名
|
||||
Data interface{} // 数据源(必须是切片类型)
|
||||
Sheet string // 工作表名称,默认为 Sheet1
|
||||
}
|
||||
|
||||
// Export 生成Excel文件
|
||||
func Export(config ExportData) (*excelize.File, error) {
|
||||
f := excelize.NewFile()
|
||||
sheet := config.Sheet
|
||||
if sheet == "" {
|
||||
sheet = "Sheet1"
|
||||
}
|
||||
|
||||
// 如果不是默认Sheet1,则创建新Sheet
|
||||
index, err := f.NewSheet(sheet)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 设置表头
|
||||
for i, header := range config.Headers {
|
||||
cell, _ := excelize.CoordinatesToCellName(i+1, 1)
|
||||
f.SetCellValue(sheet, cell, header)
|
||||
}
|
||||
|
||||
// 设置表头样式(加粗、背景色)
|
||||
style, _ := f.NewStyle(&excelize.Style{
|
||||
Font: &excelize.Font{Bold: true},
|
||||
Fill: excelize.Fill{Type: "pattern", Color: []string{"#E0E0E0"}, Pattern: 1},
|
||||
})
|
||||
f.SetRowStyle(sheet, 1, 1, style)
|
||||
|
||||
// 处理数据
|
||||
val := reflect.ValueOf(config.Data)
|
||||
if val.Kind() != reflect.Slice {
|
||||
return nil, fmt.Errorf("data must be a slice")
|
||||
}
|
||||
|
||||
for i := 0; i < val.Len(); i++ {
|
||||
item := val.Index(i)
|
||||
// 如果是指针,获取其指向的值
|
||||
if item.Kind() == reflect.Ptr {
|
||||
item = item.Elem()
|
||||
}
|
||||
|
||||
rowNum := i + 2 // 从第2行开始(第1行是表头)
|
||||
|
||||
for j, field := range config.Fields {
|
||||
cellName, _ := excelize.CoordinatesToCellName(j+1, rowNum)
|
||||
var cellValue interface{}
|
||||
|
||||
// 尝试从结构体或Map中获取值
|
||||
if item.Kind() == reflect.Struct {
|
||||
fieldVal := item.FieldByName(field)
|
||||
if fieldVal.IsValid() {
|
||||
cellValue = fieldVal.Interface()
|
||||
}
|
||||
} else if item.Kind() == reflect.Map {
|
||||
key := reflect.ValueOf(field)
|
||||
mapVal := item.MapIndex(key)
|
||||
if mapVal.IsValid() {
|
||||
cellValue = mapVal.Interface()
|
||||
}
|
||||
}
|
||||
|
||||
// 特殊类型处理
|
||||
switch v := cellValue.(type) {
|
||||
case time.Time:
|
||||
if !v.IsZero() {
|
||||
f.SetCellValue(sheet, cellName, v.Format("2006-01-02 15:04:05"))
|
||||
}
|
||||
case *time.Time:
|
||||
if v != nil && !v.IsZero() {
|
||||
f.SetCellValue(sheet, cellName, v.Format("2006-01-02 15:04:05"))
|
||||
}
|
||||
default:
|
||||
f.SetCellValue(sheet, cellName, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
f.SetActiveSheet(index)
|
||||
// 如果创建了新Sheet且名字不叫Sheet1,删除默认的Sheet1
|
||||
if sheet != "Sheet1" {
|
||||
f.DeleteSheet("Sheet1")
|
||||
}
|
||||
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// Parse 读取Excel文件内容,返回二维字符串数组
|
||||
func Parse(r io.Reader) ([][]string, error) {
|
||||
f, err := excelize.OpenReader(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// 获取第一个工作表
|
||||
sheet := f.GetSheetName(0)
|
||||
rows, err := f.GetRows(sheet)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return rows, nil
|
||||
}
|
||||
Reference in New Issue
Block a user