Unity 转换 Excel 数据为 Json

一、使用情形

我们往往需要使用策划配置的本地数据,此方法可以使配置的Excel数据转化为json以供使用。

二、解决方案

  1. 需要使用的插件
    在这里插入图片描述

  2. 转化Json 第三方工具

    LitJson 和 Newtonsoft.Json 均可

三、代码

using System.Collections.Generic;
using UnityEngine;
using System.Data;
using System.IO;
using Excel;
using Newtonsoft.Json.Linq;
using System;
using UnityEditor;

public class ExcelEditor
{

    /// <summary>
    /// 表格的存放位置
    /// </summary>
    static string configPath = Application.dataPath.Replace("Assets", "Excel");

    /// <summary>
    /// 实体类模板存放位置
    /// </summary>
    static string scriptsPath = "/Scripts/Config/";

    /// <summary>
    /// json文件存放位置
    /// </summary>
    static string jsonPath = "/Resources/Json/";

    /// <summary>
    /// 表格数据列表
    /// </summary>
    static List<TableData> dataList = new List<TableData>();



    /// <summary>
    /// 遍历文件夹,读取所有表格
    /// </summary>
    [UnityEditor.MenuItem("Tools / ReadExcel")]
    public static void ReadExcel()
    {
        if (Directory.Exists(configPath))
        {
            //获取指定目录下所有的文件
            DirectoryInfo direction = new DirectoryInfo(configPath);
            FileInfo[] files = direction.GetFiles("*", SearchOption.AllDirectories);
            Debug.Log("fileCount:" + files.Length);

            for (int i = 0; i < files.Length; i++)
            {
                if (files[i].Name.EndsWith(".meta") || !files[i].Name.EndsWith(".xlsx"))
                {
                    continue;
                }
                Debug.Log("FullName:" + files[i].FullName);
                LoadData(files[i].FullName, files[i].Name);

                //刷新本地资源
                AssetDatabase.Refresh();
            }
        }
        else
        {
            Debug.LogError("ReadExcel configPath not Exists!");
        }
    }

    /// <summary>
    /// 读取表格并保存脚本及json
    /// </summary>
    static void LoadData(string filePath, string fileName)
    {
        //获取文件流
        FileStream fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read);
        //生成表格的读取
        IExcelDataReader excelDataReader = ExcelReaderFactory.CreateOpenXmlReader(fileStream);
        // 表格数据全部读取到result里(引入:DataSet(using System.Data;)
        DataSet result = excelDataReader.AsDataSet();

        CreateTemplate(result, fileName);

