读取excel文件并将其中数据转换成脚本数据结构

7 篇文章 0 订阅
2 篇文章 0 订阅

最近写代码测试了在unity中读取Excel配置文件,将配置中的数据结构自动写成脚本中的数据结构。


要写的Excel文件如下:

角色信息表

boss信息表



读取excel文件并写成脚本的代码:

using UnityEngine;
using System.Collections;
using Excel;
using System.IO;
using System.Text;
using System.Data;
using System.Collections.Generic;
using System.Globalization;
using System.Threading;
using UnityEditor;

public class UnityEditorSelection_Test : Editor
{

    [MenuItem("Change/将excel文件内容转换成类结构")]
    public static void WriteClass()
    {
        string path = Application.dataPath + "/MyScripts/";
        string excel = Application.dataPath + "/Excel";

        //原本要保存的文件名为DataClass.cs,但是先生成DataClass2.cs,成功之后将原文件删除,重命名这个文件。
        //这样做是为了避免在写入过程中出现错误,导致原文件都被破坏了
        string targetPath = path + "/DataClass2.cs"; //要写入的文件脚本

        DirectoryInfo di = new DirectoryInfo(excel);
        System.Object data = null;
        using (FileStream fs = new FileStream(targetPath, FileMode.Create, FileAccess.Write))
        {
            using (TextWriter tw = new StreamWriter(fs))
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendLine("using UnityEngine;"); //注意格式、大小写、结束符
                sb.AppendLine(); //空一行
                sb.AppendLine("namespace DataClass"); //写入命名空间
                sb.AppendLine("{"); //这是命名空间的前花括号
                tw.Write(sb);
                #region 根据excel表内容写脚本类
                foreach (var f in di.GetFiles("*.xlsx")) //得到所有的excel文件
                {
                    FileStream fs2 = File.Open(f.FullName, FileMode.Open, FileAccess.Read);
                    string className = Path.GetFileNameWithoutExtension(f.FullName); //得到excel表名作为类结构名

                    IExcelDataReader edr = ExcelReaderFactory.CreateOpenXmlReader(fs2);
                    DataSet result = null;

                    try
                    {
                        result = edr.AsDataSet();
                    }
                    catch(System.Exception e)
                    {
                        Debug.LogError("无法获取正确数据! " + e);
                    }

                    if (result.Tables.Count < 1) //判断excel文件中是否存在数据表
                    {
                        Debug.LogWarning("excel文件" + f.Name + "中没有数据表");
                        return;
                    }

                    DataTable one = result.Tables[0]; //默认获取第一个数据表

                    if (one.Rows.Count < 1) //判断数据表内是否存在数据
                    {
                        Debug.LogWarning("excel文件" + f.Name + "的第一个数据表中没有数据");
                        return;
                    }

                    //存注释
                    List
   
   
    
     comments = new List
    
    
     
     ();
                    //存字段类型
                    List
     
     
      
       filedsType = new List
      
      
       
       ();
                    //存字段名
                    List
       
       
         filedsName = new List 
        
          (); string text = string.Empty; for (int i = 0; i < one.Columns.Count; ++i) { //要注意这里获取各个数据的时候,要和excel文件的数据编写顺序一致。excel中第一行是注释,那么这里就要先得到注释 //存字段注释 comments.Add(one.Rows[0][i].ToString()); //存字段类型 text = one.Rows[1][i].ToString().Trim(); //以防万一,去掉空格 if (string.IsNullOrEmpty(text)) continue; switch (text) { case "bool": filedsType.Add("bool"); break; case "int": filedsType.Add("int"); break; case "float": filedsType.Add("float"); break; case "string": filedsType.Add("string"); break; case "list 
         
           ": filedsType.Add("List 
          
            "); break; case "vector2": filedsType.Add("Vector2"); break; default: Debug.LogWarning("暂不支持类型" + text); break; } //存字段名 filedsName.Add(one.Rows[2][i].ToString()); } StringBuilder sb2 = new StringBuilder(); CultureInfo ci = Thread.CurrentThread.CurrentCulture; TextInfo tf = ci.TextInfo; className = tf.ToTitleCase(className); //转换成首字母大写,其他小写 //写入声明的类 sb2.AppendLine("\tpublic class " + className); //注意换行 sb2.AppendLine("\t{"); //类的前花括号 for (int i = 0; i < filedsType.Count; ++i) { //字段的注释 sb2.AppendLine("\t\t/// 
           "); sb2.AppendLine("\t\t///" + comments[i]); sb2.AppendLine("\t\t///"); //字段具体的声明 sb2.AppendLine("\t\tpublic readonly " + filedsType[i] + " " + filedsName[i] + ";"); } sb2.AppendLine("\t}"); //类的后花括号 sb2.AppendLine(); //空一行 之后写下一个类 tw.Write(sb2); } #endregion tw.Write("}");//这是命名空间的后花括号 data = fs; } } Debug.Log("新的数据结构脚本生成成功!"); DirectoryInfo di2 = new DirectoryInfo(path); FileInfo[] files = di2.GetFiles(); if (files != null) { for (int i = 0; i < files.Length; ++i) { if (files[i].Name.Equals("DataClass.cs")) { files[i].Delete(); Debug.Log("删除原数据结构脚本DataClass.cs"); break; } } AssetDatabase.Refresh(); //这里要添加,不然会报错 string str = AssetDatabase.RenameAsset("Assets/MyScripts/DataClass2.cs", "DataClass"); Debug.Log("改名返回信息 " + str); Debug.Log("新数据结构脚本已重命名为DataClass.cs"); } AssetDatabase.Refresh(); } } 
           
          
         
       
      
      
     
     
    
    
   
   
代码执行后,会在目录Assets/MyScripts中生成一个新的脚本DataClass.cs。里面的内容就是Assets/Excel目录中所有的Excel文件对应生成的类。
如下,就是我测试时生成的结果。

当Excel表转换脚本出错时(代码中执行到return语句了),还是会生成DataClass2.cs这个脚本,这个时候需要手动将这个文件删除了。生成成功是会自动删除的。

代码中用到的动态库可在这里下载。

Excel.dll

System.Data


可供参考的网页:

AssetDatabase 

Unity 获取指定资源目录下的所有文件

Unity3d 操作文件(存储,读取,删除文件,删除目录)

批量修改unity的Asset下资源的文件名

Unity Excel 文件读取和写入

unity3d 根据指定的Assets下的文件夹路径 返回这个路径下的所有文件名

Unity遍历所选文件夹中包含某后缀名的文件路径

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值