8.生成包含字典的容器类

8.Excel表自动生成相关文件-生成容器类


8.1 知识点

定义容器类脚本存储位置路径

/// <summary>
/// 容器类脚本存储位置路径
/// </summary>
public static string DATA_CONTAINER_PATH = Application.dataPath + "/Scripts/ExcelData/Container/";

创建生成Excel表对应的数据容器类函数,在生成Excel信息的菜单项函数调用

/// <summary>
/// 生成Excel表对应的数据容器类
/// </summary>
/// <param name="table"></param>
private static void GenerateExcelContainer(DataTable table)
{
    // 生成Excel信息的菜单项函数
    [MenuItem("GameTool/GenerateExcel")]
    private static void GenerateExcelInfo()
    {
        ...
        // 遍历文件中的所有表的信息
        foreach (DataTable table in tableConllection)
        {
            Debug.Log(table.TableName);

            // 生成数据结构类
            GenerateExcelDataClass(table);

            // 生成容器类
            GenerateExcelContainer(table);

            // 生成二进制数据
        }
    }
}


/// <summary>
/// 生成Excel表对应的数据容器类
/// </summary>
/// <param name="table"></param>
private static void GenerateExcelContainer(DataTable table)
{

}

创建获取主键索引函数,方便等一下在生成Excel表对应的数据容器类函数调用。获取表的第三行数据(索引从0开始),即字段类型所在行,遍历表的所有列,判断当前列的值是否等于”key”,如果是主键列,则返回列索引, 如果没有找到主键列,则返回默认值0。

/// <summary>
/// 获取主键索引
/// </summary>
/// <param name="table"></param> // 传入一个DataTable对象,表示数据表
/// <returns></returns> // 返回一个整型值,表示主键所在的列索引
private static int GetKeyIndex(DataTable table)
{
    // 获取表的第三行数据(索引从0开始),即字段类型所在行
    DataRow row = table.Rows[2];

    // 遍历表的所有列
    for (int i = 0; i < table.Columns.Count; i++)
    {
        // 判断当前列的值是否等于"key",即判断是否是主键列
        if (row[i].ToString() == "key")
            return i; // 如果是主键列,则返回列索引
    }

    // 如果没有找到主键列,则返回默认值0
    return 0;
}

在生成Excel表对应的数据容器类函数中,通过获取主键索引函数获得组件索引。 获取字段类型所在行。判断容器存储路径存不存在,如果路径不存在,则创建路径。字符串拼接容器类,导入所需命名空间,生成数据容器类的代码字符串,声明数据字典并初始化。将代码字符串写入文件,文件名为表名加上”Container.cs”。刷新Unity的Project窗口。

/// <summary>
/// 生成Excel表对应的数据容器类
/// </summary>
/// <param name="table"></param>
private static void GenerateExcelContainer(DataTable table)
{
    // 获取主键索引
    int keyIndex = GetKeyIndex(table);

    // 获取字段类型所在行
    DataRow rowType = GetVariableTypeRow(table);

    // 如果路径不存在,则创建路径
    if (!Directory.Exists(DATA_CONTAINER_PATH))
        Directory.CreateDirectory(DATA_CONTAINER_PATH);

    // 导入所需命名空间
    string str = "using System.Collections.Generic;\n";

    // 生成数据容器类的代码字符串
    str += "public class " + table.TableName + "Container" + "\n{\n";

    // 声明数据字典并初始化
    str += "    ";
    str += "public Dictionary<" + rowType[keyIndex].ToString() + ", " + table.TableName + ">";
    str += "dataDic = new " + "Dictionary<" + rowType[keyIndex].ToString() + ", " + table.TableName + ">();\n";

    str += "}";

    // 将代码字符串写入文件,文件名为表名加上"Container.cs"
    File.WriteAllText(DATA_CONTAINER_PATH + table.TableName + "Container.cs", str);

    // 刷新Unity的Project窗口
    AssetDatabase.Refresh();
}

8.2 知识点代码

ExcelTool

using Excel;  // 导入Excel命名空间,用来读取和操作Excel文件
using System.Collections;
using System.Collections.Generic;
using System.Data;  // 导入System.Data命名空间,用来使用DataTable等数据结构
using System.IO;  // 导入System.IO命名空间,用来进行文件的读写操作
using UnityEditor;  // 导入UnityEditor命名空间,用来刷新Project窗口
using UnityEngine;  // 导入UnityEngine命名空间,用来获取应用程序路径

public class ExcelTool
{
    /// <summary>
    /// excel文件存放的路径
    /// </summary>
    public static string EXCEL_PATH = Application.dataPath + "/ArtRes/Excel/";

    /// <summary>
    /// 数据结构类脚本存储位置路径
    /// </summary>
    public static string DATA_CLASS_PATH = Application.dataPath + "/Scripts/ExcelData/DataClass/";

    /// <summary>
    /// 容器类脚本存储位置路径
    /// </summary>
    public static string DATA_CONTAINER_PATH = Application.dataPath + "/Scripts/ExcelData/Container/";

