Json生成Lua Table工具

最近参与一个Unity手游项目的前端程序开发,主要使用lua语言,项目之前有了成型的服务器,包括策划配置好的数据,虽然策划配置数据使用的是Excel表格,但一开始没按照可Excel直接生成Lua表的格式去配,所以Excel表直接生成Lua代码的路是走难走得通了,但Excel却可以生成Json格式文件,那么我依然可以使用Json来生成Lua代码。

所以用Python写了一个Json生成Lua代码工具:

Python代码工具下载地址: http://download.csdn.net/detail/u012740992/9752228

注意:需安装Python27环境来运行工具:
这里写图片描述

使用效果:

这里写图片描述

生成的文件:

这里写图片描述

生成的内容:

这里写图片描述

贴代码:

import json  
import types  
import os,sys
import sys


from Tkinter import *
import datetime
import time
import Tkinter, Tkconstants, tkFileDialog
import tkMessageBox

reload(sys)
sys.setdefaultencoding('utf-8')



def isJsonStr(newstr):
    try:
        json.loads(newstr)
    except Exception as e:
        #except ValueError:
        return False
    else:
        return True


def addSpace(layer):  
    luaStr = ""  
    for i in range(0,layer):  
        luaStr += '\t'  
    return luaStr 

def parsJsonObj(jsonObj,layer=0):  

    jsonObjType = type(jsonObj)
    #字符串类型  
    if  jsonObjType is types.StringTypes or jsonObjType is str or jsonObjType is types.UnicodeType:

        #支持在json中再遇到json字符串时,继续解析json字符串
        if isJsonStr(jsonObj):
            luaStr = ''
            luaStr += parsJsonObj(json.loads(jsonObj),layer+1)
            return luaStr
        else:
            newstr = jsonObj.replace('\n', '\\n').replace('\t', '\\t').replace('"', '\\"').replace("'", "\\'")
            return "'" + newstr + "'" 



    #数组类型  
    elif jsonObjType is types.ListType:  
        luaStr = "{\n"  
        luaStr += addSpace(layer+1)  
        for i in range(0,len(jsonObj)):  
            luaStr += parsJsonObj(jsonObj[i],layer+1)  
            if i < len(jsonObj)-1:  
                luaStr += ','  
        luaStr += '\n'  
        luaStr += addSpace(layer)  
        luaStr +=  '}'  
        return luaStr
    elif jsonObjType is types.BooleanType:  
        if jsonObj:  
            return 'true'  
        else:  
            return 'false'
    #数字类型  
    elif jsonObjType is types.IntType or jsonObjType is types.LongType or jsonObjType is types.FloatType:
        jsonObjstr = str(jsonObj)
        return str(jsonObj)
    #字典类型  
    elif jsonObjType is types.DictType:  
        luaStr = ''  
        luaStr += "\n"  
        luaStr += addSpace(layer)  
        luaStr += "{\n"  
        jsonObjlen = len(jsonObj)  
        jsonObjcount = 0  
        for k,v in jsonObj.items():  
            jsonObjcount += 1  
            luaStr += addSpace(layer+1)  
            if type(k) is types.IntType or str.isdigit(str(k)) == True:  
                luaStr += '[' + k + ']'  
            else:
                #print('is not int type : ' + str(k))
                #那些以数字开头,又不是数字的key值非法,当字符串处理,
                #比如 0nb、345nb、 34-45  
                if str.isdigit(str(str(k)[0]))==True:
                    luaStr += "['"+str(k)+"']"
                else:
                    #普通键值
                    luaStr += k   
            luaStr += ' = '  
            try:  
                luaStr += parsJsonObj(v,layer +1)  
                if jsonObjcount < jsonObjlen:  
                    luaStr += ',\n'  

            except Exception, e:  
                print 'error in ',k,v  
                raise  
        luaStr += '\n'  
        luaStr += addSpace(layer)  
        luaStr += '}'  
        return luaStr  
    else:  
        print jsonObjType , 'is error'  
        return None  


def genLuaFile(genfileName,tableName,jsonStr):
    try:
        newdata = json.loads(jsonStr)
    except Exception as e:
        #except ValueError:
        tkMessageBox.showinfo('提示', '遇到错误的json格式: \n ' + str(e))
        return 

    luatableJson = parsJsonObj(newdata)
    luagendir = luadir.get().replace('\\', '/')

    if os.path.exists(luagendir) == False:
        os.mkdir(luagendir)
    newluafile = luagendir +'/'+genfileName
    if os.path.exists(newluafile):
        os.remove(newluafile)

    with open(newluafile, 'a') as f:

        f.write('return {\n')
        f.write(tableName + " = " + luatableJson)

        f.write('\n}')

        f.close()



