Unity中C#实现Excel存取
C#实现Excel文件的读取与保存,主要用作游戏开发时对于一些数据的修改及添加。游戏打包后不使用。
- 所需第三方dll文件
- 自定义Attribute,用作中文解释Excel的字段名
- 将List类型的数据保存至Excel
- 将Excel中的数据转化为List
- 类型转换
第三方文件
1.读取Excel
2.保存Excel
3.常规
System.Data.dll
在Assets下新建Plugins/Excel目录,将上述为文件放在Assets/Plugins/Excel文件夹下。
自定义Attribute
自定义Attribute,为类的字段添加标签。保存Excel文件时,通过反射获取字段的CustomAttributes,这样就可以为Excel文件的字段添加中文的解释。
自定义Attribute的代码如下:
/// <summary>
/// 自定义Attribute
/// </summary>
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的代码如下:
/// <summary>
/// 测试使用 DescriptionAttribute
/// </summary>
public class AttributeTest
{
[Description("编号")]
public int id;
[Description("名称")]
public string name;
[Description("修改日期")]
public string updateTime;
}
将List数据存储到Excel
1.定义抽象类ExcelData
/// <summary>
/// 可用于保存到Excel文件的抽象类
/// </summary>
[System.Serializable]
public abstract class ExcelData
{
/// 唯一标识符
protected string _guid;
public abstract string guid
{
get;
}
}
2.定义可用于存储的数据类(继承ExcelData)
/// <summary>
/// 测试数据类
/// </summary>
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文件方法实现
/// <summary>
/// 将数据写入excel
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="current">所需保存的数据</param>
/// <param name="fileName">Excel文件名</param>
/// <param name="sheet_name">Excel文件中的sheetName</param>
public static void SaveToExcel<T>(this List<T> 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<TestData> source = new List<TestData>();
for (int i = 0; i < 10; i++)
{
source.Add(new TestData(i, "name_" + i.ToString(), DateTime.Now.ToString()));
}
/// 保存到Excel文件中
source.SaveToExcel<TestData>();
将Excel中的数据读取并转换为List
/// <summary>
/// Excel种读取数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="current"></param>
/// <param name="excel_name"></param>
/// <param name="sheet_name"></param>
/// <returns></returns>
public static List<T> ReadFromExcel<T>(this List<T> 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<T>();
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中读取的数据转换为制定类型的数据,需要进一步扩展。