加班,闲来无事 吹一波。。。
吹啊吹啊 我的骄傲放纵。。。
五毛钱的来了(良心商家,不涨价)
其实呢,表格生成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); } } }
原版秘籍拿去,切记 第一章的“欲练此功,必先自宫”,可不必相信,否则后果概与本人无关。