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

摘要:

主要使用Epplus的的表格转换功能,将表格转换成Json,而Unity中Json的使用要搭配对应结构的类,故顺便将利用表格结构生成对应的类,免除人工创建的麻烦过程。

示例:

表格示例:

编辑模式下:
生成Json:

生成Class:
image

运行时数据读取:
image

image

代码

Json数据读取器以及泛型基类
using UnityEngine;
public class JsonDataManager : Singleton<JsonDataManager>
{
    public JsonDataList<T> LoadData<T>()
    {
        string json = Resources.Load<TextAsset>("Json/" + typeof(T).Name).text;
        return JsonUtility.FromJson<JsonDataList<T>>(json);
    }
}
using System.Collections.Generic;
using System;

[Serializable]
public class JsonDataList<T>
{
    public List<T> datas = new List<T>();
}

Excel转换类
using UnityEngine;
using UnityEditor;
using System.IO;
using OfficeOpenXml;
using System.Collections.Generic;
using System;
using System.Text;
/// <summary>
/// 使用EPPlus获取表格数据,同时导出对应的Json以及Class.
/// </summary>
public class ExcelExporter
{
    /// <summary>
    /// Excel表格路径
    /// </summary>
    private const string excelPath = "../Assets/Excels";
    /// <summary>
    /// 导出的Json路径
    /// </summary>
    private const string configPath = "../Assets/Resources/Json";
    /// <summary>
    /// 导出的类路径
    /// </summary>
    private const string classPath = "../Assets/Scripts/Configs";

    /// <summary>
    /// 属性行
    /// </summary>
    private const int propertyIndex = 2;
    /// <summary>
    /// 类型行
    /// </summary>
    private const int typeIndex = 3;
    /// <summary>
    /// 值行
    /// </summary>
    private const int valueIndex = 4;



    [MenuItem("Tools/ExportExcel")]
    private static void ExportConfigs()
    {
        try
        {
            FileInfo[] files = Files.LoadFiles(excelPath);

            foreach (var file in files)
            {
                //过滤文件
                if (file.Extension != ".xlsx") continue;
                ExcelPackage excelPackage = new ExcelPackage(file);
                ExcelWorksheets worksheets = excelPackage.Workbook.Worksheets;
                //只导表1
                ExcelWorksheet worksheet = worksheets[1];

                ExportJson(worksheet, Path.GetFileNameWithoutExtension(file.FullName));
                ExportClass(worksheet, Path.GetFileNameWithoutExtension(file.FullName));

            }
            AssetDatabase.Refresh();
        }
        catch (Exception e)
        {
            Debug.LogError(e.ToString());
        }
    }

    /// <summary>
    /// 导出类
    /// </summary>
    private static void ExportClass(ExcelWorksheet worksheet, string fileName)
    {
        string[] properties = GetProperties(worksheet);
        StringBuilder sb = new StringBuilder();
        sb.Append("using System;\t\n");
        sb.Append("[Serializable]\t\n");
        sb.Append($"public class {fileName}Config\n");//类名
        sb.Append("{\n");

        for (int col = 1; col <= properties.Length; col++)
        {
            string fieldType = GetType(worksheet, col);
            string fieldName = properties[col - 1];
            sb.Append($"\tpublic {fieldType} {fieldName};\n");
        }

        sb.Append("}\n\n");
        Files.SaveFile(classPath, string.Format("{0}Config.cs", fileName), sb.ToString());

    }
    /// <summary>
    /// 导出JSON
    /// </summary>
    private static void ExportJson(ExcelWorksheet worksheet, string fileName)
    {
        string str = "";
        int num = 0;
        string[] properties = GetProperties(worksheet);
        for (int col = 1; col <= properties.Length; col++)
        {
            string[] temp = GetValues(worksheet, col);
            num = temp.Length;
            foreach (var value in temp)
            {
                str += GetJsonK_VFromKeyAndValues(properties[col - 1],
                    Convert(GetType(worksheet, col), value)) + ',';
            }
        }
        //获取key:value的字符串
        str = str.Substring(0, str.Length - 1);
        str = GetJsonFromJsonK_V(str, num);
        str = GetUnityJsonFromJson(str);
        Files.SaveFile(configPath, string.Format("{0}Config.json", fileName), str);
    }

