Unity3D Excel转Asset文件

一、首先问题来了,为什么要把Excel转成Asset文件呢

1.Excel的不兼容性。首先PC上打包的程序就比编辑器模式下要多添加几个dll才能读取,移动端对Excel的支持就更差。

2.读取速度慢。这个我亲测过,一份Excel文件,一份该Excel转成的Asset文件。如下图,Excel第一次读取为88毫秒,后面基本维持在40毫秒左右,而Asset文件一直是0毫秒。

为了了解读取Asset文件到底有多快,我使用循环读取来看看,

读取10次和读100次都如下图第一次1毫秒,后面都是0毫秒

读取1000次

这么牛逼吗,10000次试试

一万次才7、8毫秒,又试了一下都一万次Excel,Unity直接卡死了!

后面又试了一下读空Excel,一次大概耗时15毫秒左右,着说名随内容增加,时间也会增加很多。

结论:用Asset文件吧!

二、读取Excel的方法

要先把Excel转成Asset文件,首先还是要读取Excel,介绍两种方式吧。

方法一

1.引入几个读取Excel需要的dll,如图

Excel.dll和ICSharpCode.SharpZipLib.dll的下载链接 https://download.csdn.net/download/yasinxin/11861899

System.Data.dll 在D:\Program Files\Unity2017.2\Editor\Data\Mono\lib\mono\2.0

如过要在PC打包版本读取还需要加加几个

I18N开头的dll 在 D:\Program Files\Unity2017.2\Editor\Data\Mono\lib\mono\unity

备注:Unity2017.2 为你的unity版本,去对应的安装目录中取dll

2.读取方法

 public static DataSet ReadExcel(string path)
    {
        FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read);
        IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
        DataSet result = excelReader.AsDataSet();
        return result;
    }

DataSet 为Unity中的一个Excel类,读完就存在里面,然后通过类的属性取想要的数据

Path 为Excel存放路径,如:string path = Application.dataPath + "/Resources/PreparationPatientItem.xlsx";

方法二

csv格式读取

这个方法直接写成编辑模式窗口打开的方式

    /// <summary>
    /// 文件转存数组内容
    /// </summary>
    static string[][] array = null;

    /// <summary>
    /// 打开csv文件
    /// </summary>
    [MenuItem("Tool/OpenCsv")]
    static void OpenFile(string functionName)
    {
        EditorUtility.DisplayDialog("选择文件夹", "请选择路径!", "OK");

        string CompentPath = string.Empty;

        //如果按下弹窗的OK按钮
        CompentPath = EditorUtility.OpenFilePanel("Overwrite with csv", "", "csv,xls,xlsx");

        if (CompentPath.Length != 0)
        {
            Debug.Log(CompentPath);

            if (!CompentPath.EndsWith(".csv") && !CompentPath.EndsWith(".CSV") && !CompentPath.EndsWith(".xls") && !CompentPath.EndsWith(".xlsx"))
            {
                Debug.LogWarning("请选择Excel文件");
                return;
            }

            string str = File.ReadAllText(CompentPath);

            //读取每一行的内容  
            string[] lineArray = str.Split("\r"[0]);
            Debug.Log(lineArray[5]);
            //创建二维数组  
            array = new string[lineArray.Length][];

            //把csv中的数据储存在二位数组中  
            for (int i = 0; i < lineArray.Length; i++)
            {
                array[i] = lineArray[i].Split(',');
            }

            PreparationPatientItemFunction();
        }
    }

这样就把数据存放到了二维数组array里面了。

备注: 方法二只能读取csv格式,因为只有csv格式有UTF-8的编码方式,如图:

试了其他格式打开会成乱码。不过读csv格式比xlsx要快一些,但和读Asset比还不是一个级别的。

但读csv可以不用导入dll就能读取。

三、把数据转成Asset文件

如下图是我数据样式

 根据样式创建相应的数据类

public class PreparationPatientItemDatas : ScriptableObject
{
    public List<PreparationPatientItemData> PreparationPatientItemDataList = new List<PreparationPatientItemData>();
}

[System.Serializable]
public class PreparationPatientItemData
{
    public string id;
    public string itemKey;
    public string itemContent;
    public GMMedicalProjectType internalMedicineType = GMMedicalProjectType.None;
    public string questionKey;
    public string questionContents;
    public string answerKey;
    public string answerContents;
}

/// <summary>
/// 医学项目类型 +400
/// </summary>
public enum GMMedicalProjectType
{
    None,
    Chest,
    Abdoment,
    Marrow,
    Lumber,
    Pericardium,
    Thyrocricoid,
    MarrowChild,
    LumberChild,
    KneeJoint,
    MarrowTibiaChild,
    Culdocentesis,
    KneeJointChild,
    MaleCatheterization,
    FemaleCatheterization,
    AbdomentChild,
    ChestChild,
    GastricLavage,
    NasogastricGavage
}

 然后把从Excel读到的数据填到类中,再生成Asset文件,这里以第二种读取为例

    static void PreparationPatientItemFunction()
    {
        if (array == null || array.Length < 1)
        {
            Debug.LogWarning("未读csv!!!");
            return;
        }

        string assetName = GetDataByRowAndCol(0, 0);
        Debug.Log(assetName);
        PreparationPatientItemDatas preparationPatientItemDatas = new PreparationPatientItemDatas();

        for (int i = 3; i < array.Length - 1; i++)
        {
            PreparationPatientItemData preparationPatientItemData = new PreparationPatientItemData();
            preparationPatientItemData.id = array[i][0].Replace("\n", "");
            Debug.Log(i);
            preparationPatientItemData.itemKey = array[i][1];
            preparationPatientItemData.itemContent = array[i][2];
            preparationPatientItemData.internalMedicineType = (GMMedicalProjectType)(int.Parse(array[i][3]) - 400);
            preparationPatientItemData.questionKey = array[i][4];
            preparationPatientItemData.questionContents = array[i][5];
            preparationPatientItemData.answerKey = array[i][6];
            preparationPatientItemData.answerContents = array[i][7];

            preparationPatientItemDatas.PreparationPatientItemDataList.Add(preparationPatientItemData);
        }

        AssetDatabase.CreateAsset(preparationPatientItemDatas, "Assets/Resources/" + assetName + ".asset");

        Debug.Log("Save it");
    }

    static string GetDataByRowAndCol(int nRow, int nCol)
    {
        if (array.Length <= 0 || nRow >= array.Length)
            return "";
        if (nCol >= array[0].Length)
            return "";

        return array[nRow][nCol];
    }

 最后生成的Asset如下

发布了13 篇原创文章 · 获赞 4 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/YasinXin/article/details/102524921