首次提交
This commit is contained in:
53
excel/download.go
Normal file
53
excel/download.go
Normal 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
174
excel/excel.go
Normal 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
|
||||
}
|
||||
|
||||
//假设我们有一个命令行工具,比如:dir(Windows环境下列出目录内容)
|
||||
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
49
excel/tools.go
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user