Unity中C#实现Excel存取

Unity中C#实现Excel存取

参考

C#实现Excel文件的读取与保存,主要用作游戏开发时对于一些数据的修改及添加。游戏打包后不使用。

  • 所需第三方dll文件
  • 自定义Attribute,用作中文解释Excel的字段名
  • 将List类型的数据保存至Excel
  • 将Excel中的数据转化为List
  • 类型转换

第三方文件

1.读取Excel

Excel.dll 以及 ICSharpCode.SharpZipLib

2.保存Excel

Epplus.dll

3.常规

System.Data.dll 

在Assets下新建Plugins/Excel目录,将上述为文件放在Assets/Plugins/Excel文件夹下。

自定义Attribute

自定义Attribute,为类的字段添加标签。保存Excel文件时,通过反射获取字段的CustomAttributes,这样就可以为Excel文件的字段添加中文的解释。

自定义Attribute的代码如下:

/// 
/// 自定义Attribute
/// 
public class DescriptionAttribute : Attribute
{
    private string description;
    public DescriptionAttribute(string str_description)
    {
        description = str_description;
    }

    public string Description
    {
        get { return description; }
        set { description = value; }
    }
}

测试使用 DescriptionAttribute的代码如下:

/// 
/// 测试使用 DescriptionAttribute
/// 
public class AttributeTest
{
    [Description("编号")]
    public int id;

    [Description("名称")]
    public string name;

    [Description("修改日期")]
    public string updateTime;
}

将List数据存储到Excel

1.定义抽象类ExcelData

/// 
/// 可用于保存到Excel文件的抽象类
/// 
[System.Serializable]
public abstract class ExcelData
{
    /// 唯一标识符
    protected string _guid;

    public abstract string guid
    {
        get;
    }
}

2.定义可用于存储的数据类(继承ExcelData)

/// 
/// 测试数据类
/// 
public class TestData : ExcelData
{
    [Description("编号")]
    public int id;

    [Description("名称")]
    public string name;

    [Description("修改日期")]
    public string updateTime;

    public override string guid
    {
        get
        {
            return string.Format("{0}_{1}", id, name);
        }
    }
}

3.List数据保存到Excel文件方法实现

/// 
/// 将数据写入excel
/// 
/// 
/// 所需保存的数据
/// Excel文件名
/// Excel文件中的sheetName
public static void SaveToExcel(this List current, string excel_name = "", string sheet_name = "") where T : ExcelData, new()
{
    /// excel_name为空时采用T类型名作为excel文件名,sheet_name同理
    excel_name = string.IsNullOrEmpty(excel_name) ? typeof(T).ToString() : excel_name;
    sheet_name = string.IsNullOrEmpty(sheet_name) ? typeof(T).ToString() : sheet_name;

    /// 获取文件信息 PathConst.ExcelFilePath(excel_name) 为文件地址
    var fileInfo = new FileInfo(PathConst.ExcelFilePath(excel_name));

    using (var package = new ExcelPackage(fileInfo))
    {
        if (package.Workbook.Worksheets[sheet_name] != null)
        {
            package.Workbook.Worksheets.Delete(sheet_name);
        }

        var workSheet = package.Workbook.Worksheets.Add(sheet_name);

        var fields = typeof(T).GetFields();

        /// 字段名
        for (int titleId = 0; titleId < fields.Length; titleId++)
        {
            var attribs = fields[titleId].GetCustomAttributes(typeof(DescriptionAttribute), false);
            workSheet.Cells[1, titleId + 1].Value = attribs.Length > 0 ? ((DescriptionAttribute)attribs[0]).Description : fields[titleId].Name;
        }

        /// 内容
        for (int i = 0; i < current.Count; i++)
        {
            for (int j = 0; j < fields.Length; j++)
            {
                workSheet.Cells[i + 2, j + 1].Value = fields[j].GetValue(current[i]);
            }
        }

        package.Save();

        Debuger.Log(string.Format("{0}_{1}:写入成功!", excel_name, sheet_name));

    }
}

4. 使用

List source = new List();

for (int i = 0; i < 10; i++)
{
    source.Add(new TestData(i, "name_" + i.ToString(), DateTime.Now.ToString()));
}

/// 保存到Excel文件中
source.SaveToExcel();

将Excel中的数据读取并转换为List

/// 
/// Excel种读取数据
/// 
/// 
/// 
/// 
/// 
/// 
public static List ReadFromExcel(this List current, string excel_name = "", string sheet_name = "") where T : ExcelData, new()
{
    excel_name = string.IsNullOrEmpty(excel_name) ? typeof(T).ToString() : excel_name;
    sheet_name = string.IsNullOrEmpty(sheet_name) ? typeof(T).ToString() : sheet_name;

    if (!File.Exists(PathConst.ExcelFilePath(excel_name)))
    {
        current.SaveToExcel();
        return current;
    }

    using (var fs = File.Open(PathConst.ExcelFilePath(excel_name), FileMode.Open, FileAccess.Read))
    {
        using (var excelReader = ExcelReaderFactory.CreateOpenXmlReader(fs))
        {
            var table = excelReader.AsDataSet().Tables[sheet_name];
            var fields = typeof(T).GetFields();
            int rowCount = table.Rows.Count;
            int columnCount = table.Columns.Count;
            /// 第一行为变量名称
            var variableNameList = new List<string>();
            for (int i = 0; i < columnCount; i++)
                variableNameList.Add(table.Rows[0][i].ToString());
            for (int i = 1; i < rowCount; i++)
            {
                var item = new T();
                var row = table.Rows[i];
                for (int j = 0; j < fields.Length; j++)
                {
                    var field = fields[j];
                    var index = variableNameList.IndexOf(field.Name);
                    if (index < 0)
                        Debuger.LogError(string.Format("Excel表格{0}中,无法找到{1}字段", typeof(T).ToString(), field.Name));
                    else
                        field.SetValue(item, Convert.ChangeType(row[j], field.FieldType));
                }
                current.Add(item);
            }
        }

        Debuger.Log(string.Format("{0}_{1}:读出成功!", excel_name, sheet_name));

    }
    return current;
}

类型转换

上述 ConvertObject(object,type) 方法是将excel中读取的数据转换为制定类型的数据,需要进一步扩展。

你可能感兴趣的:(c#)