        CreateJson(result, fileName);
    }

    /// <summary>
    /// 生成json文件
    /// </summary>
    static void CreateJson(DataSet result, string fileName)
    {
        // 创建目录
        if (!Directory.Exists(Application.dataPath + jsonPath))
        {
            Directory.CreateDirectory(Application.dataPath + jsonPath);
        }

        // 获取表格有多少列 
        int columns = result.Tables[0].Columns.Count;
        // 获取表格有多少行 
        int rows = result.Tables[0].Rows.Count;

        TableData tempData;
        string value;
        JArray array = new JArray();

        //第一行为表头,第三行为类型 ,第二行为字段名 不读取
        for (int i = 3; i < rows; i++)
        {
            for (int j = 0; j < columns; j++)
            {
                // 获取表格中指定行指定列的数据 
                value = result.Tables[0].Rows[i][j].ToString();

                //if (string.IsNullOrEmpty(value))
                //{
                //    continue;
                //}
                tempData = new TableData();
                tempData.type = result.Tables[0].Rows[2][j].ToString();
                tempData.fieldName = result.Tables[0].Rows[1][j].ToString();
                tempData.value = value;

                dataList.Add(tempData);
            }

            if (dataList != null && dataList.Count > 0)
            {
                JObject tempo = new JObject();
                foreach (var item in dataList)
                {
                    //Debug.Log(item.type + " = " + item.value);
                    switch (item.type)
                    {
                        case "string":
                            if (item.value == null)
                            {
                                tempo[item.fieldName] = "";
                            }
                            else
                            {
                                tempo[item.fieldName] = GetValue<string>(item.value);
                            }                            
                            break;
                        case "int":                            
                            if (string.IsNullOrEmpty(item.value))
                            {
                                tempo[item.fieldName] = 0;
                            }
                            else
                            {
                                tempo[item.fieldName] = GetValue<int>(item.value);
                            }
                            break;
                        case "float":
                            if (string.IsNullOrEmpty(item.value))
                            {
                                tempo[item.fieldName] = 0;
                            }
                            else
                            {
                                tempo[item.fieldName] = GetValue<float>(item.value);
                            }
                            break;
                        case "bool":
                            if (string.IsNullOrEmpty(item.value))
                            {
                                tempo[item.fieldName] = false;
                            }
                            else
                            {
                                tempo[item.fieldName] = GetValue<bool>(int.Parse(item.value));
                            }
                            break;
                        case "string[]":
                            tempo[item.fieldName] = new JArray(GetList<string>(item.value, ','));
                            break;
                        case "int[]":
                            tempo[item.fieldName] = new JArray(GetList<int>(item.value, ','));
                            break;
                        case "float[]":
                            tempo[item.fieldName] = new JArray(GetList<float>(item.value, ','));
                            break;
                        case "bool[]":
                            tempo[item.fieldName] = new JArray(GetList<bool>(item.value, ','));
                            break;
                    }
                }

                if (tempo != null)
                    array.Add(tempo);
                dataList.Clear();
            }
        }

        JObject o = new JObject();
        o["datas"] = array;
        //o["version"] = "20200331";
        fileName = fileName.Replace(".xlsx", "");
        var jsonAddress = Application.dataPath + jsonPath + fileName + ".json";
        if (File.Exists(jsonAddress))
        {
            File.Delete(jsonAddress);
        }

        File.WriteAllText(Application.dataPath + jsonPath + fileName + ".json", o.ToString());
    }


    /// <summary>
    /// 字符串拆分列表
    /// </summary>
    static List<T> GetList<T>(string str, char spliteChar)
    {
        string[] ss = str.Split(spliteChar);
        int length = ss.Length;
        List<T> arry = new List<T>(ss.Length);
        for (int i = 0; i < length; i++)
        {
            if (!string.IsNullOrEmpty(ss[i]))
            {
                arry.Add(GetValue<T>(ss[i]));
            }            
        }
        return arry;
    }

    static T GetValue<T>(object value)
    {
        return (T)Convert.ChangeType(value, typeof(T));
    }

    /// <summary>
    /// 生成实体类模板
    /// </summary>
    static void CreateTemplate(DataSet result, string fileName)
    {
        // 创建目录
        if (!Directory.Exists(Application.dataPath + scriptsPath))
        {
            Directory.CreateDirectory(Application.dataPath + scriptsPath);
        }

        field = "";
        for (int i = 0; i < result.Tables[0].Columns.Count; i++)
        {
            string typeStr = result.Tables[0].Rows[2][i].ToString();
            typeStr = typeStr.ToLower();
            if (typeStr.Contains("[]"))
            {
                typeStr = typeStr.Replace("[]", "");
                typeStr = string.Format(" List<{0}>", typeStr);
            }

            string nameStr = result.Tables[0].Rows[1][i].ToString();
            if (string.IsNullOrEmpty(typeStr) || string.IsNullOrEmpty(nameStr)) continue;
            field += "public " + typeStr + " " + nameStr + " { get; set; }\r\t\t";
        }

        fileName = fileName.Replace(".xlsx", "");
        string tempStr = Eg_str;
        tempStr = tempStr.Replace("@Name", fileName);
        tempStr = tempStr.Replace("@File1", field);

        var templatePath = Application.dataPath + scriptsPath + fileName + ".cs";
        if (File.Exists(templatePath))
        {
            File.Delete(templatePath);
        }

        File.WriteAllText(Application.dataPath + scriptsPath + fileName + ".cs", tempStr);

    }

    /// <summary>
    /// 字段
    /// </summary>
    static string field;

    /// <summary>
    /// 实体类模板
    /// </summary>
    static string Eg_str =

        "using System.Collections.Generic;\r" +
        "using UnityEngine;\r" +
        "using Newtonsoft.Json;\r\r" +
        "public class @Name  {\r\r\t\t" +
        "@File1 \r\t\t" +
        "public static string configName = \"@Name\";\r\t\t" +
        "public static @Name config { get; set; }\r\t\t" +
        //"public string version { get; set; }\r\t\t" +
        "public List<@Name> datas { get; set; }\r\r\t\t" +
        //"public static void Init()\r\t\t{\r\t\t\tConfigManager.Ins.Readjson(configName, (json) => {\r\t\t\tif (!string.IsNullOrEmpty( json))\r\t\t\t{\r\t\t\t\t config = JsonConvert.DeserializeObject<@Name>(json);\r\t\t\t\t PlayerPrefs.SetString(\"brother_\" + configName, config.version);\r\t\t\t}\r\t\t\t}, false);\r\t\t }\r\r\t\t" +
        "public static @Name Get(int id)\r\t\t{\r\t\t\tforeach (var item in config.datas)\r\t\t\t{\r\t\t\t\tif (item.ID == id)\r\t\t\t\t{ \r\t\t\t\t\treturn item;\r\t\t\t\t}\r\t\t\t}\r\t\t\treturn null;\r\t\t}\r"
         + "\r}";
}

public struct TableData
{
    public string fieldName;
    public string type;
    public string value;

    public override string ToString()
    {
        return string.Format("fieldName:{0} type:{1} value:{2}", fieldName, type, value);
    }
}

四、使用方法

  1. 表格样式
    在这里插入图片描述
    第一行为描述,第二行是变量名,第三行为类型。

  2. 生成的Json 也 实例类
    json
    在这里插入图片描述

五、demo

https://download.csdn.net/download/weixin_56130753/88411604

后续有网盘地址或者git地址会更新

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值