【简单实用框架】【读Excel表】【可移植】

news/2024/11/23 5:50:59/

在这里插入图片描述

☀️博客主页:CSDN博客主页
💨本文由 我是小狼君 原创,首发于 CSDN💢
🔥学习专栏推荐:面试汇总
❗️游戏框架专栏推荐:游戏实用框架专栏
⛅️点赞 👍 收藏 ⭐留言 📝,如有错误请指正
📆 未来很长,值得我们全力奔赴更美好的生活✨


在这里插入图片描述Unity 小科普

老规矩,先介绍一下Unity的科普小知识:​​​​​​

  • Unity 是行业领先的实时3D开发平台。
  • 包括游戏开发,电影,AR/VR,虚拟现实在内的所有创作者,可以将梦想照进现实。
  • Unity提供了一套完整完善的软件解决方案,可用于创作,运营和模拟任何2D和3D的内容,进本全平台支持。

简单实用框架

目的:游戏开发中,经常会用到读表这个功能,一些配置数据都是放在表格中交给策划配置,这次分享的就是一个可快速移植的读表功能

原理:

经过了一个中间XMl的转换,极其方便使用,一个脚本搞定。

源码

using System.IO;
using Excel;
using System.Data;
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using Table;
using System;
using System.Xml;
using System.Xml.Serialization;
using System.Runtime.Serialization.Formatters.Binary;/// <summary>
/// Excel生成bytes和cs工具
/// </summary>
public class Excel2CsBytesTool
{static string ExcelDataPath = Application.dataPath + "/../ExcelData";//源Excel文件夹,xlsx格式static string BytesDataPath = Application.dataPath + "/Resources/DataTable";//生成的bytes文件夹static string CsClassPath = Application.dataPath + "/Scripts/DataTable";//生成的c#脚本文件夹static string XmlDataPath = ExcelDataPath + "/tempXmlData";//生成的xml(临时)文件夹..static string AllCsHead = "all";//序列化结构体的数组类.类名前缀static char ArrayTypeSplitChar = '#';//数组类型值拆分符: int[] 1#2#34 string[] 你好#再见 bool[] true#false ...static bool IsDeleteXmlInFinish = true;//生成bytes后是否删除中间文件xml[MenuItem("SDGSupporter/Excel/Excel2Cs")]static void Excel2Cs(){Init();Excel2CsOrXml(true);}[MenuItem("SDGSupporter/Excel/Excel2Bytes")]static void Excel2Xml2Bytes(){Init();//生成中间文件xmlExcel2CsOrXml(false);//生成bytesWriteBytes();}static void Init(){if (!Directory.Exists(CsClassPath)){Directory.CreateDirectory(CsClassPath);}if (!Directory.Exists(XmlDataPath)){Directory.CreateDirectory(XmlDataPath);}if (!Directory.Exists(BytesDataPath)){Directory.CreateDirectory(BytesDataPath);}}static void WriteCs(string className, string[] names, string[] types, string[] descs){try{StringBuilder stringBuilder = new StringBuilder();stringBuilder.AppendLine("using System;");stringBuilder.AppendLine("using System.Collections.Generic;");stringBuilder.AppendLine("using System.IO;");stringBuilder.AppendLine("using System.Runtime.Serialization.Formatters.Binary;");stringBuilder.AppendLine("using System.Xml.Serialization;");stringBuilder.Append("\n");stringBuilder.AppendLine("namespace Table");stringBuilder.AppendLine("{");stringBuilder.AppendLine("    [Serializable]");stringBuilder.AppendLine("    public class " + className);stringBuilder.AppendLine("    {");for (int i = 0; i < names.Length; i++){stringBuilder.AppendLine("        /// <summary>");stringBuilder.AppendLine("        /// " + descs[i]);stringBuilder.AppendLine("        /// </summary>");stringBuilder.AppendLine("        [XmlAttribute(\"" + names[i] + "\")]");string type = types[i];if (type.Contains("[]")){//type = type.Replace("[]", "");//stringBuilder.AppendLine("        public List<" + type + "> " + names[i] + ";");//可选代码://用_name字段去反序列化,name取_name.item的值,直接返回list<type>。//因为xml每行可能有多个数组字段,这样就多了一层变量item,所以访问的时候需要.item才能取到list<type>//因此用额外的一个变量直接返回List<type>。type = type.Replace("[]", "");stringBuilder.AppendLine("        public List<" + type + "> " + names[i] + "");stringBuilder.AppendLine("        {");stringBuilder.AppendLine("            get");stringBuilder.AppendLine("            {");stringBuilder.AppendLine("                if (_" + names[i] + " != null)");stringBuilder.AppendLine("                {");stringBuilder.AppendLine("                    return _" + names[i] + ".item;");stringBuilder.AppendLine("                }");stringBuilder.AppendLine("                return null;");stringBuilder.AppendLine("            }");stringBuilder.AppendLine("        }");stringBuilder.AppendLine("        [XmlElementAttribute(\"" + names[i] + "\")]");stringBuilder.AppendLine("        public " + type + "Array _" + names[i] + ";");}else{stringBuilder.AppendLine("        public " + type + " " + names[i] + ";");}stringBuilder.Append("\n");}stringBuilder.AppendLine("        public static List<" + className + "> LoadBytes()");stringBuilder.AppendLine("        {");stringBuilder.AppendLine("            string bytesPath = \"" + BytesDataPath + "/" + className + ".bytes\";");stringBuilder.AppendLine("            if (!File.Exists(bytesPath))");stringBuilder.AppendLine("                return null;");stringBuilder.AppendLine("            using (FileStream stream = new FileStream(bytesPath, FileMode.Open))");stringBuilder.AppendLine("            {");stringBuilder.AppendLine("                BinaryFormatter binaryFormatter = new BinaryFormatter();");stringBuilder.AppendLine("                all" + className + " table = binaryFormatter.Deserialize(stream) as all" + className + ";");stringBuilder.AppendLine("                return table." + className + "s;");stringBuilder.AppendLine("            }");stringBuilder.AppendLine("        }");stringBuilder.AppendLine("    }");stringBuilder.Append("\n");stringBuilder.AppendLine("    [Serializable]");stringBuilder.AppendLine("    public class " + AllCsHead + className);stringBuilder.AppendLine("    {");stringBuilder.AppendLine("        public List<" + className + "> " + className + "s;");stringBuilder.AppendLine("    }");stringBuilder.AppendLine("}");string csPath = CsClassPath + "/" + className + ".cs";if (File.Exists(csPath)){File.Delete(csPath);}using (StreamWriter sw = new StreamWriter(csPath)){sw.Write(stringBuilder);Debug.Log("生成:" + csPath);}}catch (System.Exception e){Debug.LogError("写入CS失败:" + e.Message);throw;}}static void WriteXml(string className, string[] names, string[] types, List<string[]> datasList){try{StringBuilder stringBuilder = new StringBuilder();stringBuilder.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");stringBuilder.AppendLine("<" + AllCsHead + className + ">");stringBuilder.AppendLine("<" + className + "s>");for (int d = 0; d < datasList.Count; d++){stringBuilder.Append("\t<" + className + " ");//单行数据string[] datas = datasList[d];//填充属性节点for (int c = 0; c < datas.Length; c++){string type = types[c];if (!type.Contains("[]")){string name = names[c];string value = datas[c];stringBuilder.Append(name + "=\"" + value + "\"" + (c == datas.Length - 1 ? "" : " "));}}stringBuilder.Append(">\n");//填充子元素节点(数组类型字段)for (int c = 0; c < datas.Length; c++){string type = types[c];if (type.Contains("[]")){string name = names[c];string value = datas[c];string[] values = value.Split(ArrayTypeSplitChar);stringBuilder.AppendLine("\t\t<" + name + ">");for (int v = 0; v < values.Length; v++){stringBuilder.AppendLine("\t\t\t<item>" + values[v] + "</item>");}stringBuilder.AppendLine("\t\t</" + name + ">");}}stringBuilder.AppendLine("\t</" + className + ">");}stringBuilder.AppendLine("</" + className + "s>");stringBuilder.AppendLine("</" + AllCsHead + className + ">");string xmlPath = XmlDataPath + "/" + className + ".xml";if (File.Exists(xmlPath)){File.Delete(xmlPath);}using (StreamWriter sw = new StreamWriter(xmlPath)){sw.Write(stringBuilder);Debug.Log("生成文件:" + xmlPath);}}catch (System.Exception e){Debug.LogError("写入Xml失败:" + e.Message);}}static void Excel2CsOrXml(bool isCs){string[] excelPaths = Directory.GetFiles(ExcelDataPath, "*.xlsx");for (int e = 0; e < excelPaths.Length; e++){//0.读Excelstring className;//类型名string[] names;//字段名string[] types;//字段类型string[] descs;//字段描述List<string[]> datasList;//数据try{string excelPath = excelPaths[e];//excel路径  className = Path.GetFileNameWithoutExtension(excelPath);FileStream fileStream = File.Open(excelPath, FileMode.Open, FileAccess.Read);IExcelDataReader excelDataReader = ExcelReaderFactory.CreateOpenXmlReader(fileStream);// 表格数据全部读取到result里DataSet result = excelDataReader.AsDataSet();// 获取表格列数int columns = result.Tables[0].Columns.Count;// 获取表格行数int rows = result.Tables[0].Rows.Count;// 根据行列依次读取表格中的每个数据names = new string[columns];types = new string[columns];descs = new string[columns];datasList = new List<string[]>();for (int r = 0; r < rows; r++){string[] curRowData = new string[columns];for (int c = 0; c < columns; c++){//解析:获取第一个表格中指定行指定列的数据string value = result.Tables[0].Rows[r][c].ToString();//清除前两行的变量名、变量类型 首尾空格if (r < 2){value = value.TrimStart(' ').TrimEnd(' ');}curRowData[c] = value;}//解析:第一行类变量名if (r == 0){names = curRowData;}//解析:第二行类变量类型else if (r == 1){types = curRowData;}//解析:第三行类变量描述else if (r == 2){descs = curRowData;}//解析:第三行开始是数据else{datasList.Add(curRowData);}}}catch (System.Exception exc){Debug.LogError("请关闭Excel:" + exc.Message);return;}if (isCs){//写CsWriteCs(FirstCharacterUppercase(className), names, types, descs);}else{//写XmlWriteXml(FirstCharacterUppercase(className), names, types, datasList);}}AssetDatabase.Refresh();}static string FirstCharacterUppercase(string s){char[] a = s.ToCharArray();a[0] = char.ToUpper(a[0]);return new string(a);}static void WriteBytes(){string csAssemblyPath = Application.dataPath + "/../Library/ScriptAssemblies/Assembly-CSharp.dll";Assembly assembly = Assembly.LoadFile(csAssemblyPath);if (assembly != null){Type[] types = assembly.GetTypes();for (int i = 0; i < types.Length; i++){Type type = types[i];if (type.Namespace == "Table" && type.Name.Contains(AllCsHead)){string className = type.Name.Replace(AllCsHead, "");//读取xml数据string xmlPath = XmlDataPath + "/" + className + ".xml";if (!File.Exists(xmlPath)){Debug.LogError("Xml文件读取失败:" + xmlPath);continue;}object table;using (Stream reader = new FileStream(xmlPath, FileMode.Open)){//读取xml实例化table: all+classname//object table = assembly.CreateInstance("Table." + type.Name);XmlSerializer xmlSerializer = new XmlSerializer(type);table = xmlSerializer.Deserialize(reader);}//obj序列化二进制string bytesPath = BytesDataPath + "/" + className + ".bytes";if (File.Exists(bytesPath)){File.Delete(bytesPath);}using (FileStream fileStream = new FileStream(bytesPath, FileMode.Create)){BinaryFormatter binaryFormatter = new BinaryFormatter();binaryFormatter.Serialize(fileStream, table);Debug.Log("生成:" + bytesPath);}if (IsDeleteXmlInFinish){File.Delete(xmlPath);Debug.Log("删除:" + bytesPath);}}}}if (IsDeleteXmlInFinish){Directory.Delete(XmlDataPath);Debug.Log("删除:" + XmlDataPath);}}
}

