237 lines
6.4 KiB
Go
237 lines
6.4 KiB
Go
package main
|
||
|
||
import (
|
||
"bytes"
|
||
"fmt"
|
||
"os"
|
||
"path/filepath"
|
||
"strings"
|
||
"text/template"
|
||
|
||
"github.com/tealeg/xlsx"
|
||
)
|
||
|
||
var XlsxFiles = make(map[string]string)
|
||
var templates *template.Template
|
||
|
||
type SheetColumnMetaStruct struct {
|
||
ColIndex int // 列序号
|
||
ColName string // 列名称
|
||
ColType int // 数据类型
|
||
CTString string // proto数据类型
|
||
IsArray bool // 是否数组
|
||
IsMap bool // 是否map
|
||
IsIndex bool // 是否建立索引
|
||
}
|
||
|
||
type SheetMetaStruct struct {
|
||
AbsPath string
|
||
FileName string
|
||
ProtoName string
|
||
Cols []*SheetColumnMetaStruct
|
||
}
|
||
|
||
const (
|
||
// xlsx标签
|
||
IntType = "(int)"
|
||
Int64Type = "(int64)"
|
||
StrType = "(str)"
|
||
ArrIntType = "(arrint)"
|
||
ArrInt64Type = "(arrint64)"
|
||
ArrStrType = "(arrstr)"
|
||
MapType = "(map)"
|
||
// xlsx索引类型,带索引
|
||
IntTypeIndex = "(int*)"
|
||
Int64TypeIndex = "(int64*)"
|
||
StrTypeIndex = "(str*)"
|
||
// proto类型
|
||
IntTypeProto = "int32"
|
||
Int64TypeProto = "int64"
|
||
StrTypeProto = "string"
|
||
MapProto = "map"
|
||
)
|
||
|
||
func Init() {
|
||
var err error
|
||
wd, err := os.Getwd()
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
protoAbsPath := filepath.Join(wd, "..", "..", "protocol")
|
||
err = os.MkdirAll(protoAbsPath, os.ModePerm)
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
xlsxAbsPath := filepath.Join(wd, "..", "..", "xlsx")
|
||
var fis []os.DirEntry
|
||
fis, err = os.ReadDir(xlsxAbsPath)
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
srvDataAbsPath := filepath.Join(wd, "..", "..", "srvdata")
|
||
err = os.MkdirAll(srvDataAbsPath, os.ModePerm)
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
for _, v := range fis {
|
||
if !v.IsDir() {
|
||
if !strings.HasSuffix(v.Name(), ".xlsx") {
|
||
continue
|
||
}
|
||
|
||
pfAbs := filepath.Join(xlsxAbsPath, v.Name())
|
||
XlsxFiles[v.Name()] = pfAbs
|
||
}
|
||
}
|
||
|
||
pattern := filepath.Join(wd, "templ", "*.templ")
|
||
funcMap := template.FuncMap{
|
||
"inc": func(n int) int {
|
||
n++
|
||
return n
|
||
},
|
||
}
|
||
//fmt.Println("templ目录:", pattern)
|
||
templates, err = template.Must(template.New("mytempl").Funcs(funcMap).ParseGlob(pattern)).Parse("")
|
||
}
|
||
|
||
func main() {
|
||
Init()
|
||
|
||
smsMap := make(map[string]*SheetMetaStruct)
|
||
for xlsxFileName, xlsxFilePath := range XlsxFiles {
|
||
xlsxFile, err := xlsx.OpenFile(xlsxFilePath)
|
||
if err != nil {
|
||
fmt.Println("excel file open error:", err, " filePath:", xlsxFilePath)
|
||
continue
|
||
}
|
||
|
||
for _, sheet := range xlsxFile.Sheets {
|
||
sms := &SheetMetaStruct{
|
||
AbsPath: xlsxFilePath,
|
||
FileName: xlsxFileName,
|
||
ProtoName: strings.TrimSuffix(xlsxFileName, ".xlsx"),
|
||
Cols: make([]*SheetColumnMetaStruct, 0, sheet.MaxCol)}
|
||
|
||
for _, row := range sheet.Rows {
|
||
for i, cell := range row.Cells {
|
||
s := cell.String()
|
||
switch {
|
||
case strings.HasSuffix(s, IntType):
|
||
sms.Cols = append(sms.Cols, &SheetColumnMetaStruct{i, strings.TrimSuffix(s, IntType), 1, IntTypeProto, false, false, false})
|
||
case strings.HasSuffix(s, StrType):
|
||
sms.Cols = append(sms.Cols, &SheetColumnMetaStruct{i, strings.TrimSuffix(s, StrType), 2, StrTypeProto, false, false, false})
|
||
case strings.HasSuffix(s, ArrIntType):
|
||
sms.Cols = append(sms.Cols, &SheetColumnMetaStruct{i, strings.TrimSuffix(s, ArrIntType), 3, IntTypeProto, true, false, false})
|
||
case strings.HasSuffix(s, Int64Type):
|
||
sms.Cols = append(sms.Cols, &SheetColumnMetaStruct{i, strings.TrimSuffix(s, Int64Type), 5, Int64TypeProto, false, false, false})
|
||
case strings.HasSuffix(s, ArrInt64Type):
|
||
sms.Cols = append(sms.Cols, &SheetColumnMetaStruct{i, strings.TrimSuffix(s, ArrInt64Type), 6, Int64TypeProto, true, false, false})
|
||
case strings.HasSuffix(s, MapType):
|
||
sms.Cols = append(sms.Cols, &SheetColumnMetaStruct{i, strings.TrimSuffix(s, MapType), 7, MapProto, false, true, false})
|
||
case strings.HasSuffix(s, IntTypeIndex):
|
||
sms.Cols = append(sms.Cols, &SheetColumnMetaStruct{i, strings.TrimSuffix(s, IntTypeIndex), 1, IntTypeProto, false, false, true})
|
||
case strings.HasSuffix(s, Int64TypeIndex):
|
||
sms.Cols = append(sms.Cols, &SheetColumnMetaStruct{i, strings.TrimSuffix(s, Int64TypeIndex), 5, Int64TypeProto, false, false, true})
|
||
case strings.HasSuffix(s, StrTypeIndex):
|
||
sms.Cols = append(sms.Cols, &SheetColumnMetaStruct{i, strings.TrimSuffix(s, StrTypeIndex), 2, StrTypeProto, false, false, true})
|
||
}
|
||
}
|
||
break //only fetch first row
|
||
}
|
||
|
||
smsMap[sms.ProtoName] = sms
|
||
break //only fetch first sheet
|
||
}
|
||
}
|
||
|
||
geneProto(smsMap)
|
||
}
|
||
|
||
func geneProto(xlsxs map[string]*SheetMetaStruct) {
|
||
if xlsxs == nil {
|
||
return
|
||
}
|
||
|
||
geneAgcHelper(xlsxs) //生成go代码 xlsx转二进制文件(.json,.dat)
|
||
geneDataStructProto(xlsxs) //生成xlsx转protobuf结构文件(pbdata.proto)
|
||
|
||
for _, val := range xlsxs {
|
||
genGoDataMgr(val) // 生成Go对象文件
|
||
}
|
||
}
|
||
|
||
// geneAgcHelper 生成go代码,读取xlsx数据
|
||
func geneAgcHelper(xlsxs map[string]*SheetMetaStruct) {
|
||
dm := map[string]interface{}{
|
||
"data": xlsxs,
|
||
"opath": filepath.Join("..", "..", "data"),
|
||
"isMapCol": isMapColumn(xlsxs),
|
||
}
|
||
outputHelper := bytes.NewBuffer(nil)
|
||
err := templates.ExecuteTemplate(outputHelper, "agc", dm)
|
||
if err != nil {
|
||
fmt.Println("geneProto ExecuteTemplate error:", err)
|
||
return
|
||
}
|
||
|
||
helperGoFile := filepath.Join("..", "xlsx2binary", "agc.go")
|
||
err = os.WriteFile(helperGoFile, outputHelper.Bytes(), os.ModePerm)
|
||
if err != nil {
|
||
fmt.Println("geneProto WriteFile error:", err)
|
||
return
|
||
}
|
||
}
|
||
|
||
// geneDataStructProto 生成xlsx的proto文件
|
||
func geneDataStructProto(xlsxs map[string]*SheetMetaStruct) {
|
||
|
||
outputHelper := bytes.NewBuffer(nil)
|
||
err := templates.ExecuteTemplate(outputHelper, "gpb", xlsxs)
|
||
if err != nil {
|
||
fmt.Println("geneDataStructProto ExecuteTemplate error:", err)
|
||
return
|
||
}
|
||
|
||
protoFile := "../../protocol/server/pbdata.proto"
|
||
err = os.WriteFile(protoFile, outputHelper.Bytes(), os.ModePerm)
|
||
if err != nil {
|
||
fmt.Println("geneDataStructProto error:", err)
|
||
}
|
||
}
|
||
|
||
// genGoDataMgr 生成go代码,读取.dat文件数据
|
||
func genGoDataMgr(sms *SheetMetaStruct) {
|
||
if sms == nil {
|
||
return
|
||
}
|
||
|
||
outputHelper := bytes.NewBuffer(nil)
|
||
err := templates.ExecuteTemplate(outputHelper, "gpb_mgr", sms)
|
||
if err != nil {
|
||
fmt.Println("genGoDataMgr ExecuteTemplate error:", err)
|
||
return
|
||
}
|
||
opath := filepath.Join("../../srvdata", strings.ToLower(fmt.Sprintf("%v.go", sms.ProtoName)))
|
||
err = os.WriteFile(opath, outputHelper.Bytes(), os.ModePerm)
|
||
if err != nil {
|
||
fmt.Println("genGoDataMgr WriteFile error:", err)
|
||
return
|
||
}
|
||
}
|
||
|
||
func isMapColumn(xlsxs map[string]*SheetMetaStruct) bool {
|
||
for _, sheet := range xlsxs {
|
||
for _, col := range sheet.Cols {
|
||
if col.IsMap {
|
||
return true
|
||
}
|
||
}
|
||
}
|
||
return false
|
||
}
|