    /// <summary>
    /// 获取属性
    /// </summary>
    private static string[] GetProperties(ExcelWorksheet worksheet)
    {
        string[] properties = new string[worksheet.Dimension.End.Column];
        for (int col = 1; col <= worksheet.Dimension.End.Column; col++)
        {
            if (worksheet.Cells[propertyIndex, col].Text == "")
                throw new System.Exception(string.Format("第{0}行第{1}列为空", propertyIndex, col));
            properties[col - 1] = worksheet.Cells[propertyIndex, col].Text;
        }
        return properties;
    }

    /// <summary>
    /// 获取值
    /// </summary>
    private static string[] GetValues(ExcelWorksheet worksheet, int col)
    {
        //容量减去前三行
        string[] values = new string[worksheet.Dimension.End.Row - 3];
        for (int row = valueIndex; row <= worksheet.Dimension.End.Row; row++)
        {
            values[row - valueIndex] = worksheet.Cells[row, col].Text;
        }
        return values;
    }

    /// <summary>
    /// 获取类型
    /// </summary>
    private static string GetType(ExcelWorksheet worksheet, int col)
    {
        return worksheet.Cells[typeIndex, col].Text;
    }

    /// <summary>
    /// 通过类型返回对应值
    /// </summary>
    private static string Convert(string type, string value)
    {
        string res = "";
        switch (type)
        {
            case "int": res = value; break;
            case "int32": res = value; break;
            case "int64": res = value; break;
            case "long": res = value; break;
            case "float": res = value; break;
            case "double": res = value; break;
            case "string": res = $"\"{value}\""; break;
            default:
                throw new Exception($"不支持此类型: {type}");
        }
        return res;
    }

    /// <summary>
    /// 返回key:value
    /// </summary>
    private static string GetJsonK_VFromKeyAndValues(string key, string value)
    {
        return string.Format("\"{0}\":{1}", key, value);
    }

    /// <summary>
    ///获取[key:value]转换为{key:value,key:value},再变成[{key:value,key:value},{key:value,key:value}]
    /// </summary>
    private static string GetJsonFromJsonK_V(string json, int valueNum)
    {
        string str = "";
        string[] strs;
        List<string> listStr = new List<string>();
        strs = json.Split(',');
        listStr.Clear();
        for (int j = 0; j < valueNum; j++)
        {
            listStr.Add("{" + string.Format("{0},{1}", strs[j], strs[j + valueNum]) + "}");
        }
        str = "[";
        foreach (var l in listStr)
        {
            str += l + ',';
        }
        str = str.Substring(0, str.Length - 1);
        str += ']';
        return str;
    }

    /// <summary>
    /// 适应JsonUtility.FromJson函数的转换格式
    /// </summary>
    private static string GetUnityJsonFromJson(string json)
    {
        return "{" + "\"datas\":" + json + "}";
    }

}

文件读写的辅助类
using UnityEngine;
using System.IO;
using System.Collections.Generic;

public class Files
{
    public static FileInfo[] LoadFiles(string path)
    {
        path = string.Format("{0}/{1}", Application.dataPath, path);

        if (Directory.Exists(path))
        {
            DirectoryInfo directory = new DirectoryInfo(path);
            List<FileInfo> files = new List<FileInfo>();
            foreach (var file in directory.GetFiles("*"))
            {
                if (file.Name.EndsWith(".meta"))
                    continue;
                if (file.Name.StartsWith("~")) continue;

                files.Add(file);
            }
            return files.ToArray();
        }
        else
        {
            throw new System.Exception("路径不存在");
        }
    }

    public static void SaveFile(string path, string fileName, string fileContent)
    {
        path = string.Format("{0}/{1}", Application.dataPath, path);

        if (Directory.Exists(path))
        {
            path = string.Format("{0}/{1}", path, fileName);
            if (File.Exists(path))
            {
                File.Delete(path);
            }
            File.WriteAllText(path, fileContent);
        }
        else
        {
            throw new System.Exception("路径不存在");
        }
    }
}


posted @ 2023-03-29 19:33  C1earF  阅读(598)  评论(0编辑  收藏  举报