Unity 之 Excel表格转换为Unity用的文件格式 -- ScriptableObject,Json,XML 全部搞定
前言
最近工作中遇到的一个问题,其他同事在网上抓来的数据保存为Excel表格,需要在Unity中进行使用其中的数据进行开发。有些经验的同学都知道Unity是可以对Excel进行操作的,由于我Excel并不是Unity中常用的数据格式,并且相同数量级的情况下其他数据格式会比Excel更节省内存空间,于是有了这篇文章 – Excel表格转换为Unity用的文件格式。由于需求和个人习惯的不同,我这里为大家提供了转换为三种格式的方法 – ScriptableObject,Json,XML。
一,准备工作
1.1 确认表格表头
既然是Excel进行格式转换,首先要有一个Excel表格吧,所以新建一个Excel:(注意:后缀是.xlsx)
模拟数据编写如下:
这时表头就确定好了:
任务ID | 任务描述 | 任务奖励 |
---|---|---|
task_id | task_describe | task_reward |
1.2 读取Excel
- 导入用到的dll库
没有的童鞋文末获取:
- 引用命名空间:
using Excel;
- 编写读取方法:
/// <summary>
/// 处理Excel工具类
/// </summary>
public class ExcelTool
{
/// <summary>
/// 读取excel文件内容
/// </summary>
/// <param name="filePath">文件路径</param>
/// <param name="columnNum">行数</param>
/// <param name="rowNum">列数</param>
/// <returns></returns>
static DataRowCollection ReadExcelContext(string filePath, ref int columnNum, ref int rowNum)
{
FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
// Debug.Log(stream == null);
IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
DataSet result = excelReader.AsDataSet();
// Tables[0] 下标0表示excel文件中第一张表的数据
columnNum = result.Tables[0].Columns.Count;
rowNum = result.Tables[0].Rows.Count;
return result.Tables[0].Rows;
}
}
1.3 存储数据
按照1.1确认的表头,写一个数据类:
/// <summary>
/// 数据序列化类 -- 和Excel列一一对应
/// </summary>
[System.Serializable]
public class ExcelItem
{
public int task_id;
public string task_describe;
public string task_reward;
}
再添加一个数据管理类,作为读出来的所有数据的和,最后也是将它转换为我们要存储的格式。
一开始使我是这样写的:
public class ExcelManager
{
public static ExcelItem[] dataArray;
}
不过后来为了兼容转换为ScriptableObject格式改成了如下写法:
public class ExcelManager : ScriptableObject
{
public ExcelItem[] dataArray;
}
最后转化格式的原理是一样的,只是在调用上略有不同。
有了上面两个类之后,我们将在Excel中读出来的数据存储起来,在ExcelTool
类中编写方法:
/// <summary>
/// 读取表数据,生成对应的数组
/// </summary>
/// <param name="filePath">excel文件全路径</param>
/// <returns>Item数组</returns>
public static ExcelItem[] CreateItemArrayWithExcel(string filePath)
{
//获得表数据
int columnNum = 0, rowNum = 0;
Debug.Log(filePath);
DataRowCollection collect = ReadExcelContext(filePath, ref columnNum, ref rowNum);
Debug.Log("读取到数据表 列数 columnNum : " + columnNum + " ,行数 rowNum: " + rowNum);
// 第一行是标题(头)
//for (int i = 0; i < columnNum; i++)
//{
// rowTitleList.Add(collect[0][i].ToString());
//}
//第二行开始才是数据
ExcelItem[] array = new ExcelItem[rowNum - 1];
for (int i = 1; i < rowNum; i++)
{
ExcelItem item = new ExcelItem();
//解析每列的数据
item.task_id = int.Parse(collect[i][0].ToString());
item.task_describe = collect[i][1].ToString();
item.task_reward = collect[i][2].ToString();
array[i - 1] = item;
}
return array;
}
至此在Excel中的所有数据,都被保存到ExcelManager
中 ExcelItem[]
类型的数组dataArray
中了。
1.4 配置文件类
为了方便后续使用,我定义了一个配置文件类,用来存储读取Excel文件路径,文件名 和保存其他格式文件的路径和文件名称,这样以后有路径更改的时候,只需要在这个类中进行修改就可以了。
public class ExcelConfig
{
/// <summary>
/// 存放excel表文件夹的的路径,本例Excel表放在了"Assets/Excels/"当中
/// </summary>
public static readonly string excelsFolderPath = Application.dataPath + "/ReadExcel/";
/// <summary>
/// 要读取的Excel文件名称 -- 后缀为xlsx
/// </summary>
public static readonly string excelName = "TaskConfig.xlsx";
/// <summary>
/// 存放Excel转化后文件的文件夹路径
/// </summary>
public static readonly string assetPath = "Assets/ReadExcel/";
/// <summary>
/// 保存处理后数据文件名称
/// </summary>
public static readonly string saveName = "TaskConfig";
}
二,转换为ScriptableObject
在编辑器拓展中处理格式转换,这样有数据更新,就只需要替换Excel文件,然后点点按钮就可以更新文件了。
创建"Editor"文件夹,在其下创建“ExcelBuild”脚本,编写拓展方法代码如下:
using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml;
using UnityEditor;
using UnityEngine;
// <summary>
/// 编辑器扩展 将xlsx文件转换为其他格式
/// </summary>
public class ExcelBuild : Editor
{
/// <summary>
/// 转换为 ScriptableObject
/// </summary>
[MenuItem("CustomEditor/CreateExcelAsset")]
public static void CreateItemAsset() {
ExcelManager excelManager = CreateInstance<ExcelManager>();
//赋值
excelManager.dataArray = ExcelTool.CreateItemArrayWithExcel(ExcelConfig.excelsFolderPath + ExcelConfig.excelName);
// 确保文件夹存在
if(!Directory.Exists(ExcelConfig.assetPath)) {
Directory.CreateDirectory(ExcelConfig.assetPath);
}
// asset文件的路径 要以"Assets/..."开始,否则CreateAsset会报错
string assetPath = string.Format("{0}{1}.asset", ExcelConfig.assetPath, ExcelConfig.saveName);
// 生成一个Asset文件
AssetDatabase.CreateAsset(excelManager, assetPath);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
}
最后点击“CustomEditor” --> “CreateExcelAsset” 既可以得到.asset格式的文件了:
三,转换为Json
若你跳过了2步骤,则需要创建"Editor"文件夹,在其下创建“ExcelBuild”脚本,若为跳过,则直接“ExcelBuild”,添加方法即可
编写拓展方法代码如下:
using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml;
using UnityEditor;
using UnityEngine;
// <summary>
/// 编辑器扩展 将xlsx文件转换为其他格式
/// </summary>
public class ExcelBuild : Editor
{
/// <summary>
/// 转换为 JSON
/// </summary>
[MenuItem("CustomEditor/CreateExcelJson")]
public static void CreateExcelJson()
{
ExcelManager excelManager = CreateInstance<ExcelManager>();
//赋值
excelManager.dataArray = ExcelTool.CreateItemArrayWithExcel(ExcelConfig.excelsFolderPath + ExcelConfig.excelName);
// 文件保存路径
string filePath = ExcelConfig.assetPath + ExcelConfig.saveName + ".json";
// 找到当前路径
FileInfo file = new FileInfo(filePath);
// 判断有没有文件,有则打开文件,没有创建后打开文件
StreamWriter sw = file.CreateText();
// ToJson接口将你的列表类传进去,并自动转换为string类型
string json = JsonUtility.ToJson(excelManager);
// 转码
Regex reg = new Regex(@"(?i)\\[uU]([0-9a-f]{4})");
json = reg.Replace(json, delegate (Match m) { return ((char)Convert.ToInt32(m.Groups[1].Value, 16)).ToString(); });
// 将转换好的字符串存进文件,
sw.WriteLine(json);
// 注意释放资源
sw.Close();
sw.Dispose();
AssetDatabase.Refresh();
}
}
最后点击“CustomEditor” --> “CreateExcelJson” 既可以得到.json格式的文件了:
四,转换为XML
若你跳过了2步骤,则需要创建"Editor"文件夹,在其下创建“ExcelBuild”脚本,若为跳过,则直接“ExcelBuild”,添加方法即可
编写拓展方法代码如下:
using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml;
using UnityEditor;
using UnityEngine;
// <summary>
/// 编辑器扩展 将xlsx文件转换为其他格式
/// </summary>
public class ExcelBuild : Editor
{
/// <summary>
/// 转换为 XML
/// </summary>
[MenuItem("CustomEditor/CreateExcelXML")]
public static void CreateExcelXML()
{
ExcelManager excelManager = CreateInstance<ExcelManager>();
//赋值
excelManager.dataArray = ExcelTool.CreateItemArrayWithExcel(ExcelConfig.excelsFolderPath + ExcelConfig.excelName);
// 文件保存路径
string filePath = ExcelConfig.assetPath + ExcelConfig.saveName + ".XML";
XmlDocument doc = new XmlDocument();
//创建根节点
XmlElement root = doc.CreateElement("root");
// 设置根节点
doc.AppendChild(root);
for (int i = 0; i < excelManager.dataArray.Length; i++)
{
// 一级子节点
XmlElement data = doc.CreateElement("Data");
// 设置和根节点的关系
root.AppendChild(data);
//创建数据子节点
XmlElement itemId = doc.CreateElement("task_id");
XmlElement itemDescribe = doc.CreateElement("task_describe");
XmlElement itemReward = doc.CreateElement("task_reward");
// 设置节点间关系
data.AppendChild(itemId);
data.AppendChild(itemDescribe);
data.AppendChild(itemReward);
// 数据负值
itemId.InnerText = excelManager.dataArray[i].task_id.ToString();
itemDescribe.InnerText = excelManager.dataArray[i].task_describe;
itemReward.InnerText = excelManager.dataArray[i].task_reward;
}
// 保存到本地
doc.Save(filePath);
AssetDatabase.Refresh();
}
}
最后点击“CustomEditor” --> “CreateExcelXML” 既可以得到.XML格式的文件了:
五,使用小结
-
Excel转换为上面三种格式的准备工作是一致的
都需要对Excel进行读取存储,若表头有改动则需要更改ExcelItem
类的对应数据
还需要修改ExcelTool.CreateItemArrayWithExcel
存储方法:
-
在编写转换XML格式的文件时的拓展方法写的具体,若有大量的改动会很麻烦,建议使用转换为JSON格式的拓展方法,然后通过工具进行JSON到XML格式的转换,比如:
工具目录:
- 点赞
- 收藏
- 关注作者
评论(0)