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如下

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章