unity游戏开发 Excel表格生成class类

加班,闲来无事 吹一波。。。

吹啊吹啊 我的骄傲放纵。。。

五毛钱的来了(良心商家,不涨价)

其实呢,表格生成class类 就是一个编辑器,比如:策划给你了好多excel表,而你肯定要把表对应一个个的class类。这个时候手动写那岂不是很难受,有失我高级程序员的尊严。下面就是我挽回英俊潇洒的尊严的嘶吼(时候)了。

先用一波思路骚情骚情你哦。

首先,要获取到excel的所在的目录以及并用io流()读取到里面的excel文件,这个时候最好判断下目录中有木有文件(最好提示个弹框或者debug),倘若是空表,那我岂不是很没面子。其次获取到生成class类所放的目录。

其次,读取excel表,这可是个比较牛逼的活呀,其实在你没接触过的情况下,感觉还是挺神奇的,至少牛逼如我也曾这么天真的认为过。欸,那个嚷嚷着要代码的,注意素质。我贴还不行吗。。。

FileStream mStream = File.Open(excelFile, FileMode.Open, FileAccess.Read);
IExcelDataReader mExcelReader = ExcelReaderFactory.CreateOpenXmlReader(mStream);
DataSet mResultSet = mExcelReader.AsDataSet();

牛逼吧,行了 别奉承了。且听我慢慢吹完。

下面就是要读取数据表了哈,这个要用到上述代码的mResultset。获取到excel的数据表以及行数和列数,将表头对应的数据存入字典中。

再其次,获取excel头字段的内容,也就是第一行内容。各位英雄都清楚 生成的class类中数字段,头字段内容对应class中字段名。至于这个也是根据excel行列获取的。

最后,这节就比较重要了,而且方法很不常见,本店小二也是感觉不太好整啊,其实归根结底就是一个CodeDom。CodeDom是.net提供的源代码生成器。各位若想详细了解下其中类 可参考https://blog.csdn.net/firewolffeng/article/details/2214913

鉴于被各位英雄豪杰催代码的经验,本店小二这回也要主动一下下的啦,毕竟男人是要主动的。嘿嘿

好看的代码来啦。。。

// fileName:excel文件

// json:上述“其次”读出的json

// statements:上述“再其次独处的头字段

private static void Json2Class(string fileName, string json, List<object> statements)
        {
            string structName = "";

            structName = Path.GetFileName(fileName).ToLower().Replace(".xlsx", "");

            //首字母大写
            structName = structName.Substring(0, 1).ToUpper() + structName.Substring(1);
            //输出目录控制
            string outputFile = Path.Combine(Application.dataPath,"Code/Game@hotfix/Table");
            if (Directory.Exists(outputFile) == false)
            {
                Directory.CreateDirectory(outputFile);
            }
            //输出目录
            outputFile = Path.Combine(outputFile,  Path.GetFileName(fileName).Replace(".xlsx", ".cs"));

            //生成类服务
            CodeCompileUnit compunit = new CodeCompileUnit();
            CodeNamespace sample = new CodeNamespace("Game.Data");
            compunit.Namespaces.Add(sample);
            //引用命名空间
            sample.Imports.Add(new CodeNamespaceImport("System"));
            sample.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));

            //在命名空间下添加一个类
            CodeTypeDeclaration wrapProxyStruct = new CodeTypeDeclaration(structName);
            wrapProxyStruct.IsClass = false;
            wrapProxyStruct.IsEnum = false;
            wrapProxyStruct.IsInterface = false;
            wrapProxyStruct.IsPartial = false;
            wrapProxyStruct.IsStruct = true;
            //把这个类添加到命名空间 
            sample.Types.Add(wrapProxyStruct);

            //
            var jsonData = JsonMapper.ToObject(json)[0];

            int i = 0;
            foreach (var key in jsonData.Keys)
            {
                //字段

                string memberContent =
@"       public [type] [Name] {get;set;}";
                CodeSnippetTypeMember member = new CodeSnippetTypeMember();
                if (key.ToLower() == "id" && key != "Id")
                {
                    Debug.LogErrorFormat("<color=yellow>表格{0}字段必须为Id[大小写],请修改后生成</color>", structName);
                    break;
                }
                else if (key == "Id")
                {
                    //增加一个sqlite主键
                    //member.CustomAttributes.Add(new CodeAttributeDeclaration("PrimaryKey"));
                    memberContent =
@"      [PrimaryKey] 
        public [type] [Name] {get;set;}";
                }

                var value = jsonData[key];


                string type = null;
                if (value.IsArray)
                {
                    var str = value.ToJson();
                    if (str.IndexOf("\"") > 0)
                    {
                        type = "List<string>";
                    }
                    else
                    {
                        type = "List<double>";
                    }
                }
                else if (value.IsInt) type = "int";
                else if (value.IsDouble || value.IsLong) type = "double";
                else if (value.IsBoolean) type = "bool";
                else if (value.IsString) type = "string";

                //注释
                member.Comments.Add(new CodeCommentStatement(statements[i].ToString()));

                member.Text = memberContent.Replace("[type]", type).Replace("[Name]", key);

                wrapProxyStruct.Members.Add(member);
                i++;
            }

            //生成代码       
            CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
            CodeGeneratorOptions options = new CodeGeneratorOptions();
            options.BracingStyle = "C";
            options.BlankLinesBetweenMembers = true;

            using (System.IO.StreamWriter sw = new System.IO.StreamWriter(outputFile))
            {
                provider.GenerateCodeFromCompileUnit(compunit, sw, options);
            }
        }

