XLSX配置表直接导出到LuaTable
导出的时候把key进行抽离出__key__ 节约内存占用 逻辑中通过__index进行映射
XLSX数据
工具代码
pip install pandas
import pandas as pd
import math
INT_TYPE = 'int'
BOOL_TYPE = 'bool'
STRING_TYPE = 'string'
FLOAT_TYPE = 'float'
INT_ARRAY_TYPE = 'int[]'
BOOL_ARRAY_TYPE = 'bool[]'
STRING_ARRAY_TYPE = 'string[]'
FLOAT_ARRAY_TYPE = 'float[]'
VALUE_NAME = '__value__'
INDEX_NAME = '__index__'
KEY_NAME = '__key__'
LEN_NAME = 'len'
def isnan(value):
try:
float_value = float(value)
return math.isnan(float_value)
except (TypeError, ValueError):
return False
def readXlsx(xlsxPath):
df = pd.read_excel(xlsxPath, header=None)
return df
def FrmatIntArray(text):
return '{' + text + '}'
def FrmatFloatArray(text):
return '{' + text + '}'
def FrmatStringArray(text):
outStr = "{"
for value in text.split(','):
outStr += f'"{value}",'
outStr = outStr[:len(outStr) - 1]
outStr += "}"
return outStr
def FrmatBoolArray(text):
outStr = "{"
for value in text.split(','):
outStr += str(bool(int(value))).lower() + ","
outStr = outStr[:len(outStr) - 1]
outStr += "}"
return outStr
def FormatValue(value, type):
if pd.isna(value):
if type == INT_TYPE or type == FLOAT_TYPE:
value = 0
elif type == STRING_TYPE:
value = '""'
elif type == BOOL_TYPE:
value = 'false'
elif type == INT_ARRAY_TYPE or type == STRING_ARRAY_TYPE or type == BOOL_ARRAY_TYPE or type == FLOAT_ARRAY_TYPE:
value = '{}'
else:
value = str(value).strip()
if type == STRING_TYPE:
value = f'"{value}"'
elif type == INT_TYPE:
value = int(value)
elif type == FLOAT_TYPE:
value = float(value)
elif type == BOOL_TYPE:
value = str(bool(value)).lower()
elif type == INT_ARRAY_TYPE:
value = FrmatIntArray(value)
elif type == STRING_ARRAY_TYPE:
value = FrmatStringArray(value)
elif type == BOOL_ARRAY_TYPE:
value = FrmatBoolArray(value)
elif type == FLOAT_ARRAY_TYPE:
value = FrmatFloatArray(value)
return value
def toTable(xlsxPath, tableName):
df = readXlsx(xlsxPath)
field_names = list(df.iloc[1])
field_types = list(df.iloc[2])
key2Index = {}
Index2Id = {}
length = 0
table = '--The generated code cannot be modified!!\n'
table+=(tableName + ' = {} \nlocal ' + f'{VALUE_NAME} = ' + '{\n')
for index, row in df.iloc[3:].iterrows():
row_id = row[0]
table+=(f' [{row_id}] = {{')
length+=1
Index2Id[length] = row_id
for column, value in row.items():
field_type = field_types[column]
field_name = field_names[column]
if isnan(field_type) or isnan(field_name):
continue
value = FormatValue(value, field_type)
key2Index[field_name] = column + 1
table+=(f'{value}, ')
table = table[:len(table) - 2]
table+=('},\n')
table+=('}\n\n')
table+=('local ' + f'{KEY_NAME} = ' + '{\n')
for key, value in key2Index.items():
table+=(f' {key} = {value},\n')
table+=('}\n\n')
table+=('local ' + f'{INDEX_NAME} = ' + '{')
for key, value in Index2Id.items():
table+=(f'{value},')
table = table[:len(table) - 1]
table+=('}\n')
table+=(f'{tableName}.{LEN_NAME} = ' + f'{length}' + '\n\n')
table+=('local function GetValue(tTable, vKey)\n')
table+=(f'\tlocal nIndex = {KEY_NAME}[vKey]\n')
table+=('\tif not nIndex then\n\t\treturn nil\n\tend\n\n\treturn tTable[nIndex]\nend\n\n')
table+=('local function Get(tTable, vKey)\n')
table+=(f'\tif vKey == "tMap" then\n\t\treturn {VALUE_NAME}\n\tend\n\n')
table+=(f'\tif vKey == "tList" then\n\t\treturn {INDEX_NAME}\n\tend\n\n')
table+=(f'\treturn {VALUE_NAME}[vKey]\nend\n\n')
table+=(f'local function ReadOnly(tTable, vKey, vValue)\n\tprint("{tableName} A read-only table cannot be modified, key: "..vKey.." be changed to: "..vValue)\nend\n\n')
table+=(f'for nId, tCfg in pairs({VALUE_NAME}) do\n\t' + 'setmetatable(tCfg, {__index = GetValue, __newindex = ReadOnly})\nend\n\n')
table+=(f'setmetatable({tableName}, ' + '{__index = Get, __newindex = ReadOnly})')
return table
def writeTable(tablePath, table):
with open(tablePath, 'w', encoding="utf-8") as f:
f.write(table)
tableName = 'TestTable'
table = toTable('XlsxToLuaTable\Test.xlsx', tableName)
writeTable('XlsxToLuaTable\\' + tableName + '.lua', table)
XLSX输出的结果
对于外部而言 这个Table里内容是不可以直接访问得 除了TestTable.len
Table中的内容也不会被修改使用__newindex进行约束 把table变为只读 如果尝试修改静态数据 会报错
TestTable = {}
local __value__ = {
[10086] = {10086, "超赛1", true, 20, 160, 23.33, {101,102,103,104}, {true,false,false,false}, {"描述1","描述2","描述3","描述4"}, {10.2,10.3,10.4,10.5}},
[10087] = {10087, "超赛2", true, 21, 161, 24.33, {101,102,103,104}, {true,false,true,true}, {"描述1","描述2","描述3","描述5"}, {10.2,10.3,10.4,10.6}},
[10088] = {10088, "超赛3", true, 22, 162, 25.33, {101,102,103,104}, {true,false,true,false}, {"描述1","描述2","描述3","描述6"}, {10.2,10.3,10.4,10.7}},
[10089] = {10089, "超赛4", true, 23, 163, 26.33, {101,102,103,104}, {true,false,true,true}, {"描述1","描述2","描述3","描述7"}, {10.2,10.3,10.4,10.8}},
[10090] = {10090, "超赛5", true, 24, 164, 27.33, {101,102,103,104}, {true,false,false,false}, {"描述1","描述2","描述3","描述8"}, {10.2,10.3,10.4,10.9}},
}
local __key__ = {
ID = 1,
Name = 2,
Sex = 3,
Age = 4,
Height = 5,
Width = 6,
skillIds = 7,
skillOpens = 8,
skillDesc = 9,
cds = 10,
}
local __index__ = {10086,10087,10088,10089,10090}
TestTable.len = 5
local function GetValue(tTable, vKey)
local nIndex = __key__[vKey]
if not nIndex then
return nil
end
return tTable[nIndex]
end
local function Get(tTable, vKey)
if vKey == "tMap" then
return __value__
end
if vKey == "tList" then
return __index__
end
return __value__[vKey]
end
local function ReadOnly(tTable, vKey, vValue)
print("TestTable A read-only table cannot be modified, key: "..vKey.." be changed to: "..vValue)
end
for nId, tCfg in pairs(__value__) do
setmetatable(tCfg, {__index = GetValue, __newindex = ReadOnly})
end
setmetatable(TestTable, {__index = Get, __newindex = ReadOnly})
逻辑内使用这些配置
local Len = TestTable.len
local tMap = TestTable.tMap
local tList = TestTable.tList
local tItem = tMap[10086]
local tItem1 = TestTable[10086]
local sName = tItem.Name
local sDesc = tItem.skillDesc
运行结果
只实现了导出到luatable, 如果想导出到其他语言 修改python代码即可
GitHub项目地址