Unity 之 Excel表格转换为Unity用的文件格式 -- ScriptableObject,Json,XML 全部搞定

Posted 陈言必行

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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_idtask_describetask_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中的所有数据,都被保存到ExcelManagerExcelItem[] 类型的数组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格式的文件了:


五,使用小结

  1. Excel转换为上面三种格式的准备工作是一致的
    都需要对Excel进行读取存储,若表头有改动则需要更改ExcelItem类的对应数据

    还需要修改ExcelTool.CreateItemArrayWithExcel存储方法:

  2. 在编写转换XML格式的文件时的拓展方法写的具体,若有大量的改动会很麻烦,建议使用转换为JSON格式的拓展方法,然后通过工具进行JSON到XML格式的转换,比如:


工具目录:

Excel的动态链接库:获取链接
转换工具源码分享:获取链接
积分不足的小伙伴,可以私信我哦~

以上是关于Unity 之 Excel表格转换为Unity用的文件格式 -- ScriptableObject,Json,XML 全部搞定的主要内容,如果未能解决你的问题,请参考以下文章

Unity中解析Excel表格工具

Unity中基于EPPLUS的Excel转换以及Json数据读取

Unity直接读取Excel之Unity quick sheet

Unity安装配置Python使用protobuf转换Excel表格数据并在unit中使用

Unity安装配置Python使用protobuf转换Excel表格数据并在unit中使用

Unity3D读取之——读取Excel文件内容