    // 生成Excel信息的菜单项函数
    [MenuItem("GameTool/GenerateExcel")]
    private static void GenerateExcelInfo()
    {
        // 创建存放Excel文件的目录
        DirectoryInfo dInfo = Directory.CreateDirectory(EXCEL_PATH);
        // 获取目录下的所有文件信息,相当于得到所有的Excel表
        FileInfo[] files = dInfo.GetFiles();
        // 数据表容器
        DataTableCollection tableConllection;
        for (int i = 0; i < files.Length; i++)
        {
            // 如果不是Excel文件就不处理
            if (files[i].Extension != ".xlsx" &&
                files[i].Extension != ".xls")
                continue;
            // 打开一个Excel文件并获取其中的表数据
            using (FileStream fs = files[i].Open(FileMode.Open, FileAccess.Read))
            {
                IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(fs);
                tableConllection = excelReader.AsDataSet().Tables;
                fs.Close();
            }

            // 遍历文件中的所有表的信息
            foreach (DataTable table in tableConllection)
            {
                Debug.Log(table.TableName);
                // 生成数据结构类
                GenerateExcelDataClass(table);
                // 生成容器类
                GenerateExcelContainer(table);
                // 生成二进制数据
            }
        }
    }

    /// <summary>
    /// 生成Excel表对应的数据结构类
    /// </summary>
    /// <param name="table"></param>
    private static void GenerateExcelDataClass(DataTable table)
    {
        // 获取字段名所在行
        DataRow rowName = GetVariableNameRow(table);
        // 获取字段类型所在行
        DataRow rowType = GetVariableTypeRow(table);

        // 判断路径是否存在,如果不存在则创建文件夹
        if (!Directory.Exists(DATA_CLASS_PATH))
            Directory.CreateDirectory(DATA_CLASS_PATH);
        // 如果要生成数据结构类脚本,实际上是通过代码进行字符串拼接,然后存入文件中
        string str = "public class " + table.TableName + "\n{\n";

        // 进行变量的字符串拼接
        for (int i = 0; i < table.Columns.Count; i++)
        {
            str += "    public " + rowType[i].ToString() + " " + rowName[i].ToString() + ";\n";
        }

        str += "}";

        // 将拼接好的字符串存入指定文件中
        File.WriteAllText(DATA_CLASS_PATH + table.TableName + ".cs", str);

        // 刷新Project窗口
        AssetDatabase.Refresh();
    }

    /// <summary>
    /// 生成Excel表对应的数据容器类
    /// </summary>
    /// <param name="table"></param>
    private static void GenerateExcelContainer(DataTable table)
    {
        // 获取主键索引
        int keyIndex = GetKeyIndex(table);

        // 获取字段类型所在行
        DataRow rowType = GetVariableTypeRow(table);

        // 如果路径不存在,则创建路径
        if (!Directory.Exists(DATA_CONTAINER_PATH))
            Directory.CreateDirectory(DATA_CONTAINER_PATH);

        // 导入所需命名空间
        string str = "using System.Collections.Generic;\n";

        // 生成数据容器类的代码字符串
        str += "public class " + table.TableName + "Container" + "\n{\n";

        // 声明数据字典并初始化
        str += "    ";
        str += "public Dictionary<" + rowType[keyIndex].ToString() + ", " + table.TableName + ">";
        str += "dataDic = new " + "Dictionary<" + rowType[keyIndex].ToString() + ", " + table.TableName + ">();\n";

        str += "}";

        // 将代码字符串写入文件,文件名为表名加上"Container.cs"
        File.WriteAllText(DATA_CONTAINER_PATH + table.TableName + "Container.cs", str);

        // 刷新Unity的Project窗口
        AssetDatabase.Refresh();
    }

    /// <summary>
    /// 获取变量名所在行
    /// </summary>
    /// <param name="table"></param>
    /// <returns></returns>
    private static DataRow GetVariableNameRow(DataTable table)
    {
        return table.Rows[0];
    }

    /// <summary>
    /// 获取变量类型所在行
    /// </summary>
    /// <param name="table"></param>
    /// <returns></returns>
    private static DataRow GetVariableTypeRow(DataTable table)
    {
        return table.Rows[1];
    }


    /// <summary>
    /// 获取主键索引
    /// </summary>
    /// <param name="table"></param> // 传入一个DataTable对象,表示数据表
    /// <returns></returns> // 返回一个整型值,表示主键所在的列索引
    private static int GetKeyIndex(DataTable table)
    {
        // 获取表的第三行数据(索引从0开始),即字段类型所在行
        DataRow row = table.Rows[2];

        // 遍历表的所有列
        for (int i = 0; i < table.Columns.Count; i++)
        {
            // 判断当前列的值是否等于"key",即判断是否是主键列
            if (row[i].ToString() == "key")
                return i; // 如果是主键列,则返回列索引
        }

        // 如果没有找到主键列,则返回默认值0
        return 0;
    }

}

PlayerInfoContainer

using System.Collections.Generic;
public class PlayerInfoContainer
{
    public Dictionary<int, PlayerInfo>dataDic = new Dictionary<int, PlayerInfo>();
}

TowerInfoContainer

using System.Collections.Generic;
public class TowerInfoContainer
{
    public Dictionary<int, TowerInfo>dataDic = new Dictionary<int, TowerInfo>();
}

TestInfoContainer

using System.Collections.Generic;
public class TestInfoContainer
{
    public Dictionary<int, TestInfo>dataDic = new Dictionary<int, TestInfo>();
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