admin管理员组文章数量:1565357
游戏开发中,经常会遇见各式各样的配置表,不同的字段,加上不同的类型,组成的策划们所需要的配置表,但为了达到版本内容,往往配置表格式变化反复无穷。因为在经过数个游戏项目的摧残之后,我们总结了一套比较实用的配置表生成工具。基本原理是约定一套excel格式,然后制定多种生成函数的格式,然后根据需要生成指定语言格式的文件模块。
以下是这套工具的详细约定:
1.目录列表:
2:Configs目录。这里存放的是设置文档 Setting.cfg。
{
"app_set": {},
"path_set": {
"erl_path": "E:\\workplace\\erlang_java\\Auto_Data\\Erlang\\data",
"hrl_path": "E:\\workplace\\erlang_java\\Auto_Data\\Erlang\\include",
"excel_path": "E:\\workplace\\erlang_java\\Auto_Data\\Excels"
}
}
3.Erlang目录。这里存放的是生成指定语言格式的文件模块,也可以更换为其他语言格式,或者新建目录,然后格式填写在Setting.cfg中。
4.Excels目录。这里存放的是配置表文件。
配置表列表
data数据工作表
上图中各行的约定是:
1)第一行为中文注释名
2)第二行为英文翻译名
3)第三行为数据类型,数据类型支持 int、float、string、json
4)第四行为数据引用表与字段,即该字段下数据必须存在与引用表中
5)第五行为前端是否导出,0|不填:导出;1:不导出
6)第六行为后端是否导出,0|不填:导出;1:不导出
config配置工作表
上图中各个字段的约定是:
1)type:生成的语言格式模块。如上图 erl,则会生成 xxx.erl
2)fun_name:生成的函数名
3)keys:函数引用参数字段。需要使用中括号圈起来
4)vals:函数导出参数字段。需要使用中括号圈起来
5.PyPlace目录。这里存放的是python 代码模块。
模块列表
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 文件名:main.py
# author:zhlhudson
# 这个模块适用于自动编译配置
from csv import excel
from excel_pkg import excel_common
import excel_gui
def main():
print(dir(excel_common))
excel_gui.excel_gui_main()
return
if __name__ == "__main__":
main()
pass
主模块
# coding=utf-8
# 文件名:excel_gui.py
# author:zhlhudson
import os
import wx
import re
from excel_pkg import excel_common as ec
import excel_ruler
class excelizer_frame(wx.Frame):
def __init__(self, maxSizeWeight, maxSizeHeight):
self.maxSizeWeight = maxSizeWeight
self.maxSizeHeight = maxSizeHeight
self.maxSize = (self.maxSizeWeight, self.maxSizeHeight)
super().__init__(parent=None, title="wxPython", size=self.maxSize)
self.SetMaxSize(self.maxSize)
self.SetMinSize(self.maxSize)
# 设置界面
class excelizer_setting(excelizer_frame):
def __init__(self, parent):
self.maxSizeWeight = 800
self.maxSizeHeight = 500
super().__init__(self.maxSizeWeight, self.maxSizeHeight)
self.parent = parent
self.setting = ec.load_setconfig()
self.set_panel = wx.Panel(self)
path_set = self.setting['path_set']
text_size = (self.maxSizeWeight/2, 24)
btn_size = (120, 24)
# 按钮坐标偏移量
btn_x_offset = 20
for key_index in range(len(path_set.keys())):
set_key = list(path_set.keys())[key_index]
btn_path = path_set[set_key]
self.btn_layout(key_index, set_key, btn_path, text_size, btn_size, btn_x_offset)
self.Center()
# 设置按钮布局
def btn_layout(self, _id, set_key, btn_path, text_size, btn_size, btn_x_offset):
btn_y = 10 + _id * 30
path_text = wx.TextCtrl(self.set_panel, id=200+_id, style=wx.TE_LEFT | wx.TE_READONLY,
size=text_size, pos=(10, btn_y))
path_text.AppendText(set_key + " : " + btn_path)
erl_path_btn = wx.Button(self.set_panel, id=1000+_id, label=u"修改路径",
size=btn_size, pos=(self.maxSizeWeight / 2 + btn_x_offset, btn_y))
# lambda 方法增加按钮事件参数
erl_path_btn.Bind(wx.EVT_BUTTON, lambda e, pt=path_text, sk=set_key: self.btn_event(e, pt, sk))
pass
# 按钮事件
def btn_event(self, event, path_text, set_key):
print("打印测试。。。。。sss")
dlg = wx.DirDialog(self, u"选择文件夹", defaultPath=self.setting['path_set'][set_key],
style=wx.DD_DEFAULT_STYLE)
if dlg.ShowModal() == wx.ID_OK:
self.setting['path_set'][set_key] = dlg.GetPath()
ec.reset_setconfig(self.setting)
path_text.Clear()
path_text.AppendText(set_key + " : " + self.setting['path_set'][set_key])
dlg.Destroy()
pass
def Destroy(self):
print("销毁设置面板...")
self.parent.Thaw()
self.parent.set_frame = None
super().Destroy()
return False
# 主界面
class excelizer_main(excelizer_frame):
def __init__(self):
self.maxSizeWeight = 1024
self.maxSizeHeight = 760
super().__init__(self.maxSizeWeight, self.maxSizeHeight)
# 菜单栏
menubar = wx.MenuBar()
menu_file = wx.Menu()
menu_set = wx.Menu()
menu_about = wx.Menu()
menubar.Append(menu_file, u"菜单")
menubar.Append(menu_set, u"设置")
menubar.Append(menu_about, u"关于")
menu_set.Bind(wx.EVT_MENU_OPEN, self.menu_set)
menu_about.Bind(wx.EVT_MENU_OPEN, self.menu_about)
self.set_frame = None
self.about_frame = None
self.SetMenuBar(menubar)
self.panel = wx.Panel(self, -1)
# 导出按钮
self.export_btn = wx.Button(parent=self.panel, id=-1, label=u"全导出",
size=(120, 30), pos=(10, 0))
self.export_btn.Bind(wx.EVT_BUTTON, self.export_event)
# 搜索框
self.search_text = wx.TextCtrl(parent=self.panel, id=-1, style=wx.TE_LEFT,
size=(300, 30), pos=(150, 0))
self.search_text.Bind(wx.EVT_TEXT, self.search_event)
# 展示列表
self.check_list = wx.CheckListBox(
parent=self.panel, id=wx.ID_VIEW_LIST, choices=[],
size=(300, self.maxSizeHeight-200), pos=(10, 40))
self.show_excel_list()
self.text = wx.TextCtrl(
parent=self.panel, id=-1, style=wx.TE_MULTILINE|wx.TE_READONLY,
size=(self.maxSizeWeight/2, self.maxSizeHeight-200), pos=(400, 40))
self.Center()
def menu_about(self, event):
wx.MessageBox(message=u"zhlhudson 开发设计!", style=wx.OK|wx.CENTER)
# 设置按钮
def menu_set(self, event):
print("打开设置.." + str(self.set_frame == None))
if self.set_frame == None:
self.set_frame = excelizer_setting(self)
self.set_frame.Show()
self.Freeze()
self.set_frame.SetFocus()
# 显示配置列表
def show_excel_list(self):
all_excels = os.listdir(ec.get_excel_path())
all_excels = excel_ruler.filter_valid_files(all_excels)
self.check_list.Clear()
self.check_list.InsertItems(all_excels, 0)
self.check_list.Bind(wx.EVT_CHECKLISTBOX, self.export_layout)
# 搜索框事件
def search_event(self, event):
search_str = str.strip(self.search_text.GetLineText(0))
if len(search_str) > 0:
# 忽略大小写
all_strs = self.check_list.GetStrings()
all_checked = []
for cb in all_strs:
index_ = self.check_list.FindString(cb)
result = re.match('(.*)%s(.*)'%(search_str), cb)
if not result:
self.check_list.Delete(index_)
else:
all_checked.append(cb)
self.check_list.SetCheckedStrings(all_checked)
else:
self.show_excel_list()
# 导出按钮布局
def export_layout(self, event):
if len(self.check_list.GetCheckedStrings()) > 0:
self.export_btn.SetLabel(u"部分导出")
else:
self.export_btn.SetLabel(u"全导出")
# 导出事件
def export_event(self, event):
self.text.Clear()
checked_strs = self.check_list.GetCheckedStrings() != [] and \
self.check_list.GetCheckedStrings() or self.check_list.GetStrings()
# 全导出时,将目录下的文件全删除
if self.export_btn.GetLabelText() == u"全导出":
def del_file(path_):
for fn in os.listdir(path_):
os.remove(os.path.join(path_, fn))
del_file(ec.get_erl_path())
del_file(ec.get_hrl_path())
# 部分导出,则只删除对应的文件
else:
def del_file(path_):
cns = [cs.split('.')[0] for cs in checked_strs]
for fn in os.listdir(path_):
if cns == []:
break
for cn in cns:
if not re.match('(.*)%s(.*)'%(cn), fn): continue
os.remove(os.path.join(path_, fn))
cns.remove(cn)
break
del_file(ec.get_erl_path())
del_file(ec.get_hrl_path())
excel_ruler.batch_make_file(checked_strs)
def excel_gui_main():
app = wx.App()
frame = excelizer_main()
frame.Show()
app.MainLoop()
if __name__ == "__main__":
app = wx.App()
frame = excelizer_main()
frame.Show()
app.MainLoop()
小工具面板模块
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 文件名:excel_ruler.py
# author:zhlhudson
# 配置表规则模块
# (1)读取规则
# 第1行 :字段中文命名
# 第2行 :字段英文命名
# 第3行 :字段类型
# int :整型
# float :浮点型
# string :字符串
# json :json类型([{"attr":1,"rate":100,"name":"生命"}])
# 第4行 :字段引用行(ref:scene:id)
# 第5行 :前端是否导出(0|不填:导出;1:不导出)
# 第6行 :后端是否导出(0|不填:导出;1:不导出)
# (2)转译规则
# 第3行 :字段类型
# int、float、string :与常用规则类似
# json :需要转化为对应erlang map格式
# 第4行 :字段引用行。需要对比引用配置表,查看字段是否存在
import xlrd
import os
import json
from excel_pkg.excel_common import excel_common
from excel_pkg import excel_common as ec
# 配置表文件读写类
class excel_filelizer(excel_common):
_instance = None
def __init__(self, filename):
print("声明。。。。。")
self.filename = filename
# 打开文件字典
self.open_file_dict = {}
def __del__(self):
print("删除。。。。。")
# 打开文件字典
for open_filename in self.open_file_dict.keys():
self.close_file(open_filename)
self.open_file_dict = None
# 单例模式
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = object.__new__(cls)
return cls._instance
# 打开文件
def open_file(self, open_filename):
if not open_filename in self.open_file_dict.keys():
# TODO : 生成文件名不大对
# 后缀名不是xlsx和xls忽略
suffix_name = (open_filename.split('.'))[-1]
file_path = os.path.dirname(__file__)
if suffix_name == self.cfg_type_erl():
file_path = os.path.join(ec.get_erl_path(), open_filename)
elif suffix_name == self.cfg_type_hrl():
file_path = os.path.join(ec.get_hrl_path(), open_filename)
fd_ = open(file_path, 'a+', encoding='utf8')
self.open_file_dict[open_filename] = fd_
return self.open_file_dict[open_filename]
# 关闭文件
def close_file(self, open_filename):
if open_filename in self.open_file_dict.keys():
self.open_file_dict[open_filename].close()
self.open_file_dict.pop(open_filename)
# 回写文件
def write_file(self, open_filename, str_list):
fd_ = self.open_file(open_filename)
fd_.writelines(str_list)
fd_.flush()
self.close_file(open_filename)
# 读取文件
def read_file(self, open_filename):
fd_ = self.open_file(open_filename)
fd_.readlines()
# 配置表规则模块
class excel_ruler(excel_common):
def __init__(self, filename):
# 当前定位的文件
self.filename = filename
def __del__(self):
print("释放%s资源" % self.__class__.__name__)
pass
def set_setting_dict(self, setting_dict):
self.setting_dict = setting_dict
pass
# 处理配置工作表
def deal_sheet(self, excel):
if (self.data_name() in excel.sheet_names()) and (self.cfg_name() in excel.sheet_names()):
data_sheet = excel.sheet_by_name(self.data_name())
cfg_sheet = excel.sheet_by_name(self.cfg_name())
cfg_dict_list = self.deal_config_sheet(cfg_sheet, data_sheet)
if cfg_dict_list == False:
return False
if not self.deal_data_sheet(data_sheet):
return False
has_record = False # 是否声明record
for cfg_dict in cfg_dict_list:
if cfg_dict[self.cfg_type()] == self.cfg_type_hrl():
self.format_define_hrl(cfg_dict, data_sheet)
if cfg_dict[self.cfg_type()] == self.cfg_type_erl():
if not has_record:
has_record = True
self.format_record_hrl(data_sheet)
self.format_include_erl()
self.format_erl(cfg_dict, data_sheet)
return True
# 处理数据格式工作表
def deal_data_sheet(self, data_sheet):
for rid in range(data_sheet.nrows):
# 第1行 :字段备注
if rid == self_name_rid(): continue
# 剩下的字段不需要检测
if rid > self.pr_ref_rid(): break
if not self.is_valid_of_data_value(rid, data_sheet): return False
return True
# 检测数据工作表所有参数是否有效
def is_valid_of_data_value(self, rid, data_sheet):
# 第2行 :字段英文命名
if rid == self.en_name_rid():
can_pass = True
for cid in range(data_sheet.ncols):
en_name = data_sheet.cell_value(rid, cid)
if en_name != "" and not en_name.islower():
print("%s data 工作表中第%s行%s列 %s,字段英文名须全部小写..." %
(self.filename, str(rid + 1), str(cid + 1), str(en_name)))
can_pass = False
break
# 第3行 :字段类型
elif rid == self.pr_type_rid():
can_pass = True
for cid in range(data_sheet.ncols):
pr_type = data_sheet.cell_value(rid, cid)
if pr_type != "" and not str.islower(pr_type):
print("%s data 工作表中第%s行%s列 %s,字段类型须全部小写..." %
(self.filename, str(rid + 1), str(cid + 1), str(pr_type)))
can_pass = False
break
if pr_type != "" and not pr_type in self.param_types():
print("%s data 工作表中第%s行%s列 %s,字段类型暂不支持..." %
(self.filename, str(rid + 1), str(cid + 1), str(pr_type)))
can_pass = False
break
# 第4行 :字段引用行(ref:scene:id)
elif rid == self.pr_ref_rid():
can_pass = True
for cid in range(data_sheet.ncols):
pr_ref = data_sheet.cell_value(rid, cid)
if pr_ref != "" and not str.islower(pr_ref):
print("%s data 工作表中第%s行%s列 %s,字段引用行须全部小写..." %
(self.filename, str(rid + 1), str(cid + 1), str(pr_ref)))
can_pass = False
break
if pr_ref != "" and len(pr_ref.split(':')) != self.pr_ref_count():
print("%s data 工作表中第%s行%s列 %s,字段引用行格式有误..." %
(self.filename, str(rid + 1), str(cid + 1), str(pr_ref)))
can_pass = False
break
if pr_ref != "":
can_pass = self.is_valid_of_param_ref(pr_ref, cid, data_sheet.col_values(cid))
if not can_pass : break
else : can_pass = True
return can_pass
# 判断引用表里是否存在字段
def is_valid_of_param_ref(self, pr_ref, cid, data_col_list):
[_, _filename, _param_name] = pr_ref.split(':')
file_path = os.path.join(ec.get_excel_path(), _filename)
can_pass = True
is_xlsx = os.path.exists(file_path + ".xlsx")
is_xls = os.path.exists(file_path + ".xls")
if not is_xlsx and not is_xls:
return False
# 判断引用表里是否存在字段
elif is_xlsx: file_path += ".xlsx"
else: file_path += ".xls"
excel = xlrd.open_workbook(file_path, encoding_override="utf-8")
ref_sheet = excel.sheet_by_name(self.data_name())
ref_en_name_list = ref_sheet.row_values(self.en_name_rid())
if not _param_name in ref_en_name_list:
return False
ref_col_list = ref_sheet.col_values(ref_en_name_list.index(_param_name))
# 遍历引用数据是否都存在与引用表内
for rid in range(len(data_col_list)):
if rid <= 5: continue
if data_col_list[rid] in ref_col_list: continue
else:
print("%s data 工作表中第%s行%s列 %s,字段引用行引用的数据不存在..." %
(self.filename, str(rid + 1), str(cid + 1), str(data_col_list[rid])))
can_pass = False
break
excel.release_resources()
return can_pass
# 处理配置格式工作表
def deal_config_sheet(self, cfg_sheet, data_sheet):
cfg_dict_list = []
for rid in range(cfg_sheet.nrows):
cfg_dict = json.loads(cfg_sheet.row_values(rid)[0])
if not self.is_valid_of_config_value(cfg_dict, data_sheet):
return False
cfg_dict_list.append(cfg_dict)
return cfg_dict_list
# 检测配置工作表所有参数是否存在
def is_valid_of_config_value(self, cfg_dict, data_sheet):
# 没有包含类型
if not self.cfg_type() in cfg_dict.keys():
return False
cfg_type = cfg_dict[self.cfg_type()]
# 没有包含函数名
if cfg_type == self.cfg_type_erl() and not self.fun_name() in cfg_dict.keys():
return False
en_names = data_sheet.row_values(self.en_name_rid())
# 返回值为全部时,只需要检测参数列
key_vals = cfg_dict[self.vals()] != self.val_all() and \
cfg_dict[self.keys()] + cfg_dict[self.vals()] or cfg_dict[self.keys()]
for _kv_ in key_vals:
if _kv_ not in en_names:
print("%s config 工作表中%s参数不存在..." % (self.filename, _kv_))
return False
pr_type = data_sheet.cell_value(self.pr_type_rid(), en_names.index(_kv_))
if pr_type != "" and not str.islower(pr_type):
print("%s config 工作表中%s参数,字段类型须全部小写..." % (self.filename, str(pr_type)))
return False
elif pr_type != "" and not pr_type in self.param_types():
print("%s config 工作表中%s参数,字段类型暂不支持..." % (self.filename, str(pr_type)))
return False
elif _kv_ in cfg_dict[self.keys()] and cfg_type == self.cfg_type_hrl() and \
(not len(cfg_dict[self.keys()]) == 1 or len(cfg_dict[self.vals()]) < 1):
print("%s config 工作表中%s参数数量非法..." % (self.filename, str(_kv_)))
return False
elif _kv_ in cfg_dict[self.keys()] and cfg_type == self.cfg_type_hrl() and \
not self.key_hrl_valid_pr_types(pr_type):
print("%s config 工作表中%s参数类型须为%s..." %
(self.filename, str(_kv_), str(self.get_key_hrl_valid_pr_types())))
return False
elif _kv_ in cfg_dict[self.keys()] and cfg_type == self.cfg_type_erl() and \
not self.key_erl_valid_pr_types(pr_type):
print("%s config 工作表中%s参数类型须为%s..." %
(self.filename, str(_kv_), str(self.get_key_erl_valid_pr_types())))
return False
return True
# 组织文件格式 - 头文件
# -define(XXX_YYY, aaa).
def format_define_hrl(self, cfg_dict, data_sheet):
cfg_keys = cfg_dict[self.keys()]
cfg_vals = cfg_dict[self.vals()]
cfg_key = cfg_keys[0]
en_names = data_sheet.row_values(self.en_name_rid())
# key 列id
key_cid = en_names.index(cfg_key)
key_pr_type = data_sheet.cell_value(self.pr_type_rid(), key_cid)
# vals 列id
val_cids = {}
for val in cfg_vals:
val_cid = en_names.index(val)
val_pr_type = data_sheet.cell_value(self.pr_type_rid(), val_cid)
val_cids[val_cid] = val_pr_type
# 得到真实文件名
(realy_filename, _) = os.path.splitext(self.filename)
# 逐行拼接字符串
hrl_str_list = []
for rid in range(data_sheet.nrows):
if rid <= self.server_output_rid(): continue
# key 拼接结果
key_ret = self.format_ret(key_pr_type, data_sheet.cell_value(rid, key_cid))
key_str = ('%s_%s' % (realy_filename, key_ret)).upper()
# val 拼接结果
val_list = []
for val_cid in val_cids.keys():
val_ret = self.format_ret(val_cids[val_cid], data_sheet.cell_value(rid, val_cid))
val_list.append(val_ret)
if len(cfg_vals) > 1:
val_str = '[%s]' % (','.join(val_list))
else:
val_str = val_list[0]
hrl_str_list.append(u'-define(%s, %s).\n' % (key_str, val_str))
if len(hrl_str_list) > 0:
filelizer = excel_filelizer(self.filename)
filelizer.write_file('cfg_' + realy_filename + '.' + self.cfg_type_hrl(), hrl_str_list)
pass
# 组织文件格式 - 头文件
# -record(xxx, {}).
def format_record_hrl(self, data_sheet):
# 字段拼接列表
pr_str_list = []
for cid in range(data_sheet.ncols):
# 不导出字段 | 沒有命名 | 字段类型,跳过
if data_sheet.cell_value(self.server_output_rid(), cid) == 1 or \
data_sheet.cell_value(self.en_name_rid(), cid) == "" or \
data_sheet.cell_value(self.pr_type_rid(), cid) == "":
continue
en_name = data_sheet.cell_value(self.en_name_rid(), cid)
pr_type = data_sheet.cell_value(self.pr_type_rid(), cid)
pr_str_list.append('%s = %s' % (en_name, self.format_ret(pr_type)))
if len(pr_str_list) > 0:
# 得到真实文件名
(realy_filename, _) = os.path.splitext(self.filename)
hrl_str = u'-record(%s, {\n\t%s\n}).\n' % ('cfg_' + realy_filename, ',\n\t'.join(pr_str_list))
filelizer = excel_filelizer(self.filename)
filelizer.write_file('cfg_' + realy_filename + '.' + self.cfg_type_hrl(), [hrl_str])
pass
# 组织文件格式 - 功能模块
# erl功能模块 include
def format_include_erl(self):
# 得到真实文件名
(realy_filename, _) = os.path.splitext(self.filename)
include_str = '-module(cfg_{0}).\n' \
'-include("cfg_{0}.{1}").\n' \
'-compile(export_all).\n'.format(realy_filename, self.cfg_type_erl())
filelizer = excel_filelizer(self.filename)
filelizer.write_file('cfg_' + realy_filename + '.' + self.cfg_type_erl(), include_str)
pass
# 组织文件格式 - 功能模块和头文件
def format_erl(self, cfg_dict, data_sheet):
fun_name = cfg_dict[self.fun_name()]
cfg_keys = cfg_dict[self.keys()]
cfg_vals = cfg_dict[self.vals()]
en_names = data_sheet.row_values(self.en_name_rid())
def sub_kv_cids(cfg_kvs):
_cids = {}
for _kv_ in cfg_kvs:
_cid = en_names.index(_kv_)
_pr_type = data_sheet.cell_value(self.pr_type_rid(), _cid)
_cids[_cid] = _pr_type
return _cids
# keys 列id
key_cids = sub_kv_cids(cfg_keys)
# vals 列id
val_cids = {}
if not cfg_vals == self.val_all():
val_cids = sub_kv_cids(cfg_vals)
# 得到真实文件名
(realy_filename, _) = os.path.splitext(self.filename)
# 逐行拼接字符串
hrl_str_list = []
for rid in range(data_sheet.nrows):
if rid <= self.server_output_rid(): continue
def sub_format(kv_cids):
# key 拼接结果
kvlist = []
for kv_cid in kv_cids.keys():
kv_ret = self.format_ret(kv_cids[kv_cid], data_sheet.cell_value(rid, kv_cid))
kvlist.append(kv_ret)
return kvlist
# key 拼接结果
key_list = sub_format(key_cids)
key_str = ','.join(key_list)
# val 拼接结果
if not cfg_vals == self.val_all() and len(val_cids) > 1:
val_list = sub_format(val_cids)
val_str = u'[%s]' % (','.join(val_list))
elif not cfg_vals == self.val_all():
val_list = sub_format(val_cids)
val_str = val_list[0]
else:
# 字段拼接列表
pr_str_list = []
for cid in range(data_sheet.ncols):
# 不导出字段 | 沒有命名 | 字段类型,跳过
if data_sheet.cell_value(self.server_output_rid(), cid) == 1 or \
data_sheet.cell_value(self.en_name_rid(), cid) == "" or \
data_sheet.cell_value(self.pr_type_rid(), cid) == "":
continue
en_name = data_sheet.cell_value(self.en_name_rid(), cid)
pr_type = data_sheet.cell_value(self.pr_type_rid(), cid)
pr_val = data_sheet.cell_value(rid, cid)
pr_str_list.append('%s = %s' % (en_name, self.format_ret(pr_type, pr_val)))
val_str = u'#%s{%s}.' % ('cfg_' + realy_filename, ','.join(pr_str_list))
hrl_str_list.append(u'%s(%s) -> %s.\n' % (fun_name, key_str, val_str))
filelizer = excel_filelizer(self.filename)
filelizer.write_file('cfg_' + realy_filename + '.' + self.cfg_type_erl(), hrl_str_list)
pass
# erlang目录
ErlangPath = r'..\\Erlang\\'
# 过滤有效配置表
def filter_valid_files(filenames):
valid_names = []
for filename in filenames:
print(filename)
# 预览文件直接忽略
if filename[0:1] == '~':
continue
# 后缀名不是xlsx和xls忽略
suffix_name = (filename.split('.'))[-1]
if suffix_name != 'xlsx' and suffix_name != 'xls':
continue
valid_names.append(filename)
return valid_names
# 批量导出配置文件
def batch_make_file(valid_names):
for filename in valid_names:
exceler = excel_ruler(filename)
file_path = os.path.join(ec.get_excel_path(), filename)
excel = xlrd.open_workbook(file_path, encoding_override="utf-8")
exceler.deal_sheet(excel)
excel.release_resources()
print(r"释放配置表读取资源...")
def __main__():
pass
if __name__ == "__main__":
__main__()
# TODO : 测试读写大excel效率
# TODO : 多线程
# TODO : 界面
小工具规则模块
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 文件名:excel_common.py
# author:zhlhudson
import json
import os
# 配置表常用类
class excel_common(object):
_instance = None
def __init__(self):
pass
def __del__(self):
print(r"释放excel_common资源...")
pass
# 单例模式
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = object.__new__(cls)
return cls._instance
def data_name(self):
# 配置内容工作表
return 'data'
def cfg_name(self):
# 配置格式工作表
return 'config'
def cfg_type(self):
# cfg生成类型
return "type"
def cfg_type_hrl(self):
# cfg生成文件 只有头文件
return "hrl"
def cfg_type_erl(self):
# cfg生成文件 功能模块和头文件
return "erl"
def fun_name(self):
# cfg生成函数名
return "fun_name"
def keys(self):
# cfg生成函数参数
return "keys"
# 只有头文件
def get_key_hrl_valid_pr_types(self):
# cfg生成函数参数 允许的格式
return ['int', 'string']
def key_hrl_valid_pr_types(self, key_type):
# cfg生成函数参数 允许的格式
if key_type in self.get_key_hrl_valid_pr_types(): return True
return False
# 有头文件和模块文件
def get_key_erl_valid_pr_types(self):
# cfg生成函数参数 允许的格式
return ['int', 'float', 'string']
def key_erl_valid_pr_types(self, key_type):
# cfg生成函数参数 允许的格式
if key_type in self.get_key_erl_valid_pr_types(): return True
return False
def vals(self):
# cfg生成函数返回值
return "vals"
def val_all(self):
# cfg生成函数返回值
return "all"
def param_types(self):
# 配置表字段类型
return ['int', 'float', 'string', 'json']
def cn_name_rid(self):
# 第1行 :字段备注
return 0
def en_name_rid(self):
# 第2行 :字段英文命名
return 1
def pr_type_rid(self):
# 第3行 :字段类型
return 2
def pr_ref_rid(self):
# 第4行 :字段引用行(ref:scene:id)
return 3
def pr_ref_count(self):
# 配置表引用字段拆分长度
return 3
def client_output_rid(self):
# 第5行 :前端是否导出(0|不填:导出;1:不导出)
return 4
def server_output_rid(self):
# 第6行 :后端是否导出(0|不填:导出;1:不导出)
return 5
# 格式化
# pr_type :字段格式
# val : 格式化目标
def format_ret(self, pr_type, val=None):
# 返回 cfg生成函数参数 返回值 允许的格式
if pr_type == 'int' and val == None: return str('%d' % 0)
if pr_type == 'int': return str('%d' % val)
if pr_type == 'float' and val == None: return str('%.3f' % 0)
if pr_type == 'float': return str('%.3f' % val)
if pr_type == 'string' and val == None: return '\"\"'
if pr_type == 'string': return u'\"%s\"' % val
if pr_type == 'json' and val == None: return '[]'
if pr_type == 'json':
# 闭包 转化 json格式为erl map格式
def val_json_format(v_dict):
v_ret = []
for k in v_dict.keys():
v_ret.append('%s => %s' % (str(k), str(v_dict[k])))
return '#{%s}' % (','.join(v_ret))
val_dict = json.loads(val)
if isinstance(val_dict, list):
val_ret = []
for v_dict in val_dict:
val_ret.append(val_json_format(v_dict))
return '[%s]' % (','.join(val_ret))
else:
return val_json_format(val_dict)
# 加载配置文件
def load_setconfig():
with open(u"..\\..\\Configs\\Setting.cfg", mode="r+", encoding='utf-8') as fd_:
setting = json.load(fd_)
fd_.close()
return setting
# 重置配置文件
def reset_setconfig(setting):
with open(r"..\\..\\Configs\\Setting.cfg", mode="w+", encoding='utf-8') as fd_:
json.dump(setting, fd_, indent=4)
fd_.close()
# 获取配置表生成文件路径-hrl
def get_hrl_path():
return load_setconfig()['path_set']['hrl_path']
# 获取配置表生成文件路径-erl
def get_erl_path():
return load_setconfig()['path_set']['erl_path']
# 获取配置表路径
def get_excel_path():
return load_setconfig()['path_set']['excel_path']
if __name__ == "__main__":
pass
小工具常用函数
6.小工具实际使用效果
可以具备模糊搜索查找(用的是正则表达式,可能效率有点差,但是书写方便),支持全导出或者部分导出,导出结果之后会打印在右边的文档框内。
以上是这个配置表一个详细内容,里面有很多不足,希望大佬斧正,同时也希望对各位学习中、甚至项目开发中有所帮助。欢迎一起探讨python、erlang甚至别的语言。
当然上面的小工具还没有完善,其实实际项目中所导出的配置表文件可能多达几百份甚至上千份,这时候单线程导出就有点看不上了,所以这里有兴趣的可以写成支持多线程的。
版权声明:本文标题:提高游戏开发效率的小工具之配置表生成工具 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/xitong/1725842915a1045106.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论