前言
接着上一篇写
Excel表数据序列化成文本
这里直接上代码了
[MenuItem("Component/Excel表数据写入文本")]public static void Serlize(){string[] paths = FileTools.GetAllFiles(AssetData.AssetExcelToJsonOutPutPath, "xlsx");Data data = new Data(); //这是我需要序列化的对象for (int i = 0; i < paths.Length; i++){string className = paths[i].SubPath().RemoveEndName();FileStream fileStream = File.Open(paths[i], FileMode.Open);WriteData(className, fileStream, data);} FileTools.Desrlize(AssetData.AssetExcelToJsonOutPutPath + "\\data.txt", data);}/// <summary>/// 写入数据/// </summary>private static void WriteData(string className, FileStream fileStream, Data data){switch (className){case "BuildingInfo": //这些是我Excel表的文件名data.buildingInfos=LoadExcel.Load<BuildingInfo>(fileStream);break;case "BuildingDec":data.buildingDecs = LoadExcel.Load<BuildingDec>(fileStream);break;case "BuildingLv":data.buildingLvs = LoadExcel.Load<BuildingLv>(fileStream);break;case "ResidentInfo":data.residentInfos = LoadExcel.Load<ResidentInfo>(fileStream);break;case "ResidentLv":data.residentLvs = LoadExcel.Load<ResidentLv>(fileStream);break;case "ResidentStar":data.residentStars = LoadExcel.Load<ResidentStar>(fileStream);break;default:break;}}/// <summary>/// 获取路径下所有后缀名为 endName 的文件名/// </summary>/// <param name="path"></param>/// <param name="endName"></param>/// <returns></returns>public static string[] GetAllFiles(string path,string endName){return Directory.GetFiles(path,"*"+endName,SearchOption.AllDirectories);}/// <summary>/// 序列化(这里我把序列化和反序列化的方法名搞反了)/// </summary>/// <param name="path"></param>/// <param name="obj"></param>public static void Desrlize(string path, object obj){BinaryFormatter binary = new BinaryFormatter();using (FileStream fileStream = File.Open(path, FileMode.OpenOrCreate)){binary.Serialize(fileStream, obj);} }[Serializable]
public class Data
{public List<BuildingInfo> buildingInfos;public List<BuildingDec> buildingDecs;public List<BuildingLv> buildingLvs;public List<ResidentInfo> residentInfos;public List<ResidentLv> residentLvs;public List<ResidentStar> residentStars;
}
最终,我通过反射把这些数据写入实例中
/// <summary>
/// 加载Excel表
/// </summary>
public class LoadExcel
{/// <summary>/// 加载excel数据并赋值到T类型 /// 返回T类型的集合/// </summary>/// <typeparam name="T"></typeparam>/// <param name="path"></param>/// <returns></returns>public static List<T> Load<T>(Stream stream)where T:class,new(){//FileStream stream=File.Open(path, FileMode.Open);IExcelDataReader excelData=ExcelReaderFactory.CreateOpenXmlReader(stream);DataSet dataSet=excelData.AsDataSet();if (dataSet.Tables== null) return null;DataTable dataTable = dataSet.Tables[0];List<T> result = new List<T>();for (int i = 3; i < dataTable.Rows.Count; i++){T instance = new T();Type type = typeof(T); //得到type对象FieldInfo[] fieldInfos = type.GetFields(); //得到这个对象里面的所有字段for (int j = 0; j < dataTable.Columns.Count; j++){string fieldType = dataTable.Rows[2][j].ToString();fieldType= fieldType.Replace("[", null);fieldType= fieldType.Replace("]", null);fieldInfos[j].SetValue(instance, GetTheType(fieldType,dataTable.Rows[i][j])); //往字段里写入数据}result.Add(instance);}return result;}/// <summary>/// 转换类型/// </summary>/// <param name="type"></param>/// <param name="value"></param>/// <returns></returns>private static object GetTheType(string type,object value){switch (type){case "string":return value;case "int":return int.Parse(value.ToString());case "float":return float.Parse(value.ToString());case "long":return long.Parse(value.ToString());case "double":return double.Parse(value.ToString());case "bigInteger":Log.Print(value);string str = value.ToString().Replace("E", null);return System.Numerics.BigInteger.Parse(str);default:return value;}}
}
这样,我的Data对象就被写入data文本
然后读取就简单了
IEnumerator Load(string path){UnityWebRequest webRequest = UnityWebRequest.Get(path);yield return webRequest.SendWebRequest();if (webRequest.isDone){byte[] data = webRequest.downloadHandler.data;string context = webRequest.downloadHandler.text;Data= FileTools.Serlize<Data>(data);}else{ Debug.LogError("加载Excel:" + path + "错误:" + webRequest.error);}}/// <summary>/// 反序列化(这里我方法名是弄反了的)/// </summary>/// <typeparam name="T"></typeparam>/// <param name="data"></param>/// <returns></returns>public static T Serlize<T>(byte[] data)where T:class{BinaryFormatter binary = new BinaryFormatter();using(MemoryStream stream=new MemoryStream(data)){return binary.Deserialize(stream) as T;} }