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