一键读取Txt、Excel等表格配置【源码+原理】


原文:http://www.manew.com/thread-105598-1-1.html

引言 

1、您是否需要在项目中使用Txt、Excel等表格配置?
2、您是否还在一行行写配置解析代码?
3、您是否担心运行时解析速度?
 

本文将一一解答上面的问题,帮助你更好地使用配置

源码:https://github.com/RickJiangShu/ConfigManager
范例工程:https://github.com/RickJiangShu/ConfigManager-Example

设计思路


1、自动生成解析类
项目中经常需要用到策划配置,而一个策划配置需要写一个解析类去解析,这样浪费了大量的时间且容易出错
因此,我觉得可以写一个自动生成解析类的工具。

2、编辑器下解析
通常解析工作是放在运行时,即加载一个文本文件之后再进行解析这个文本。这样在数据量巨大的时候,解析速度堪忧
因此,我想把大量的解析工作放在编辑器下去处理。


流程图


整个流程如上图所示,所以整个思路可以分为以下四个部分:解析、反射、序列化和反序列化


解析

1. 按“分隔符”与“换行符”将表格切割成“行x列”的字符串矩阵,关键代码如下:
[C#]  纯文本查看  复制代码
public static string[,] Content2Matrix(string config, string sv, string lf, out int row, out int col)
{
    config = config.Trim();//清空末尾的空白

    //分割
    string[] lines = Regex.Split(config, lf);
    string[] firstLine = Regex.Split(lines[0], sv, RegexOptions.Compiled);
            
    row = lines.Length;
    col = firstLine.Length;
    string[,] matrix = new string[row, col];
    //为第一行赋值
    for (int i = 0, l = firstLine.Length; i < l; i++)
    {
        matrix[0, i] = firstLine;
    }
    //为其他行赋值
    for (int i = 1, l = lines.Length; i < l; i++)
    {
        string[] line = Regex.Split(lines, sv);
        for (int j = 0, k = line.Length; j < k; j++)
        {
            matrix[i, j] = line[j];
        }
    }
    return matrix;
}


2.从矩阵中取出相应的字符,替换自定义模板中的变量并写入文件,关键代码如下:
[C#]  纯文本查看  复制代码
string idType = ConfigTools.SourceType2CSharpType(src.matrix[1, 0]);
string idField = src.matrix[2, 0];

//属性声明
string declareProperties = "";
for (int x = 0; x < src.column; x++)
{
    string comment = src.matrix[0, x];
    string csType = ConfigTools.SourceType2CSharpType(src.matrix[1, x]);
    string field = src.matrix[2, x];
    string declare = string.Format(templete2, comment, csType, field);
    declareProperties += declare;
}

//替换
content = content.Replace("/*ClassName*/", src.configName);
content = content.Replace("/*DeclareProperties*/", declareProperties);
content = content.Replace("/*IDType*/", idType);
content = content.Replace("/*IDField*/", idField);

//写入
ConfigTools.WriteFile(outputPath, content);


生成的C#文件如下
 


反射

上面解析出了C#文件和一个SerializableSet.cs,接下来将通过反射特性实例化一个SerializableSet对象,关键代码如下:
[C#]  纯文本查看  复制代码
public static object Serialize(List<Source> sources)
{
    Type t = FindType("SerializableSet");
    if (t == null)
    {
        UnityEngine.Debug.LogError("找不到SerializableSet类!");
        return null;
    }

    object set = UnityEngine.ScriptableObject.CreateInstance(t);

    foreach(Source source in sources)
    {
        string fieldName = source.sourceName + "s";
        Array configs = Source2Configs(source);
        FieldInfo fieldInfo = t.GetField(fieldName);
        fieldInfo.SetValue(set,configs);
    }
    return set;
}



序列化

最后就是使用Unity API创建Asset文件,关键代码如下:
[C#]  纯文本查看  复制代码
UnityEngine.Object set = (UnityEngine.Object)Serializer.Serialize(sources);
string o = cache.assetOutputFolder + "/" + assetName;
AssetDatabase.CreateAsset(set, o);


生成的文件如下:



反序列化
因为要在运行时使用,所以反序列化的代码没有使用反射(效率低)。而是在解析的过程中解析出一个反序列化文件,生成的代码如下:

[C#]  纯文本查看  复制代码
public class Deserializer
{
    public static void Deserialize(SerializableSet set)
    {
        for (int i = 0, l = set.Equips.Length; i < l; i++)
        {
            EquipConfig.GetDictionary().Add(set.Equips.EquipId, set.Equips);
        }

        for (int i = 0, l = set.EquipCSVs.Length; i < l; i++)
        {
            EquipCSVConfig.GetDictionary().Add(set.EquipCSVs.EquipId, set.EquipCSVs);
        }
    }
}


最后,直接调用相应的Config.Get(id)即可,效果如下:



若您发现其中有问题或任何优化意见,请在本帖留言或私信我,谢谢大家~
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别
1. 单元格合并(类似MS EXCEL,增强:合并单元格包含的行列可以移动)。(Cells merged,unmerged) 2. 边框属性(类似MS EXCEL,增强:线宽可任意)。(Cell border line style) 3. 斜线功能(一个单元格内可以含有两条斜线,符合中国人的习惯)。 4. 单元格文字属性(上下左右居中对齐,多行文字,字体颜色,背景色)。(Cell text property, alignment) 5. 公式运算(包含Delphi Script 解释器“Delphin”,可以执行Delphi 代码,显示 Delphi 的窗体文件DFM)。(Delphi interpreter) 6. 行列极大(资源允许范围)。(MaxRowCount = 0xFFFF, MaxColCount=0xFFFF) 7. 修改“Delphin”解释器,使之能够识别对单元格的引用。(Ref cell name in delphin) 8. 对单元格之间循环引用的检查。(cell loop reference check) 9. 自动调整行高、列宽。(AutoSizeRows, AutoSizeCols) 10. 插入、删除、增加行列。(InsertRow, InsertCol) 11. 隐藏、取消隐藏行列(Hide, Unhide Cols, Rows) 12. 打印预览。(Print Preivew) 13. 背景图像。(Background Image)(支持bmp,gif,jpg,pcx,tif…) 14. 单元格数字格式、时间格式等等(类似 Excel) 15. 单元格的计算公式或宏代码可以返回数组。 16. 单元格批注。(类似 Excel) 17. 单元格内的文字可以自动换行。 18. 当有多页打印时,可以选择先行后列或者先列后行的打印方式。 19. 页边距设置。 20. 打印页面居中功能。 21. 编辑状态按比例缩放。 22. 单元格内嵌控件(列表框,组合框,日期选择控件,……),目前支持与TdateTimePicker 的互动,计划支持更多控件,计划加入控件属性编辑器,加入控件事件宏功能(2000/12/13) 23. 单元格绝对引用和相对引用的区分,A1,$A1,$A$1(2000/12/13) 24. 拷贝单元格时,自动调整相对引用的单元格。如:Cells[1,1] := ‘=B1’,拷贝到Cells[3,3],则Cells[3,3] := ‘=D3’(2000/12/13) 25. 单元格名称可以使用中文(2000/12/13) 26. 函数分类列表(2000/12/13) 27. 查找替换(2000/12/13) 28. 设计模式(不执行单元格内的公式,但是检查语法和循环引用,显示公式)(2000/12/13) 29. 运行模式(执行单元格内的公式,显示计算结果)(2000/12/13) 30. 增加表格宏功能(原来只有单元格宏功能)。(Macros 属性)(2001/1) 31. 增加带语法加亮功能的宏编辑器。(来自 mwEdit 控件)(2001/1) 32. 给 Delphin 解释器增加 const 常量定义。可以直接在单元格中调用在宏 Macros 中定义的常量和函数。(2001/1) 33. 增加 COUNTIF 、COUNTROWIFCOL 统计函数。(2001/1) 34. 固定行列,类似MS Excel 的标题栏功能。(2001/1/14)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值