首次提交

This commit is contained in:
ayflying
2024-12-23 12:00:41 +08:00
commit 2006e9eef8
18 changed files with 1357 additions and 0 deletions

53
excel/download.go Normal file
View File

@@ -0,0 +1,53 @@
package excel
import (
"context"
"fmt"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"github.com/xuri/excelize/v2"
)
func Data2Excel(ctx context.Context, data []map[string]interface{}) (file string) {
// 创建一个新的 Excel 文件
f := excelize.NewFile()
var sheetName = "Sheet1"
f.NewSheet(sheetName)
//// 准备数据
//data = []map[string]interface{}{
// {"Name": "Alice", "Age": 30, "City": "New York"},
// {"Name": "Bob", "Age": 25, "City": "Los Angeles"},
// {"Name": "Charlie", "Age": 35, "City": "Chicago"},
//}
//写入头部
var colIndex = 0
var headers []string
for header := range data[0] {
//追加头部名字
headers = append(headers, header)
cell, _ := excelize.CoordinatesToCellName(colIndex+1, 1) // 表头在第一行
f.SetCellValue(sheetName, cell, header)
colIndex++
}
// 写入数据
for rowIndex, record := range data {
for colIndex, header := range headers {
cell, _ := excelize.CoordinatesToCellName(colIndex+1, rowIndex+2) // 数据从第二行开始
f.SetCellValue(sheetName, cell, record[header]) // 通过表头获取数据
}
}
// 保存 Excel 文件
saveName := fmt.Sprintf("runtime/uploads/out_%v.xlsx", gtime.Now().Nanosecond())
if err := f.SaveAs(saveName); err != nil {
g.Log().Fatal(ctx, err)
}
//下载excel
//g.RequestFromCtx(ctx).Response.ServeFileDownload(saveName)
return saveName
}

174
excel/excel.go Normal file
View File

