private static void ToScriptableObject(string excelPath, string sheetName, string outputPath, SheetData sheetData)
        {
            try
            {
                string fileName       = Path.GetFileName(excelPath);
                var    sheetClassName = EESettings.Current.GetSheetClassName(fileName, sheetName);
                var    asset          = ScriptableObject.CreateInstance(sheetClassName);
                var    dataCollect    = asset as EERowDataCollection;
                if (dataCollect == null)
                {
                    return;
                }

                dataCollect.ExcelFileName  = fileName;
                dataCollect.ExcelSheetName = sheetName;
                var className = EESettings.Current.GetRowDataClassName(fileName, sheetName, true);
                var dataType  = Type.GetType(className);
                if (dataType == null)
                {
                    var asmb = Assembly.LoadFrom(Environment.CurrentDirectory + "/Library/ScriptAssemblies/Assembly-CSharp.dll");
                    dataType = asmb.GetType(className);
                }
                if (dataType == null)
                {
                    EELog.LogError(className + " not exist !");
                    return;
                }

                //var dataCtor = dataType.GetConstructor(Type.EmptyTypes);
                var dataCtor = dataType.GetConstructor(new [] { typeof(List <List <string> >), typeof(int), typeof(int) });
                if (dataCtor == null)
                {
                    return;
                }
                var keySet = new HashSet <object>();
                for (var row = EESettings.Current.DataStartIndex; row < sheetData.RowCount; ++row)
                {
                    // 替换掉单元格中的'\n'为 "\\n"
                    for (var col = 0; col < sheetData.ColumnCount; ++col)
                    {
                        sheetData.Set(row, col, sheetData.Get(row, col).Replace("\n", "\\n"));
                    }
                    // 利用反射构造函数处理数据
                    var inst = dataCtor.Invoke(new object[] { sheetData.Table, row, 0 }) as EERowData;
                    if (inst == null)
                    {
                        continue;
                    }

                    var keys       = inst.GetKeyFieldValues();
                    var isMultiKey = keys.Count > 1;
                    if (keys.Count == 0)
                    {
                        EELog.LogError("The value of key is null in sheet " + sheetName);
                        continue;
                    }

                    if (!isMultiKey)
                    {
                        var key = keys[0];

                        if (key is int i && i == 0)
                        {
                            continue;
                        }

                        if (key is string s && string.IsNullOrEmpty(s))
                        {
                            continue;
                        }

                        if (!keySet.Contains(key))
                        {
                            dataCollect.AddData(inst);
                            keySet.Add(key);
                        }
                        else
                        {
                            EELog.LogError(string.Format("More than one rows have the same Key [{0}] in Sheet {1}", key, sheetName));
                        }
                    }
                    else
                    {
                        var isKeysOk = true;
                        // 多个key
                        var groupKey = "";
                        for (int j = 0; j < keys.Count; j++)
                        {
                            var key = keys[j];
                            if (key is int i && i == 0)
                            {
                                isKeysOk = false;
                            }
                            else if (key is string s && string.IsNullOrEmpty(s))
                            {
                                isKeysOk = false;
                            }
        private static void ToScriptableObject(string sheetName, string outputPath, SheetData sheetData)
        {
            try
            {
                var dataTableClassName = EESettings.Current.GetDataTableClassName(sheetName);
                var asset       = ScriptableObject.CreateInstance(dataTableClassName);
                var dataCollect = asset as RowDataCollection;
                if (dataCollect == null)
                {
                    return;
                }
                var className = EESettings.Current.GetRowDataClassName(sheetName, true);
                var dataType  = Type.GetType(className);
                if (dataType == null)
                {
                    var asmb = Assembly.LoadFrom(Environment.CurrentDirectory +
                                                 "/Library/ScriptAssemblies/Assembly-CSharp.dll");
                    dataType = asmb.GetType(className);
                }

                if (dataType == null)
                {
                    EELog.LogError(className + " not exist !");
                    return;
                }

                var dataCtor = dataType.GetConstructor(Type.EmptyTypes);
                if (dataCtor == null)
                {
                    return;
                }
                var ids = new HashSet <int>();
                for (var row = EESettings.Current.DataStartIndex; row < sheetData.rowCount; ++row)
                {
                    for (var col = 0; col < sheetData.columnCount; ++col)
                    {
                        sheetData.Set(row, col, sheetData.Get(row, col).Replace("\n", "\\n"));
                    }

                    var inst = dataCtor.Invoke(null) as RowData;
                    if (inst == null)
                    {
                        continue;
                    }
                    inst._init(sheetData.Table, row, 0);
                    if (!ids.Contains(inst.ID))
                    {
                        dataCollect.AddData(inst);
                        ids.Add(inst.ID);
                    }
                    else
                    {
                        EELog.LogWarning("More than one rows use ID " + inst.ID + " in " + sheetName);
                    }
                }

                var itemPath = outputPath + EESettings.GetAssetFileName(sheetName);
                itemPath = itemPath.Substring(itemPath.IndexOf("Assets", StringComparison.Ordinal));
                AssetDatabase.CreateAsset(asset, itemPath);

                AssetDatabase.Refresh();
            }
            catch (Exception ex)
            {
                EELog.LogError(ex.ToString());
            }
        }