void OnEnable()
        {
            string path = AssetDatabase.GetAssetPath(MonoScript.FromScriptableObject(this));

            path             = Path.GetDirectoryName(path);
            EXCELREADER_PATH = Path.GetDirectoryName(path);
            if (System.Environment.OSVersion.Platform == PlatformID.Unix)
            {
                SHELL_PATH = Path.Combine(path, "generate_configs_bin_mac.sh");
            }
            else
            {
                SHELL_PATH = Path.Combine(path, "generate_configs_bin_window.bat");
            }
            SAVE_PATH = Path.Combine(path, "SaveInfo.json");

            mPrefsNames         = new List <string>();
            mSelectedPrefs      = null;
            mSelectedPrefsIndex = -1;

            if (File.Exists(SAVE_PATH))
            {
                mPrefsFile = (ExcelReaderPrefsFile)JsonUtility.FromJson(System.IO.File.ReadAllText(SAVE_PATH), typeof(ExcelReaderPrefsFile));
                foreach (ExcelReaderPrefs prefs in mPrefsFile.PrefsList)
                {
                    if (string.IsNullOrEmpty(prefs.prefsName))
                    {
                        prefs.prefsName = prefs.combineClassName;
                    }
                    mPrefsNames.Add(prefs.prefsName);
                }
            }
            else
            {
                mPrefsFile = new ExcelReaderPrefsFile();
            }

            mPrefsFile.Version = VERSION;
        }
        void Export(ExcelReaderPrefs xlsxPrefs)
        {
            Func <string, string, string> buildArgs = (dataOutput, input) =>
            {
                StringBuilder sbArgs = new StringBuilder();

                //0. shell
                sbArgs.Append(SHELL_PATH);
                //1. v3 index name
                string indexPath = Path.GetFileName(xlsxPrefs.InputPaths[0]);
                sbArgs.AppendFormat(" \"{0}\"", indexPath);
                //2. code output
                sbArgs.AppendFormat(" \"{0}\"", Path.GetFullPath(xlsxPrefs.CodeOutputPath));
                //3. data output
                sbArgs.AppendFormat(" \"{0}\"", dataOutput);
                //4. json output
                sbArgs.AppendFormat(" \"{0}\"", xlsxPrefs.ExportJson ? Path.GetFullPath(ExcelReaderPrefs.OptionalDataOutputPath(dataOutput, "json")) : "null");
                //5. lua output
                sbArgs.AppendFormat(" \"{0}\"", xlsxPrefs.ExportLua ? Path.GetFullPath(ExcelReaderPrefs.OptionalDataOutputPath(dataOutput, "lua")) : "null");
                //6. cd index.xlsx pre path
                string fullPath = Path.GetFullPath(xlsxPrefs.InputPaths[0]);
                string dir      = Path.GetDirectoryName(fullPath) + "/";
                sbArgs.AppendFormat(" \"{0}\"", dir);
                //7. combine name
                sbArgs.AppendFormat(" \"{0}\"", "Table_" + xlsxPrefs.combineClassName);

                //4. xlsx input
                sbArgs.Append(input);



                return(sbArgs.ToString());
            };

            //shell tabtoy
            Action <string> shellProcess = (args) =>
            {
                System.Diagnostics.Process process = new System.Diagnostics.Process();
                if (System.Environment.OSVersion.Platform == PlatformID.Unix)
                {
                    process.StartInfo = new System.Diagnostics.ProcessStartInfo("/bin/bash", args);
                }
                else
                {
                    process.StartInfo = new System.Diagnostics.ProcessStartInfo("bash", args);
                }
                process.StartInfo.UseShellExecute        = false;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.RedirectStandardError  = true;
                process.Start();

                outputStr += process.StandardOutput.ReadToEnd() + "\n";
                process.WaitForExit();
                process.Close();
            };

            if (!xlsxPrefs.ShareClass)
            {
                StringBuilder inputSb = new StringBuilder();
                for (int i = 0; i < xlsxPrefs.InputPaths.Count; i++)
                {
                    inputSb.AppendFormat(" \"{0}\"", Path.GetFullPath(xlsxPrefs.InputPaths[i]));
                }
                string args = buildArgs(Path.GetFullPath(xlsxPrefs.DataOutputPath), inputSb.ToString());
                //Debug.Log(">>>>>> shell args: " + args);
                shellProcess(args);
            }
            else
            {
                List <string> dataOutputs = xlsxPrefs.ShareClassDataOutputPaths();
                for (int i = 0; i < xlsxPrefs.InputPaths.Count; i++)
                {
                    string args = buildArgs(Path.GetFullPath(dataOutputs[i]), string.Format(" \"{0}\"", Path.GetFullPath(xlsxPrefs.InputPaths[i])));
                    //Debug.Log(">>>>>> shell args: " + args);
                    shellProcess(args);
                }
            }

            //export partial class
            if (xlsxPrefs.ExportPartialClass)
            {
                string partialClassPath = Path.GetFullPath(xlsxPrefs.PartialCodeOutputPath);
                if (!File.Exists(partialClassPath))
                {
                    //only export once
                    string str = System.IO.File.ReadAllText(Path.GetFullPath(xlsxPrefs.CodeOutputPath));
                    if (!string.IsNullOrEmpty(str))
                    {
                        string namespaceStr = str.Substring(str.IndexOf("namespace"), str.IndexOf("{") - str.IndexOf("namespace"));
                        namespaceStr = namespaceStr.Trim();
                        string[] strs = namespaceStr.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                        namespaceStr = strs[1];

                        StringBuilder sb = new StringBuilder();
                        sb.Append("// Generated by Putao.PTXlsxReader only once\n");
                        sb.Append("// Free to edit\n\n");
                        sb.AppendFormat("namespace {0}\n", namespaceStr);
                        sb.Append("{\n");
                        sb.AppendFormat("\tpublic partial class {0}\n", xlsxPrefs.combineClassName);
                        sb.Append("\t{\n\n");
                        sb.Append("\t}\n");
                        sb.Append("}");

                        System.IO.File.WriteAllText(partialClassPath, sb.ToString());
                    }
                }
            }
        }
        void OnGUI()
        {
            mIsDirty = false;

            mScrollViewPos = GUILayout.BeginScrollView(mScrollViewPos);

            GUILayout.Label("Excel Reader", EditorStyles.boldLabel);

            GUILayout.Space(5);

            GUILayout.BeginHorizontal();
            GUILayout.Label("根路径", GUILayout.Width(120));
            GUILayout.Box(Path.GetFullPath(DEFAULT_ROOT_PATH + "/../"));
            GUILayout.EndHorizontal();
            GUILayout.Label("*建议xlsx放在此路径下的文件夹内");

            GUILayout.Space(5);

            GUILayout.BeginHorizontal();
            mSelectedPrefsIndex = EditorGUILayout.Popup("选择一组配置表", mSelectedPrefsIndex, mPrefsNames.ToArray(), GUILayout.Width(300));
            if (mSelectedPrefsIndex >= 0 && mPrefsDatas.Count > mSelectedPrefsIndex)
            {
                mSelectedPrefs = mPrefsDatas[mSelectedPrefsIndex];
            }

            if (GUILayout.Button("+", GUILayout.Width(40)))
            {
                mSelectedPrefs = new ExcelReaderPrefs();
                mSelectedPrefs.combineClassName = "NewConfig" + mPrefsDatas.Count;
                mSelectedPrefs.prefsName        = mSelectedPrefs.combineClassName;
                mPrefsDatas.Add(mSelectedPrefs);
                mPrefsNames.Add(mSelectedPrefs.prefsName);
                mIsDirty            = true;
                mSelectedPrefsIndex = mPrefsNames.Count - 1;
            }

            if (GUILayout.Button("-", GUILayout.Width(40)))
            {
                if (mSelectedPrefs != null)
                {
                    mPrefsDatas.RemoveAt(mSelectedPrefsIndex);
                    mPrefsNames.RemoveAt(mSelectedPrefsIndex);
                    mSelectedPrefs = null;
                    mIsDirty       = true;
                }
            }

            GUILayout.EndHorizontal();

            if (mSelectedPrefs != null)
            {
                EditSelectPrefs();
            }

            //全部导出
            if (GUILayout.Button("全部导出~.~", GUILayout.Width(100)))
            {
                ExportAll();
            }

            if (!string.IsNullOrEmpty(outputStr))
            {
                GUILayout.Label("输出:");
                EditorGUILayout.HelpBox(outputStr, MessageType.Info);
            }

            GUILayout.EndScrollView();

            if (mIsDirty)
            {
                SavePrefs();
            }
        }