首页 前端知识 unity实现支持一维二维数组的excel转json工具

unity实现支持一维二维数组的excel转json工具

2024-08-08 22:08:48 前端知识 前端哥 97 202 我要收藏

unity实现支持一维二维数组的excel转接工具

    • 导表工具的用处
      • 支持数组建模
      • 支持注释
    • 可以导表的所有类型标识符
    • sheet命名规范
    • 编辑器使用
    • App使用
    • 代码思路
    • 如何打包runtime
    • 源码

导表工具的用处

支持数组建模

游戏开发中,策划和程序的沟通一直是比较关键的一个流程。策划提出一个需求如果涉及很多数据,想要快速的传达给程序猿最快速的方式就是写好功能描述,并附上数据表。基础的方式就是找个excel转json的网站,导出json数据。或者在unity写脚本将excel表格转换为json。但是很多时候去求仅仅用过一张表很难描述完全的。比如想要表达一个活动,这个活动多个模块,每个模块完成之后可以领多个类型的奖励,并且每个类型都有不同数量。如果用最基础的导表方式,一张表是表达不出这么多层信息的。每一行肯定来表示一个模块,那奖励怎么写呢只能把每个奖励类型都列出一列,然后用数量表达存在这项奖励与否和奖励数量,而且不管这个奖励类型在不在奖励项里面也必须占用一列,并用奖励数量为0来表示不存在这个奖励项,而且代码中还要通过判断奖励数量是否为0来判断有没有这项奖励。传统表格建模方式如下:传统建模方式
而支持二位数组输入的建模方式就会优雅很多,可以和上一个做一下对比
二维数组方式对奖励列表建模
这样大大减少了无用数据的占用,也减少了程序判断数量的过程,直接遍历数组就行了

支持注释

很多时候给出一个数据表但不能对每个属性进行一个很好的解释也不行的,这样还要花费时间进行人工讲解或者写一大堆文字描述来解释。显然这两种方法都不太合理,人工讲解需要双方抽出空闲时间,然后还要保证讲解后能记住,文字描述因为缺乏位置指向性,无法直观的看出看出属性和和表述的映射关系。只有用注释的方式放在属性上方最能直观的表述属性达标的含义。![在这里插入在这里插入图片描述
那么我想把某一模块的某一属性注释一下怎么做呢?也很简单,只要在该列不设置属性名和属性类型名就不会被转成json,默认跳过。
在这里插入图片描述

那么我想把一大块区域作为注释怎么办呢?也很容易,只要在行开头用“//”来标识,就会默认把整行作为注释。在这里插入图片描述

可以导表的所有类型标识符

string
float
bool
int
double
list
list
list
list
list
list<list>
list<list>
list<list>
List<list>
list<list>

sheet命名规范

包含以#开头#结尾的字符串,就会被识别为需要转换的页签,否则会跳过
正确示例:
所有类型#AllTypeExample#
#OfflinePhaseV2#
错误示例:
#OfflinePhaseV2
OfflinePhaseV2#
OfflinePhaseV2

编辑器使用

在这里插入图片描述

在这里插入图片描述

App使用

为了方便策划使用,套了个runtime的ui,操作和editor大差不差。mac和windows一样的。
在这里插入图片描述

代码思路

主要使用第三库ExcelDataReader将xlsx文件转成DataSet所以先引入三分库
链接: ExcelDataReader
这个库还依赖ICSharpCode.SharpZipLib
所以也引进来
链接: ICSharpCode.SharpZipLib
以下是转换成DataSet的写法。

/// <summary>
	/// 表格数据集合
	/// </summary>
	private DataSet mResultSet;

	/// <summary>
	/// 构造函数
	/// </summary>
	/// <param name="excelFile">Excel file.</param>
	public ExcelUtility(string excelFile)
    {
        var stream = File.Open(excelFile, FileMode.Open, FileAccess.Read);
        var reader = ExcelReaderFactory.CreateReader(stream);
        mResultSet = reader.AsDataSet();
        reader.Close();
        stream.Close();

    }

转换成DataSet后我们就可以对Dataset的行列进行调用解析了,
第0行是属性注释,第一行是属性名字

string fieldName = mSheet.Rows [1] [j].ToString();

首列出现“//”为注释

//如果是空或者标注为"//"略过
                if (RowIsNull(mSheet.Rows[i]) ||
                mSheet.Rows[i][0].ToString() == "//"
                )
                {
                    continue;
                }

开始转换数据

//准备一个字典存储每一行的数据
               Dictionary<string, object> row = new Dictionary<string, object> ();
               for (int j = 0; j < colCount; j++)
               {
                   //读取第1行数据作为字段名字
                   string field = mSheet.Rows [1] [j].ToString();
   				field = field.Trim();

   				string typestring = mSheet.Rows [2] [j].ToString();
   				typestring = typestring.ToLower().Trim();

   				string valuestr = mSheet.Rows[i][j].ToString();
   				valuestr = valuestr.Trim();
   				//Key-Value对应 按类型存放
   				switch(typestring)
                   {
                       case "int":
                           //todo
                           break;
                       case "float":
                       	//todo
                       	brealk;
                    	case "string":
                       	//todo
                       	brealk;

   						~~~~~~
   						~~~~~~
                      }

细节就是用到了一些正则进行匹配,然后进行转换类型,这里提一下我用到的字符串转数组的优雅方式,因为优雅所以喜欢。

//转换委托
delegate T Parse<T>(string s);

//转换泛型方法
List<T> ParseStrToList<T>(string s, Parse<T> parse)
   {
       string[] strlist = null;
   	//字符串列表,用双引号包裹每个元素
   	if(typeof(T) == typeof(string))
       {
           MatchCollection elements = Regex.Matches(s, "\"(.*?)\"");
   		strlist=new string[elements.Count];
   		for (int i = 0; i < elements.Count; i++)
   		{
               strlist[i] = elements[i].Value.Trim('"');
           }
       }
       //别的类型列表, 用逗号分隔每个元素
       else
       {
           strlist = Regex.Split(s, ",");
       }

       List<T> res = new List<T>();
       for (int k = 0; k < strlist.Length; k++)
       {
           if (strlist[k] != "")
           {
               res.Add(parse(strlist[k].Trim()));
           }

       }
       return res;
   }
//示例
public void Example()
   {
       string str = "1,2,3,4";
       char[] headTrail = new char[2] { '[', ']' };
       //转int[]
       ParseStrToList<int>(str.Trim(headTrail), int.Parse);
       //转float[]
       ParseStrToList<float>(str.Trim(headTrail), float.Parse);
       //转double[]
       ParseStrToList<double>(str.Trim(headTrail), double.Parse);
       //转bool[]
       ParseStrToList<bool>(str.Trim(headTrail), BoolParse);
       //转string[]
       ParseStrToList<string>(str.Trim(headTrail), s => s);

       bool BoolParse(string s)
       {
           if (s == "0" || s.ToLower() == "false" || s == "")
           {
               return false;
           }
           else
           {
               return true;
           }
       }
   }

如何打包runtime

打包runtime主要阻碍有,选择文件夹路径、跳转文件夹、以及让导表工具runtime能运行。
文件夹目录操作用到的三方插件是
StandaloneFileBrowser

链接: StandaloneFileBrowser
导表工具runtime运行我是加入了这两个dll
在这里插入图片描述

源码

最后附上工程
欢迎指正

链接: keqikeqi/unity_excel_to_json.git

转载请注明出处或者链接地址:https://www.qianduange.cn//article/15066.html
评论
发布的文章

安装Nodejs后,npm无法使用

2024-11-30 11:11:38

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!