优点

  • 自动生成脚本
  • 一行代码调用
  • 什么时候使用什么时候读表,不会提前读表占用内存

GitCode地址

可移植读表功能


http://www.ppmy.cn/news/211508.html

相关文章

Linux 之JavaEE定制篇-搭建JavaEE 环境

Linux 之JavaEE 定制篇-搭建JavaEE 环境 注意 本篇软件链接提供 链接&#xff1a;https://pan.baidu.com/s/1y5qqQvWGQ-iz5M2WUrjD3A?pwdv5l2 提取码&#xff1a;v5l2 如果嫌自己下载麻烦或者难找可以考虑 概述 如果需要在Linux 下进行JavaEE 的开发&#xff0c;我们需要…

PHP基于MVC的Web应用

预计更新 第一章&#xff1a;入门 1.1 环境搭建1.2 变量和数据类型1.3 控制流程 第二章&#xff1a;函数 2.1 函数的定义和调用2.2 函数的参数和返回值2.3 匿名函数和闭包 第三章&#xff1a;数组 3.1 数组的基本操作3.2 多维数组3.3 数组函数和排序 第四章&#xff1a;文…

qss背景设置相关入门文档

目录 概述设置背景颜色background-color设置背景图片background-image设置背景大小background-size设置背景位置background-position设置背景重复background-repeat综合应用总结 概述 当使用Qt的QSS&#xff08;Qt Style Sheets&#xff09;样式表来自定义界面时&#xff0c;背…