@@ -0,0 +1,174 @@
package excel
import (
"context"
"github.com/ayflying/excel2json"
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
"path"
"strconv"
"strings"
"time"
)
type FileItem struct {
Name string `json:"name" dc:"配置文件名"`
Filename string `json:"filename" dc:"文件名"`
Tabs []string `json:"tabs" dc:"页签"`
Items []string `json:"items" dc:"道具字段"`
ItemsMap []string `json:"items_map" dc:"道具字段map格式"`
Slice map[string]string `json:"slice" dc:"切片"`
}
type Excel struct {
Header int //表头行数
Key int //key列
}
func New(header int, key int) *Excel {
return &Excel{
Header: header,
Key: key,
}
}
func (s *Excel) ExcelLoad(ctx context.Context, fileItem *FileItem, mainPath string) (runTime time.Duration) {
startTime := gtime.Now()
filepath := path.Join("manifest/game", fileItem.Name)
//如果filepath文件不存在跳过
if !gfile.Exists(path.Join(mainPath, fileItem.Filename)) {
return
}
//假设我们有一个命令行工具比如dirWindows环境下列出目录内容
var tempJson []interface{}
for k, v2 := range fileItem.Tabs {
sheet := v2
if k == 0 {
sheet = v2
}
//导出json
excel2json.Excel(path.Join(mainPath, fileItem.Filename),
filepath, s.Header, s.Key, sheet)
//如果配置了道具字段,则进行转换
//g.Log().Info(ctx, "当前任务表=%v,items=%v", v.Name, v.Items)
fileBytes := gfile.GetBytes(filepath)
arr, _ := gjson.DecodeToJson(fileBytes)
list := arr.Array()
//格式化item格式
if len(fileItem.Items) > 0 {
list = s.itemsFormat(list, fileItem.Items)
}
if len(fileItem.ItemsMap) > 0 {
list = s.itemsMapFormat(list, gconv.Strings(fileItem.ItemsMap))
}
//格式化切片修改
if len(fileItem.Slice) > 0 {
list = s.sliceFormat(list, fileItem.Slice)
}
//拼接json
tempJson = append(tempJson, list...)
fileBytes, _ = gjson.MarshalIndent(tempJson, "", "\t")
err := gfile.PutBytes(filepath, fileBytes)
if err != nil {
g.Log().Error(ctx, err)
}
}
runTime = gtime.Now().Sub(startTime)
return
}
func (s *Excel) itemsFormat(list []interface{}, Items []string) []interface{} {
for k2, v2 := range list {
for k3, v3 := range v2.(g.Map) {
if gstr.InArray(Items, k3) {
if _, ok := v3.(string); ok {
list[k2].(g.Map)[k3] = s.Spilt2Item(v3.(string))
} else {
g.Log().Errorf(gctx.New(), "当前类型断言失败:%v,list=%v", v3, v2)
}
}
}
}
return list
}
func (s *Excel) itemsMapFormat(list []interface{}, Items []string) []interface{} {
for k2, v2 := range list {
for k3, v3 := range v2.(g.Map) {
if gstr.InArray(Items, k3) {
if _, ok := v3.(string); ok {
get := s.Spilt2Item(v3.(string))
list[k2].(g.Map)[k3] = s.Items2Map(get)
} else {
g.Log().Errorf(gctx.New(), "当前类型断言失败:%v,list=%v", v3, v2)
}
}
}
}
return list
}
func (s *Excel) sliceFormat(list []interface{}, Slice map[string]string) []interface{} {
for s1, s2 := range Slice {
for k2, v2 := range list {
for k3, v3 := range v2.(g.Map) {
//判断是否存在
if s1 != k3 {
continue
}
if gconv.String(v3) == "" {
list[k2].(g.Map)[k3] = []string{}
continue
}
var parts []string
//断言是否成功
if get, ok := v3.(string); !ok {
//g.Log().Errorf(gctx.New(), "当前类型断言失败:%v", v3)
parts = []string{gconv.String(v3)}
continue
} else {
parts = strings.Split(get, "|") // 分割字符串
}
switch s2 {
case "int":
var temp = make([]int, len(parts))
for k, v := range parts {
temp[k], _ = strconv.Atoi(v)
}
list[k2].(g.Map)[k3] = temp
case "int64":
var temp = make([]int64, len(parts))
for k, v := range parts {
temp[k], _ = strconv.ParseInt(v, 10, 64)
}
case "float64":
var temp = make([]float64, len(parts))
for k, v := range parts {
temp[k], _ = strconv.ParseFloat(v, 64)
}
list[k2].(g.Map)[k3] = temp
default:
list[k2].(g.Map)[k3] = parts
}
}
}
}
return list
}

49
excel/tools.go Normal file
View File

@@ -0,0 +1,49 @@
package excel
import (
"github.com/xuri/excelize/v2"
"log"
"strconv"
"strings"
)
// Excel2Slice 读取excel文件导入为切片
func Excel2Slice(filePath string, _sheet ...string) [][]string {
excelObj, err := excelize.OpenFile(filePath)
if err != nil {
log.Fatalf("无法打开Excel文件: %v", err)
}
defer excelObj.Close()
var sheet string
if len(_sheet) == 0 {
sheet = excelObj.GetSheetList()[0]
} else {
sheet = _sheet[0]
}
res, err := excelObj.GetRows(sheet)
return res
}
// 字符串转道具类型
func (s *Excel) Spilt2Item(str string) (result [][]int64) {
parts := strings.Split(str, "|") // 分割字符串
for i := 0; i < len(parts)-1; i += 2 {
num1, _ := strconv.ParseInt(parts[i], 10, 64)
num2, _ := strconv.ParseInt(parts[i+1], 10, 64)
pair := []int64{num1, num2}
result = append(result, pair)
}
return
}
// 道具格式转map
func (s *Excel) Items2Map(items [][]int64) (list map[int64]int64) {
list = make(map[int64]int64)
for _, v := range items {
list[v[0]] = v[1]
}
return
}