上述功法秘籍,对于未曾接触过的英雄豪杰来说还是略有难度,不过别怕 ,结合我上述贴出的CodeDom网址一块修行,效果还是显著的。望各位珍重身体

行了,口干舌燥了 也该结束了。

啥,残卷练得筋脉逆流,走火入魔。就你事多 哪次都是你逼逼。

using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using BDFramework.ResourceMgr;
using LitJson;
using UnityEditor;
using UnityEngine;
using System;

    static public class Excel2Code
    {
        public static void GenCode()
        {
            var tablePath = Path.Combine(Application.dataPath, "Resource/Table");
            var tableDir = Path.GetDirectoryName(tablePath);
            var xlslFiles = Directory.GetFiles(tableDir, "*.xlsx", SearchOption.AllDirectories);

            if (xlslFiles.Length == 0)
            {
                EditorUtility.DisplayDialog("提示", "未发现xlsx文件,请注意不是xls", "确定");
                return;
            }

            foreach (var f in xlslFiles)
            {
                var excel = new ExcelUtility(f);
                var json = excel.GetJson();
                var statements = excel.GetLine(0);
                Json2Class(f, json, statements);
                Debug.Log("导出:" + f);
            }

            EditorUtility.DisplayDialog("提示", "生成完成!", "确定");
            AssetDatabase.Refresh();
        }


        private static void Json2Class(string fileName, string json, List<object> statements)
        {
            string structName = "";

            structName = Path.GetFileName(fileName).ToLower().Replace(".xlsx", "");

            //首字母大写
            structName = structName.Substring(0, 1).ToUpper() + structName.Substring(1);
            //输出目录控制
            string outputFile = Path.Combine(Application.dataPath,"Code/Game@hotfix/Table");
            if (Directory.Exists(outputFile) == false)
            {
                Directory.CreateDirectory(outputFile);
            }
            //输出目录
            outputFile = Path.Combine(outputFile,  Path.GetFileName(fileName).Replace(".xlsx", ".cs"));


            //生成类服务
            CodeCompileUnit compunit = new CodeCompileUnit();
            CodeNamespace sample = new CodeNamespace("Game.Data");
            compunit.Namespaces.Add(sample);
            //引用命名空间
            sample.Imports.Add(new CodeNamespaceImport("System"));
            sample.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
            sample.Imports.Add(new CodeNamespaceImport("Game.Data"));
            sample.Imports.Add(new CodeNamespaceImport("SQLite4Unity3d"));

            //在命名空间下添加一个类
            CodeTypeDeclaration wrapProxyStruct = new CodeTypeDeclaration(structName);
            wrapProxyStruct.IsClass = false;
            wrapProxyStruct.IsEnum = false;
            wrapProxyStruct.IsInterface = false;
            wrapProxyStruct.IsPartial = false;
            wrapProxyStruct.IsStruct = true;
            //把这个类添加到命名空间 
            sample.Types.Add(wrapProxyStruct);

            //
            var jsonData = JsonMapper.ToObject(json)[0];

            int i = 0;
            foreach (var key in jsonData.Keys)
            {
                //字段

                string memberContent =
@"       public [type] [Name] {get;set;}";
                CodeSnippetTypeMember member = new CodeSnippetTypeMember();
                if (key.ToLower() == "id" && key != "Id")
                {
                    Debug.LogErrorFormat("<color=yellow>表格{0}字段必须为Id[大小写],请修改后生成</color>", structName);
                    break;
                }
                else if (key == "Id")
                {
                    //增加一个sqlite主键
                    //member.CustomAttributes.Add(new CodeAttributeDeclaration("PrimaryKey"));
                    memberContent =
@"      [PrimaryKey] 
        public [type] [Name] {get;set;}";
                }

                var value = jsonData[key];

                string type = null;
                if (value.IsArray)
                {
                    var str = value.ToJson();
                    if (str.IndexOf("\"") > 0)
                    {
                        type = "List<string>";
                    }
                    else
                    {
                        type = "List<double>";
                    }
                }
                else if (value.IsInt) type = "int";
                else if (value.IsDouble || value.IsLong) type = "double";
                else if (value.IsBoolean) type = "bool";
                else if (value.IsString) type = "string";

                //注释
                member.Comments.Add(new CodeCommentStatement(statements[i].ToString()));

                member.Text = memberContent.Replace("[type]", type).Replace("[Name]", key);

                wrapProxyStruct.Members.Add(member);
                i++;
            }

            //生成代码       
            CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
            CodeGeneratorOptions options = new CodeGeneratorOptions();
            options.BracingStyle = "C";
            options.BlankLinesBetweenMembers = true;

            using (System.IO.StreamWriter sw = new System.IO.StreamWriter(outputFile))
            {
                provider.GenerateCodeFromCompileUnit(compunit, sw, options);
            }
        }
}

原版秘籍拿去,切记 第一章的“欲练此功,必先自宫”,可不必相信,否则后果概与本人无关。

猜你喜欢

转载自blog.csdn.net/IT_choshim/article/details/85012808
今日推荐