直播录音时准备一副监听耳机,实现所听即所得,丁一号G800S上手

有些朋友在录视频还有开在线会议的时候&#xff0c;都会遇到一个奇怪的问题&#xff0c;就是自己用麦克风收音的时候&#xff0c;自己的耳机和别人的耳机听到的效果不一样&#xff0c;像是音色、清晰度不好&#xff0c;或者是缺少伴奏以及背景音嘈杂等&#xff0c;这时候我们就…

微软云 Azure 云服务器 Web应用服务云计算解决方案

一、 Microsoft Azure 微软云简介 Microsoft Azure 是 Microsoft 为客户提供的公有云平台。客户可以多种不同方式使用此平台。例如&#xff0c;客户可以使用 Microsoft Azure 构建一个在 Microsoft 数据中心运行并存储其数据的 Web 应用程序。同时&#xff0c;亦可使用 Micro…

微软Surface发布会看什么

微软不软&#xff01;这次的微软 2016 年 10 月 26 日发布会不禁让人为信仰充值。27日就是苹果的发布会&#xff0c;PC界两大巨头竞争意图很明显啊&#xff0c;微软没有让我失望&#xff0c;留给我印象深刻的地方做个总结。   硬件设备更容易吸引注意&#xff0c;微软深深的…

suface怎么把计算机放到桌面,如何将Surface Pro变成一台一体电脑?

如今&#xff0c;随着技术的升级不仅仅产品的样式、性能在升级&#xff0c;形态也在打破着传统&#xff0c;比如一款产品在外接的形式下就可以变身为另一款产品。就像你曾想过将微软Surface Pro变身成一款一体电脑吗&#xff1f; 近日&#xff0c;一款名为SD7000 Dual 4K的扩展…

在微软工作有多舒服?

一项不加班文化就让同行羡慕得无以复加&#xff0c;最近微软又有了一项超福利动作——在家办公。 据外媒The Verge10月9日的报道&#xff0c;微软允许部分员工定期在家自由工作&#xff0c;每周不超过50%的工作时间。如果经理批准&#xff0c;甚至可以永久远程工作。微软会为永…