225 lines
5.8 KiB
Go
225 lines
5.8 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
|
||
IsArray bool
|
||
IsMap bool
|
||
}
|
||
|
||
type SheetMetaStruct struct {
|
||
AbsPath string
|
||
FileName string
|
||
ProtoName string
|
||
Cols []*SheetColumnMetaStruct
|
||
}
|
||
|
||
const (
|
||
INTTYPE string = "(int)"
|
||
INT64TYPE string = "(int64)"
|
||
STRTYPE = "(str)"
|
||
ARRINTTYPE = "(arrint)"
|
||
ARRINT64TYPE = "(arrint64)"
|
||
ARRSTRTYPE = "(arrstr)"
|
||
INTTYPE_PROTO = "int32"
|
||
INT64TYPE_PROTO = "int64"
|
||
STRTYPE_PROTO = "string"
|
||
MAPTYPE string = "(map)"
|
||
MAP_PROTO = "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, "..", "code")
|
||
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()
|
||
if strings.HasSuffix(s, INTTYPE) {
|
||
sms.Cols = append(sms.Cols, &SheetColumnMetaStruct{i, strings.TrimSuffix(s, INTTYPE), 1, INTTYPE_PROTO, false, false})
|
||
} else if strings.HasSuffix(s, STRTYPE) {
|
||
sms.Cols = append(sms.Cols, &SheetColumnMetaStruct{i, strings.TrimSuffix(s, STRTYPE), 2, STRTYPE_PROTO, false, false})
|
||
} else if strings.HasSuffix(s, ARRINTTYPE) {
|
||
sms.Cols = append(sms.Cols, &SheetColumnMetaStruct{i, strings.TrimSuffix(s, ARRINTTYPE), 3, INTTYPE_PROTO, true, false})
|
||
} else if strings.HasSuffix(s, ARRSTRTYPE) {
|
||
sms.Cols = append(sms.Cols, &SheetColumnMetaStruct{i, strings.TrimSuffix(s, ARRSTRTYPE), 4, STRTYPE_PROTO, true, false})
|
||
} else if strings.HasSuffix(s, INT64TYPE) {
|
||
sms.Cols = append(sms.Cols, &SheetColumnMetaStruct{i, strings.TrimSuffix(s, INT64TYPE), 5, INT64TYPE_PROTO, false, false})
|
||
} else if strings.HasSuffix(s, ARRINT64TYPE) {
|
||
sms.Cols = append(sms.Cols, &SheetColumnMetaStruct{i, strings.TrimSuffix(s, ARRINT64TYPE), 6, INT64TYPE_PROTO, true, false})
|
||
} else if strings.HasSuffix(s, MAPTYPE) {
|
||
sms.Cols = append(sms.Cols, &SheetColumnMetaStruct{i, strings.TrimSuffix(s, MAPTYPE), 7, MAP_PROTO, 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("../code", 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
|
||
}
|