public virtual void ExportToJson(string filePath)
    {
        GameDataTableBase <T> table = target as GameDataTableBase <T>;
        string jsonString           = JsonUtility.ToJson(table);

        System.IO.File.WriteAllText(filePath, jsonString);
        Debug.Log("Export to Json Process Completed. Destination: " + filePath);
    }
    public virtual void ImportFromJson(string filePath)
    {
        // read json strings from filePath
        StreamReader file       = new StreamReader(filePath);
        string       jsonString = file.ReadToEnd();

        file.Close();

        GameDataTableBase <T> table = target as GameDataTableBase <T>;

        JsonUtility.FromJsonOverwrite(jsonString, table);

        Debug.Log("Import from Json Process Completed. Source: " + filePath);
    }
    public virtual void ExportToExcel(string filePath, bool withHeader = true)
    {
        GameDataTableBase <T> table = target as GameDataTableBase <T>;

        ExcelPackage ep;
        FileStream   fstream;

        if (File.Exists(filePath))
        {
            fstream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
            ep      = new ExcelPackage(fstream);
            fstream.Close();
        }
        else
        {
            ep = new ExcelPackage();
        }

        T             dataSample = new T();
        List <string> fieldNames = dataSample.GetFieldNames();

        if (ep.Workbook.Worksheets[sheetName] != null)
        {
            ep.Workbook.Worksheets.Delete(sheetName);
        }
        ep.Workbook.Worksheets.Add(sheetName);
        ExcelWorksheet sheet = ep.Workbook.Worksheets[sheetName];

        for (int i = 0; i < fieldNames.Count; i++)
        {
            sheet.SetValueInCell(0, i, fieldNames[i]);
        }
        for (int i = 0; i < table.DataList.Count; i++)
        {
            for (int j = 0; j < fieldNames.Count; j++)
            {
                string value = table.DataList[i].GetField(typeof(T).GetField(fieldNames[j]));
                sheet.SetValueInCell(i + 1, j, value);
            }
        }

        fstream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
        ep.SaveAs(fstream);
        fstream.Close();
        ep.Dispose();

        Debug.Log("Export to Excel Process Completed. Destination: " + filePath);
    }
    public virtual void ImportFromExcel(string filePath, bool withHeader = true)
    {
        GameDataTableBase <T> table = target as GameDataTableBase <T>;

        FileStream   fstream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
        ExcelPackage ep      = new ExcelPackage(fstream);

        ExcelWorksheet sheet = ep.Workbook.Worksheets[sheetName];

        T             dataSample = new T();
        List <string> fieldNames = dataSample.GetFieldNames();

        int i         = (withHeader) ? 1 : 0;
        int dataIndex = 0;

        while (true)
        {
            ExcelRange range = sheet.GetExcelRange(i, 0, i, fieldNames.Count - 1);
            if (range.Any(c => !string.IsNullOrEmpty(c.Text)) == false) //all empty row
            {
                break;
            }

            if (table.DataList.Count <= dataIndex)
            {
                table.DataList.Add(new T());
            }
            for (int j = 0; j < fieldNames.Count; j++)
            {
                string text = sheet.GetValueInCell(i, j);
                table.DataList[dataIndex].SetField(typeof(T).GetField(fieldNames[j]), text);
            }

            i++;
            dataIndex++;
        }

        fstream.Close();
        ep.Dispose();

        Debug.Log("Import from Excel Process Completed. Source: " + filePath);
    }