def genMyLua(jsonroot, jsonfile):
    genfileName = jsonfile.replace('.json', '.lua')
    jsonfilesdir = jsonroot+'/'+jsonfile
    text = " "
    with open(jsonfilesdir, 'r') as f:
        try:
            jsontext = f.read().decode('utf-8')
        except Exception as e:
            tkMessageBox.showinfo('提示', '读取json文件出错:\n '+str(e))
            return
        finally:

            pass
        genLuaFile(genfileName, 'data', jsontext)
        f.close()

#===================================================================================
def findJsonFilesPath():
    pathname=tkFileDialog.askdirectory()
    if pathname != '':
        pathname = pathname.replace('/','\\')
        jsondir.delete(0, len(jsondir.get()))
        jsondir.insert(END, pathname)

    if pathname != '':
        luadir.delete(0, len(luadir.get()))
        luadir.insert(END, pathname+'\LuaTable')



def findGenLuaDir():
    luapath=tkFileDialog.askdirectory()
    if luapath != '':
        luadir.delete(0, len(luadir.get()))
        luadir.insert(END, luapath.replace('/','\\'))



def genLuaTable():
    jsonroot = jsondir.get().replace('\\','/')
    if jsonroot == '':
        tkMessageBox.showinfo('提示', '你好, %s' % '请输入json文件根路径')
    newluadir = luadir.get().replace('\\','/')
    if os.path.exists(newluadir) == False:
        os.mkdir(newluadir)
    if newluadir == '' or os.path.exists(newluadir) == False:
        tkMessageBox.showinfo('提示', '你好, %s' % '生成lua路径无效')

    progressTips.config(text='正在生成.....')
    ls = os.listdir(jsonroot)
    jsonfs = []
    for l in ls:
        if len(l) < 5:
            return
        if l[-5:] == '.json':

            jsonfs.append(l)
        pass

    for fn in jsonfs:
        genMyLua(jsonroot, fn)
        print(fn)

    luadirls = os.listdir(newluadir)
    luafs = []
    for f in luadirls:
        if f[-4:] =='.lua' and f.find('GameDataList') < 0:
            luafs.append(f.replace('.lua', ''))
    genLualistFile(newluadir, luafs)

    progressTips.config(text='')
    tkMessageBox.showinfo('提示', '生成结束')
    os.system("explorer.exe %s" % newluadir.replace('/', '\\')) 

def genLualistFile(luadir, luafs):
    lualistfile = luadir+'/GameDataList.lua'
    if os.path.exists(lualistfile):
        os.remove(lualistfile)
    with open(lualistfile, 'a') as f:
        content = 'local function InitGameData(reqdir)'+'\n'
        content = content + '\treturn {'
        for luaf in luafs:
            #name = require dir..'/'..f
            content = content + '\n\t\t'
            content = content + luaf + ' = require (' + 'reqdir.."/'+luaf+'"),'
        pass
        #去除最后一个逗号
        content = content.rstrip(',')
        #生成返回表
        #content = content + '\n\n\t'
        content = content +'\n\t}'

        content = content + '\nend\n'
        content = content + 'return InitGameData'
        f.write(content)
        f.close()


root = Tk()
root.title(unicode('json文件生成lua表工具','utf-8'))
#发送按钮事件



#创建几个frame作为容器
root.geometry('600x500')
frame01  = Frame(width=750, height=470)


#button_sendmsg   = Button(frame01, text=unicode('发送','utf-8'), command=sendmessage)

#使用grid设置各个容器位置

frame01.grid(row=0, column=0, padx=2, pady=5)
frame01.grid_propagate(0)
#button_sendmsg.grid(sticky=E)


jsondirdesc = Label(frame01, width = 20, text = '输入json文件根路径:')
jsondir = Entry(frame01, width = 50)
findButton = Button(frame01, text=' 查找', command=findJsonFilesPath)

genLabel = Label(frame01, text='生成lua路径', width=50)
luadir = Entry(frame01, width = 50)
findgenBtn = Button(frame01, text=' 查找', command=findGenLuaDir)

genBtn = Button(frame01, text='生成Lua表文件', command=genLuaTable)

progressTips = Label(frame01, text='', width=50)

tipLabel = Label(frame01, text='\t注意:\n  \t输入json根路径,仅筛选以"*.json"文件解析,生成同名"*.lua"文件;\n\t生成路径如果存在同名文件将会被覆盖,请备份;\n\t同时会生成GameDataList.lua文件,里面记录所有生成的"*.lua"文件、\n\tGameDataList.lua里面生成的函数可传入lua路径一键require使用。', width=50, height=10)

#helloLabel.pack()
jsondirdesc.grid(row=0, column=0)
jsondir.grid(row=1, column=0)
findButton.grid(row=1, column=1)

genLabel.grid(row=2, column=0)
luadir.grid(row=3, column=0)
findgenBtn.grid(row=3, column=1)
genBtn.grid(row=4, column=0)

progressTips.grid(row=5, column=0)

tipLabel.grid(row=8, column=0)


#主事件循环
root.mainloop()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值