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

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


引言

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

p3.jpg (36.74 KB, 下载次数: 2)

下载附件  保存到相册

2017-7-13 13:57 上传




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


工具源码免费下载
本帖隐藏的内容
源码: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#文件如下

ppp1.jpg (32.76 KB, 下载次数: 2)

下载附件  保存到相册

2017-7-13 14:40 上传





反射

上面解析出了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)即可,效果如下:



若您发现其中有问题或任何优化意见,请在本帖留言或私信我,谢谢大家~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别示例代码表格识别
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值