Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: mr-kelly/TableML
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: zhaoqingqing/TableML
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: custom
Choose a head ref
Can’t automatically merge. Don’t worry, you can still create the pull request.

Commits on Nov 2, 2016

  1. Copy the full SHA
    70af7fe View commit details

Commits on Apr 1, 2017

  1. Copy the full SHA
    8443975 View commit details
  2. Copy the full SHA
    495ccda View commit details

Commits on Apr 7, 2017

  1. 完善readme

    zhaoqingqing committed Apr 7, 2017
    Copy the full SHA
    4f4f4d3 View commit details
  2. 增加测试代码

    zhaoqingqing committed Apr 7, 2017
    Copy the full SHA
    2aecfeb View commit details
  3. 添加测试文件

    zhaoqingqing committed Apr 7, 2017
    Copy the full SHA
    9b407a0 View commit details

Commits on Apr 10, 2017

  1. Copy the full SHA
    3aa53a0 View commit details
  2. Copy the full SHA
    87baca1 View commit details

Commits on Apr 12, 2017

  1. Copy the full SHA
    146c0e2 View commit details
  2. Copy the full SHA
    dae36cb View commit details
  3. Copy the full SHA
    d38720c View commit details

Commits on Apr 13, 2017

  1. Copy the full SHA
    c179a3d View commit details

Commits on Apr 16, 2017

  1. Copy the full SHA
    3d8178d View commit details

Commits on Apr 21, 2017

  1. fix:从指定列读取生成的代码和tml不正确;

    TODO 未做单元测试
    zhaoqingqing committed Apr 21, 2017
    Copy the full SHA
    9bdf600 View commit details

Commits on Apr 22, 2017

  1. 更新表的数据类型

    zhaoqingqing committed Apr 22, 2017
    Copy the full SHA
    f4de272 View commit details

Commits on Apr 23, 2017

  1. Copy the full SHA
    d2e6970 View commit details
  2. nunit

    zhaoqingqing committed Apr 23, 2017
    Copy the full SHA
    70abd8d View commit details
  3. Copy the full SHA
    7e8186b View commit details
  4. 更新nunit为3.x

    zhaoqingqing committed Apr 23, 2017
    Copy the full SHA
    5539be7 View commit details
  5. Array.Copy

    zhaoqingqing committed Apr 23, 2017
    Copy the full SHA
    f697eba View commit details
  6. add gui

    zhaoqingqing committed Apr 23, 2017
    Copy the full SHA
    6031efa View commit details
  7. 调试代码

    zhaoqingqing committed Apr 23, 2017
    Copy the full SHA
    6358aef View commit details

Commits on Apr 24, 2017

  1. fix:当列的内容为空时,tml生成错误的bug

    TableMLGUI 可读取配置;
    zhaoqingqing committed Apr 24, 2017
    Copy the full SHA
    39541c4 View commit details

Commits on Apr 28, 2017

  1. Copy the full SHA
    08c988b View commit details

Commits on Apr 30, 2017

  1. Copy the full SHA
    c699bd9 View commit details
  2. Copy the full SHA
    bd194aa View commit details
  3. 默认的app.config

    zhaoqingqing committed Apr 30, 2017
    Copy the full SHA
    a342c2c View commit details

Commits on May 3, 2017

  1. Copy the full SHA
    187b01f View commit details

Commits on May 8, 2017

  1. Copy the full SHA
    b75dc3f View commit details

Commits on May 9, 2017

  1. Copy the full SHA
    f6d6149 View commit details
  2. Copy the full SHA
    f3d51fb View commit details
  3. Copy the full SHA
    9f0a864 View commit details
  4. Copy the full SHA
    15ac5db View commit details

Commits on May 10, 2017

  1. Copy the full SHA
    ec30342 View commit details

Commits on May 11, 2017

  1. csharpkeywords.txt

    zhaoqingqing committed May 11, 2017
    Copy the full SHA
    ca73c56 View commit details
  2. Copy the full SHA
    a1eb98f View commit details

Commits on May 12, 2017

  1. Copy the full SHA
    ca43e1d View commit details

Commits on May 16, 2017

  1. Copy the full SHA
    900a629 View commit details
  2. Copy the full SHA
    0edf421 View commit details

Commits on May 19, 2017

  1. TableML兼容数组没有分隔符;

    TableML兼容{}形式的数组;
    zhaoqingqing committed May 19, 2017
    Copy the full SHA
    bfcce68 View commit details
  2. Copy the full SHA
    d24b5bd View commit details

Commits on Jun 7, 2017

  1. 1.改选中的表数据类型;

    2.TODO 检查行数是否超出索引;
    zhaoqingqing committed Jun 7, 2017
    Copy the full SHA
    6bc2efd View commit details

Commits on Jun 9, 2017

  1. Copy the full SHA
    0f4020d View commit details
  2. Copy the full SHA
    591080a View commit details
  3. add:把编译后的tsv一键插入到数据库

    add:nuget "System.Data.SQLite"
    fix:当输出文件名为null时跳过
    zhaoqingqing committed Jun 9, 2017
    Copy the full SHA
    4812c36 View commit details
  4. 增加笔记

    zhaoqingqing committed Jun 9, 2017
    Copy the full SHA
    863747f View commit details
  5. Copy the full SHA
    6074094 View commit details

Commits on Jun 11, 2017

  1. Copy the full SHA
    7fbffcc View commit details
  2. fix: data add error

    zhaoqingqing committed Jun 11, 2017
    Copy the full SHA
    6cd2cf8 View commit details
  3. Copy the full SHA
    eb11773 View commit details
Showing with 6,587 additions and 717 deletions.
  1. +5 −1 .gitignore
  2. BIN Document/tablemlgui_main.png
  3. BIN Document/tabml_gui_v2.png
  4. +127 −22 README.md
  5. +7 −1 TableML/TableML.sln
  6. +248 −0 TableML/TableML/CSharpEx.cs
  7. +84 −0 TableML/TableML/ConsoleHelper.cs
  8. +6 −0 TableML/TableML/TableFile.cs
  9. +9 −7 TableML/TableML/TableFileGeneric.cs
  10. +20 −12 TableML/TableML/TableFileRow.cs
  11. +8 −1 TableML/TableML/TableML.csproj
  12. +5 −0 TableML/TableML/TableObjectRow.cs
  13. +136 −13 TableML/TableML/TableRowFieldParser.cs
  14. +636 −328 TableML/TableMLCompiler/BatchCompiler.cs
  15. +278 −141 TableML/TableMLCompiler/Compiler.cs
  16. +1 −1 TableML/TableMLCompiler/CompilerConfig.cs
  17. +298 −9 TableML/TableMLCompiler/DefaultTemplate.cs
  18. +14 −0 TableML/TableMLCompiler/ExcelConfig.cs
  19. +13 −2 TableML/TableMLCompiler/ITableSourceFile.cs
  20. +405 −0 TableML/TableMLCompiler/SimpleCSVFile.cs
  21. +348 −125 TableML/TableMLCompiler/SimpleExcelFile.cs
  22. +71 −0 TableML/TableMLCompiler/SimpleTSVFile.cs
  23. +5 −2 TableML/TableMLCompiler/TableCompileResult.cs
  24. +34 −16 TableML/TableMLCompiler/TableMLCompiler.csproj
  25. +117 −0 TableML/TableMLCompiler/TableTemplateVars.cs
  26. +4 −2 TableML/TableMLCompiler/packages.config
  27. +126 −10 TableML/TableMLCompilerConsole/Program.cs
  28. +30 −5 TableML/TableMLCompilerConsole/TableMLCompilerConsole.csproj
  29. +3 −0 TableML/TableMLCompilerConsole/app.config
  30. +2 −0 TableML/TableMLCompilerConsole/packages.config
  31. +51 −0 TableML/TableMLGUI/App.config
  32. +78 −0 TableML/TableMLGUI/AppConfigHelper.cs
  33. +28 −0 TableML/TableMLGUI/ConfigData.cs
  34. +267 −0 TableML/TableMLGUI/ExcelHelper.cs
  35. +237 −0 TableML/TableMLGUI/FileHelper.cs
  36. +59 −0 TableML/TableMLGUI/HelpForm.Designer.cs
  37. +35 −0 TableML/TableMLGUI/HelpForm.cs
  38. +120 −0 TableML/TableMLGUI/HelpForm.resx
  39. +51 −0 TableML/TableMLGUI/LuaHelper.cs
  40. +490 −0 TableML/TableMLGUI/MainForm.Designer.cs
  41. +595 −0 TableML/TableMLGUI/MainForm.cs
  42. +123 −0 TableML/TableMLGUI/MainForm.resx
  43. +78 −0 TableML/TableMLGUI/Program.cs
  44. +35 −0 TableML/TableMLGUI/Properties/AssemblyInfo.cs
  45. +63 −0 TableML/TableMLGUI/Properties/Resources.Designer.cs
  46. +117 −0 TableML/TableMLGUI/Properties/Resources.resx
  47. +26 −0 TableML/TableMLGUI/Properties/Settings.Designer.cs
  48. +7 −0 TableML/TableMLGUI/Properties/Settings.settings
  49. +390 −0 TableML/TableMLGUI/SQLiteHelper.cs
  50. +83 −0 TableML/TableMLGUI/SQLiteHelperTest.cs
  51. +157 −0 TableML/TableMLGUI/TableMLGUI.csproj
  52. +8 −0 TableML/TableMLGUI/packages.config
  53. +25 −14 TableML/TableMLTests/TableMLTest.cs
  54. +6 −4 TableML/TableMLTests/TableMLTests.csproj
  55. BIN TableML/TableMLTests/TestSettings/TestExcel.xls
  56. BIN TableML/TableMLTests/TestSettings/TestExcel2.xlsx
  57. BIN TableML/TableMLTests/TestSettings/TestExcel2_KSFramework.xlsx
  58. BIN TableML/TableMLTests/TestSettings/TestExcel_KSFramework.xls
  59. +2 −1 TableML/TableMLTests/packages.config
  60. +20 −0 TableML/libs/csharpkeywords.txt
  61. BIN Test/settingsrc/Billboard.xlsx
  62. BIN Test/settingsrc/Test.xlsx
  63. +9 −0 Test/命令行模式编译excel.bat
  64. BIN Test/定制格式/C004 传送点配置表.xlsx
  65. +27 −0 Test/定制格式/测试CSV文件.csv
  66. +3 −0 Test/打开测试目录.bat
  67. +7 −0 Test/拷贝到测试目录.bat
  68. +4 −0 Test/编译表.bat
  69. +34 −0 lua_guide.md
  70. +26 −0 make mdb for unity.bat
  71. +49 −0 other_tools.md
  72. +111 −0 quick_start.md
  73. +58 −0 update_log.md
  74. +68 −0 zip_and_copy_to_ksframework.py
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -242,4 +242,8 @@ ModelManifest.xml
.paket/paket.exe

# FAKE - F# Make
.fake/
.fake/

#jetbrains
.idea/*
.idea
Binary file added Document/tablemlgui_main.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Document/tabml_gui_v2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
149 changes: 127 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

# TableML

TableML, Table Markup Language, 基于电子表格的标记语言,
@@ -9,41 +8,45 @@ TableML, Table Markup Language, 基于电子表格的标记语言,

目前提供C#版本的运行时、编译器、代码生成器。

快速开始: [quick_start.md](./quick_start.md)

更新日志: [update_log.md](./update_log.md)

![GUI界面](./Document/tabml_gui_v2.png)

## Example


您可以使用Excel编译如下内容,并保存为文件setting/test.xls:
您可以使用Excel编译如下内容,并保存为文件setting/test.xls(同时支持csv文件):

| Id | #Something | Value | Comment |
| --- | --- | --- | --- |
| int | string | string | string |
| 关键字/注释行 | 带#开头的注释列 | 内容 | 带Comment开头的注释列 |
| 1 | 无用注释 | Abcdefg | 一些注释 |
| #注释行 | 无用注释 | Abcdefg | 一些注释 |
| Comment注释行 | 无用注释 | Abcdefg | 一些注释 |
| 2 | 无用注释 | Yuiop | 一些注释 |
| #if LANG_TW | | | |
| 123 | 这一行不会被编译 | skldfjlj | 一些注释 |
| #endif | | | |
| Id | #Something | Value | Comment |
| ----------- | ---------- | -------- | -------------- |
| int | string | string | string |
| 关键字/注释行 | 带#开头的注释列 | 内容 | 带Comment开头的注释列 |
| 1 | 无用注释 | Abcdefg | 一些注释 |
| #注释行 | 无用注释 | Abcdefg | 一些注释 |
| Comment注释行 | 无用注释 | Abcdefg | 一些注释 |
| 2 | 无用注释 | Yuiop | 一些注释 |
| #if LANG_TW | | | |
| 123 | 这一行不会被编译 | skldfjlj | 一些注释 |
| #endif | | | |


然后使用TableML命令行编译器:
```bash
TableML.exe --Src setting --To setting2 --CodeFile Code.cs

```

执行后,将会生成setting2/test.tml文件,打开可以看见编译后内容:

| Id | Value |
| --- | --- |
| int | string |
| 1 | Abcdefg |
| 2 | Yuiop |
| Id | Value |
| ---- | ------- |
| int | string |
| 1 | Abcdefg |
| 2 | Yuiop |

另外附带一份Code.cs,自动生成的代码。


## TableML编辑规则

以上的例子中,展示了TableML的大部分特性:
@@ -59,14 +62,116 @@ TableML.exe --Src setting --To setting2 --CodeFile Code.cs
- 行内容的第一个单元格内容,以#开头或Comment开头,改行被视为注释行,编译器忽略
- 可以使用预编译指令#if和#endif,条件式控制编译的行

## 开发者指南

### 命令行方式

1. 通过git clone 或者download master的方式将工程下载到本地
2. 建议使用visual studio2012及更高版本打开 **TableML\TableML.sln**
3. 在vs中设置**TableMLCompilerConsole** 为启动项目(解决方案面板,选中项目,**右键** - **设为启动项目**)
4. 建议把项目的输出设为**Release**,然后选择 **菜单栏** - **生成** - **生成TableMLCompilerConsole**
5. 打开目录 **TableML\TableMLCompilerConsole\bin\Release** 可以看到已经生成了**TableML.exe**

### GUI方式

1. 通过git clone 或者download master的方式将工程下载到本地
2. 建议使用visual studio2012及更高版本打开 **TableML\TableML.sln**
3. 在vs中设置**TableMLGUI** 为启动项目(解决方案面板,选中项目,**右键** - **设为启动项目**)
4. 开发过程中设置为Debug,生产环境项目设为**Release**,然后按下快捷键F5
5. 在弹出的GUI窗口中进行编译Excel

**TableML**

- tml(tsv)文件读取接口

**TableMLCompiler**

- 对excel/csv 源文件进行编译

**TableMLCompilerConsole**

- 命令行窗口,根据条件对excel进行编译

**TableMLGUI**

- 提供GUI界面,增加编译选定excel,将数据导入到sqlite中
- 增加excel的查错,输出操作日志

**TableMLTests**

- 编译功能的单元测试

### 自定义配置

**1. 从第2列(指定列)开始读**

​ 修改SimpleExcelFile.cs中的StartColumnIdx值如:

```c#
public const int StartColumnIdx = 1;
```



**2.每个表对应一个Class文件**

调用方法如下:

```c#
batchCompiler.CompileTableMLAllInSingleFile(srcDirectory, OutputDirectory, CodeFilePath, templateString, "AppSettings", ".tml", null, true);
```

示例代码可参考:LocalDebug.cs中的CompileAll()



**3.修改生成的代码模版**

修改TableML.Compiler.DefaultTemplate中的字符串模版



**4.预留指定行,自定义行,比如第6行是字段名,第8行是数据类型,第15行是字段注释**

扩展`SimpleExcelFile.PreserverRowCount = 预留行`

根据实际表格格式修改SimpleExcelFile.headRowIdx,typeRowIdx等字段数量



### For KSFramwork

对于[KSFramework](https://github.com/mr-kelly/KSFramework) 会使用到这两个工程中的dll

- TableML
- TableMLCompiler



## 读取规则

先读取Excel的行,再读取列,把数据写入到tml文件中。

## 内存溢出

如果在使用TableMLGUI时,特别占用内存,建议把excel另存为csv格式,或者减少单个excel文件的大小,以减少内存占用。

## For SQLite

TableMLGUI提供一键将excel数据插入到sqlite中。

采用sql的事务机制,在插入大量数据环境下,耗时更短。

同时在控制台输出sql语句方便调试查错。



# 自动读取配置代码生成
## 自动读取配置代码生成

TableML编译器内置Liquid模板引擎。您可以自定义模板内容,来为不同的语言生成读表类。

TableML是[KSFramework](https://github.com/mr-kelly/KSFramework)的一部分,用于游戏配置表读取代码,支持热重载、分表等机制。

# TableML for C#/Mono/Xamarin
## TableML for C#/Mono/Xamarin

TableML目前只提供C#版本。当前TableML使用基于Xamarin Studio开发,TableML的C#版本具备了跨平台特性(Windows/Mac/Linux)。
8 changes: 7 additions & 1 deletion TableML/TableML.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25123.0
VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TableML", "TableML\TableML.csproj", "{BA4B8898-DC04-4934-8858-D505226D1A28}"
EndProject
@@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TableMLCompiler", "TableMLC
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TableMLCompilerConsole", "TableMLCompilerConsole\TableMLCompilerConsole.csproj", "{D3A252A3-78B0-4651-AD16-C6B6A30F7326}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TableMLGUI", "TableMLGUI\TableMLGUI.csproj", "{55E28E01-2E74-4809-A2EE-A566FEA5D899}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -33,6 +35,10 @@ Global
{D3A252A3-78B0-4651-AD16-C6B6A30F7326}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D3A252A3-78B0-4651-AD16-C6B6A30F7326}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D3A252A3-78B0-4651-AD16-C6B6A30F7326}.Release|Any CPU.Build.0 = Release|Any CPU
{55E28E01-2E74-4809-A2EE-A566FEA5D899}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{55E28E01-2E74-4809-A2EE-A566FEA5D899}.Debug|Any CPU.Build.0 = Debug|Any CPU
{55E28E01-2E74-4809-A2EE-A566FEA5D899}.Release|Any CPU.ActiveCfg = Release|Any CPU
{55E28E01-2E74-4809-A2EE-A566FEA5D899}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
248 changes: 248 additions & 0 deletions TableML/TableML/CSharpEx.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

/// <summary>
/// 扩展C#的方法
/// NOTE 当类型转换失败时,不抛出异常,而是=默认,让程序可以正常运行
/// 此同名文件在Unity的Project中已有, 所以方法命名修改
/// </summary>
public static class CSharpEx
{
public static bool ToBool_(this string val)
{
bool ret = false;
try
{
if (!String.IsNullOrEmpty(val))
{
ret = val.ToLower() == "true" || val.ToLower() != "0";
}
}
catch (Exception)
{
}
return ret;
}

public static sbyte ToSByte_(this string val)
{
sbyte ret = 0;
try
{
if (!String.IsNullOrEmpty(val))
{
ret = Convert.ToSByte(val);
}
}
catch (Exception)
{
}
return ret;
}

public static byte ToByte_(this string val)
{
byte ret = 0;
try
{
if (!String.IsNullOrEmpty(val))
{
ret = Convert.ToByte(val);
}
}
catch (Exception)
{
}
return ret;
}

static public uint ToUInt_(this string str)
{
uint ret = 0;

try
{
if (!String.IsNullOrEmpty(str))
{
ret = Convert.ToUInt32(str);
}
}
catch (Exception)
{
}
return ret;
}

static public Int32 ToInt32_(this string str)
{
Int32 ret = 0;

try
{
if (!String.IsNullOrEmpty(str))
{
ret = Convert.ToInt32(str);
}
}
catch (Exception)
{
}
return ret;
}

static public short ToShort_(this string str)
{
short ret = 0;

try
{
if (!String.IsNullOrEmpty(str))
{
ret = Convert.ToInt16(str);
}
}
catch (Exception)
{
}
return ret;
}

public static long ToLong_(this string val)
{
return ToInt64_(val);
}

public static long ToInt64_(this string val)
{
long ret = 0;
try
{
if (!String.IsNullOrEmpty(val))
{
ret = Convert.ToInt64(val);
}
}
catch (Exception)
{
}
return ret;
}

public static float ToSingle_(this string val)
{
return ToFloat_(val);
}

public static float ToFloat_(this string val)
{
float ret = 0;
try
{
if (!String.IsNullOrEmpty(val))
{
ret = Convert.ToSingle(val);
}
}
catch (Exception)
{
}
return ret;
}

public static double ToDouble_(this string val)
{
double ret = 0;
try
{
if (!String.IsNullOrEmpty(val))
{
ret = Convert.ToDouble(val);
}
}
catch (Exception)
{
}
return ret;
}

public static char ToChar_(this string val)
{
char ret = default(char);
try
{
if (!String.IsNullOrEmpty(val))
{
ret = Convert.ToChar(val);
}
}
catch (Exception)
{
}
return ret;
}

public static Int32 ToInt32_(this object obj)
{
Int32 ret = 0;
try
{
if (obj != null)
{
ret = Convert.ToInt32(obj);
}
}
catch (Exception)
{
}

return ret;
}

/// <summary>
/// .net4.0 stringbuild 会有Clear 函数,到时可以删掉这个函数
/// </summary>
/// <param name="sb"></param>
public static void Clear_(this StringBuilder sb)
{
sb.Length = 0;
}


/// <summary>
/// 尝试将键和值添加到字典中:如果不存在,才添加;存在,不添加也不抛导常
/// </summary>
public static Dictionary<TKey, TValue> TryAdd_<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, TValue value)
{
if (dict.ContainsKey(key) == false) dict.Add(key, value);
return dict;
}

/// <summary>
/// 将键和值添加或替换到字典中:如果不存在,则添加;存在,则替换
/// </summary>
public static Dictionary<TKey, TValue> AddOrReplace_<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, TValue value)
{
if (dict.ContainsKey(key) == false)
{
dict.Add(key, value);
}
else
{
dict[key] = value;
}
return dict;
}

public static bool IsNumber_(string str)
{
if (string.IsNullOrEmpty(str))
{
return false;
}
var pattern = @"^\d*$";
return Regex.IsMatch(str, pattern);
}
}
84 changes: 84 additions & 0 deletions TableML/TableML/ConsoleHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

/// <summary>
/// 对console的扩充,可打印出不同颜色的字
/// </summary>
public class ConsoleHelper
{
/// <summary>
/// default 白色字
/// </summary>
/// <param name="message"></param>
/// <param name="args"></param>
public static void Log(string message, params object[] args)
{
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.White;
var msg = string.Concat("[", System.DateTime.Now.ToString("u"), "]", string.Format(message, args));
Console.WriteLine(msg);
Console.ResetColor();
}

public static void InfoWithNewLine(string message, params object[] args)
{
Info(message,args);
Console.WriteLine();
}

/// <summary>
/// info 蓝色字
/// </summary>
/// <param name="message"></param>
/// <param name="args"></param>
public static void Info(string message, params object[] args)
{
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.Cyan;
var msg = string.Concat("[", System.DateTime.Now.ToString("u"), "]", string.Format(message, args));
Console.WriteLine(msg);
Console.ResetColor();
}

/// <summary>
/// warn 黄色字
/// </summary>
/// <param name="message"></param>
/// <param name="args"></param>
public static void Warning(string message, params object[] args)
{
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.Yellow;
var msg = string.Concat("[", System.DateTime.Now.ToString("u"), "]", string.Format(message, args));
Console.WriteLine(msg);
Console.ResetColor();
}

/// <summary>
/// error 红色字
/// </summary>
/// <param name="message"></param>
/// <param name="args"></param>
public static void Error(string message, params object[] args)
{
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.Red;
var msg = string.Concat("[", System.DateTime.Now.ToString("u"), "]", string.Format(message, args));
Console.WriteLine(msg);
Console.ResetColor();
}

public static void ErrorWithStack(string message, params object[] args)
{
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.Red;
//打印出错堆栈
var msg = string.Concat("[", System.DateTime.Now.ToString("u"), "]", string.Format(message, args),new StackTrace());
Console.WriteLine(msg);
Console.ResetColor();
}
}

6 changes: 6 additions & 0 deletions TableML/TableML/TableFile.cs
Original file line number Diff line number Diff line change
@@ -93,6 +93,12 @@ public TableFile(string[] contents) : base(contents) { }
public TableFile() : base() { }
public TableFile(string fileFullPath, Encoding encoding) : base(fileFullPath, encoding) { }

public new static TableFile LoadFromString(string content)
{
TableFile tabFile = new TableFile(content);
return tabFile;
}

public new static TableFile LoadFromString(params string[] content)
{
TableFile tabFile = new TableFile(content);
16 changes: 9 additions & 7 deletions TableML/TableML/TableFileGeneric.cs
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
@@ -13,7 +13,7 @@ namespace TableML
/// 表格读取的核心基础类,可以设置泛型
/// </summary>
/// <typeparam name="T"></typeparam>
public partial class TableFile<T> : IDisposable, IEnumerable<TableFileRow> where T : TableFileRow
public partial class TableFile<T> : IDisposable, IEnumerable<TableFileRow> where T : TableFileRow, new()
{
private readonly TableFileConfig _config;

@@ -144,11 +144,12 @@ protected bool ParseReader(TextReader oReader)
return false;
}


//NOTE 如果第一行为null则会exception
string[] firstLineSplitString = headLine.Split(_config.Separators, StringSplitOptions.None); // don't remove RemoveEmptyEntries!
string[] firstLineDef = new string[firstLineSplitString.Length];

var metaLineArr = metaLine.Split(_config.Separators, StringSplitOptions.None);
string[] firstLineDef = new string[metaLineArr.Length];
Console.WriteLine("headLine.length={0},headMeta.length={1}", firstLineSplitString.Length, metaLineArr.Length);
Array.Copy(metaLineArr, 0, firstLineDef, 0, metaLineArr.Length); // 拷贝,确保不会超出表头的

for (int i = 0; i < firstLineSplitString.Length; i++)
@@ -178,7 +179,8 @@ protected bool ParseReader(TextReader oReader)

TabInfo[_rowIndex] = splitString1;

T newT = (T)Activator.CreateInstance(typeof(T), _rowIndex, Headers); // the New Object may not be used this time, so cache it!
T newT = new T();// prevent IL2CPP stripping!
newT.Ctor(_rowIndex, Headers); // the New Object may not be used this time, so cache it!

newT.Values = splitString1;

@@ -281,7 +283,7 @@ protected void AutoParse(TableFileRow tableRow, string[] cellStrs)

field.SetValue(tableRow, method.Invoke(tableRow, new object[]
{
cellStrs[index] , defaultValue
cellStrs[index] , defaultValue
}));
}
else
@@ -459,4 +461,4 @@ IEnumerator IEnumerable.GetEnumerator()
return Rows.Values.GetEnumerator();
}
}
}
}
32 changes: 20 additions & 12 deletions TableML/TableML/TableFileRow.cs
Original file line number Diff line number Diff line change
@@ -47,22 +47,28 @@ public virtual bool IsAutoParse
}
}

/// <summary>
/// Initializes a new instance of the <see cref="T:TableML.TableFileRow"/> class.
/// </summary>
/// <param name="rowNumber">Row number.</param>
/// <param name="headerInfos">Header infos.</param>
public TableFileRow()
{

}

/// <summary>
/// Initializes a new instance of the <see cref="T:TableML.TableFileRow"/> class.
/// </summary>
/// <param name="rowNumber">Row number.</param>
/// <param name="headerInfos">Header infos.</param>
public TableFileRow(int rowNumber, Dictionary<string, HeaderInfo> headerInfos)
{
Ctor(rowNumber, headerInfos);
}

/// <summary>
/// Ctor the specified rowNumber and headerInfos.
/// </summary>
/// <param name="rowNumber">Row number.</param>
/// <param name="headerInfos">Header infos.</param>
private void Ctor(int rowNumber, Dictionary<string, HeaderInfo> headerInfos)
/// <summary>
/// Ctor the specified rowNumber and headerInfos.
/// `public` for prevent IL2CPP striping
/// </summary>
/// <param name="rowNumber">Row number.</param>
/// <param name="headerInfos">Header infos.</param>
internal void Ctor(int rowNumber, Dictionary<string, HeaderInfo> headerInfos)
{
RowNumber = rowNumber;
HeaderInfos = headerInfos;
@@ -85,6 +91,8 @@ private void Ctor(int rowNumber, Dictionary<string, HeaderInfo> headerInfos)
/// <summary>
/// Store values of this row
/// </summary>


public string[] Values { get; internal set; }

/// <summary>
@@ -118,7 +126,7 @@ public virtual object GetPrimaryKey()
/// <param name="index">Index.</param>
public virtual object Get(int index)
{
if (index > Values.Length || index < 0)
if (index >= Values.Length || index < 0)
{
throw new Exception(string.Format("Overflow index `{0}`", index));
}
9 changes: 8 additions & 1 deletion TableML/TableML/TableML.csproj
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>TableML</RootNamespace>
<AssemblyName>TableML</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
@@ -21,6 +21,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -29,8 +30,11 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Compile Include="ConsoleHelper.cs" />
<Compile Include="CSharpEx.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TableFileGeneric.cs" />
<Compile Include="TableFileWriter.cs" />
@@ -40,6 +44,9 @@
<Compile Include="TableObjectRow.cs" />
<Compile Include="TableRowFieldParser.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
5 changes: 5 additions & 0 deletions TableML/TableML/TableObjectRow.cs
Original file line number Diff line number Diff line change
@@ -8,6 +8,11 @@ namespace TableML
/// </summary>
public class TableObjectRow : TableFileRow
{
public TableObjectRow()
{

}

public TableObjectRow(int rowNumber, Dictionary<string, HeaderInfo> headerInfos) : base(rowNumber, headerInfos)
{
}
149 changes: 136 additions & 13 deletions TableML/TableML/TableRowFieldParser.cs
Original file line number Diff line number Diff line change
@@ -8,6 +8,39 @@ namespace TableML
/// </summary>
public partial class TableRowFieldParser
{
public byte Get_byte(string value, string defaultValue)
{
var str = Get_string(value, defaultValue);
return string.IsNullOrEmpty(str) ? default(byte) : str.ToByte_();
}

public byte Get_Byte(string value, string defaultValue)
{
return Get_byte(value, defaultValue);
}

public sbyte Get_sbyte(string value, string defaultValue)
{
var str = Get_string(value, defaultValue);
return string.IsNullOrEmpty(str) ? default(sbyte) : str.ToSByte_();
}

public sbyte Get_SByte(string value, string defaultValue)
{
return Get_sbyte(value, defaultValue);
}

public char Get_char(string value, string defaultValue)
{
var str = Get_string(value, defaultValue);
return string.IsNullOrEmpty(str) ? default(char) : str.ToChar_();
}

public char Get_Char(string value, string defaultValue)
{
return Get_char(value, defaultValue);
}

public string Get_String(string value, string defaultValue)
{
return Get_string(value, defaultValue);
@@ -20,6 +53,33 @@ public string Get_string(string value, string defaultValue)
return value;
}

/// <summary>
/// 字符串中包含一些要去掉的分隔符
/// </summary>
/// <param name="value"></param>
/// <param name="splits">要去掉的符号</param>
/// <returns></returns>
public string Get_String(string value,string defaultValue, params string[] splits)
{
var str = Get_string(value, defaultValue);
if (splits != null && splits.Length > 0)
{
foreach (var split in splits)
{
if (str.Contains(split))
{
str = str.Replace(split, "");
}
}
}
return str;
}

public string Get_StringByArray(string value, string defaultValue)
{
return Get_String(value, defaultValue, new string[] { "{", "}" ,"|"});
}

public double Get_number(string value, string defaultValue)
{
return Get_double(value, defaultValue);
@@ -43,48 +103,103 @@ public bool Get_bool(string value, string defaultValue)
public bool Get_Boolean(string value, string defaultValue)
{
var str = Get_string(value, defaultValue);
bool result;
if (bool.TryParse(str, out result))
{
return result;
}
return Get_int(value, defaultValue) != 0;
if (string.IsNullOrEmpty(str)) return false;
return str.ToBool_();
}

public long Get_long(string value, string defaultValue)
{
var str = Get_string(value, defaultValue);
return string.IsNullOrEmpty(str) ? default(long) : long.Parse(str);
return string.IsNullOrEmpty(str) ? default(long) : str.ToInt64_();
}
public int Get_int(string value, string defaultValue)
{
var str = Get_string(value, defaultValue);
return string.IsNullOrEmpty(str) ? default(int) : int.Parse(str);
return string.IsNullOrEmpty(str) ? default(int) : str.ToInt32_();
}

public double Get_double(string value, string defaultValue)
{
var str = Get_string(value, defaultValue);
return string.IsNullOrEmpty(str) ? default(double) : double.Parse(str);
return string.IsNullOrEmpty(str) ? default(double) : str.ToDouble_();
}

public float Get_float(string value, string defaultValue)
{
var str = Get_string(value, defaultValue);
return string.IsNullOrEmpty(str) ? default(float) : float.Parse(str);
return string.IsNullOrEmpty(str) ? default(float) : str.ToFloat_();
}
public uint Get_uint(string value, string defaultValue)
{
var str = Get_string(value, defaultValue);
return string.IsNullOrEmpty(str) ? default(int) : uint.Parse(str);
return string.IsNullOrEmpty(str) ? default(int) : str.ToUInt_();
}

public string[] Get_string_array(string value, string defaultValue)
{
var str = Get_string(value, defaultValue);
var str = Get_StringByArray(value, defaultValue);
if (string.IsNullOrEmpty(str)) return null;
if (str.Contains(",") == false) return new string[] {str};
return str.Split(',');
}

public short[] Get_short_array(string value, string defaultValue)
{
var str = Get_StringByArray(value, defaultValue);
if (string.IsNullOrEmpty(str)) return null;
if (str.Contains(",") == false) return new short[] {str.ToShort_()};
var strs = str.Split(',');
if (strs != null && strs.Length > 0)
{
List<short> array = new List<short>();
var max = strs.Length;
for (int idx = 0; idx < max; idx++)
{
array.Add(strs[idx].ToShort_());
}
return array.ToArray();
}
return null;
}

public int[] Get_int_array(string value, string defaultValue)
{
var str = Get_StringByArray(value, defaultValue);
if (string.IsNullOrEmpty(str)) return null;
if (str.Contains(",") == false) return new int[] {str.ToInt32_()};
var strs= str.Split(',');
if (strs != null && strs.Length > 0)
{
List<int> array = new List<int>();
var max = strs.Length;
for (int idx = 0; idx < max; idx++)
{
array.Add(strs[idx].ToInt32_());
}
return array.ToArray();
}
return null;
}

public float[] Get_float_array(string value, string defaultValue)
{
var str = Get_StringByArray(value, defaultValue);
if (string.IsNullOrEmpty(str)) return null;
if (str.Contains(",") == false) return new float[] {str.ToFloat_()};
var strs = str.Split(',');
if (strs != null && strs.Length > 0)
{
List<float> array = new List<float>();
var max = strs.Length;
for (int idx = 0; idx < max; idx++)
{
array.Add(strs[idx].ToFloat_());
}
return array.ToArray();
}
return null;
}

public Dictionary<string, int> Get_Dictionary_string_int(string value, string defaultValue)
{
return GetDictionary<string, int>(value, defaultValue);
@@ -94,6 +209,7 @@ public Dictionary<TKey, TValue> GetDictionary<TKey, TValue>(string value, string
{
var dict = new Dictionary<TKey, TValue>();
var str = Get_String(value, defaultValue);
if (str.Contains(",") == false) return null;
var arr = str.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

foreach (var item in arr)
@@ -108,7 +224,14 @@ public Dictionary<TKey, TValue> GetDictionary<TKey, TValue>(string value, string

protected T ConvertString<T>(string value)
{
return (T)Convert.ChangeType(value, typeof(T));
try
{
return (T)Convert.ChangeType(value, typeof(T));
}
catch (Exception ex)
{
return default(T);
}
}

}
964 changes: 636 additions & 328 deletions TableML/TableMLCompiler/BatchCompiler.cs

Large diffs are not rendered by default.

419 changes: 278 additions & 141 deletions TableML/TableMLCompiler/Compiler.cs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion TableML/TableMLCompiler/CompilerConfig.cs
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ public class CompilerConfig
/// <summary>
/// 编译后的扩展名
/// </summary>
public string ExportTabExt = ".tml";
public string ExportTabExt = ".tsv";
// 被认为是注释的表头
public string[] CommentStartsWith = { "Comment", "#" };

307 changes: 298 additions & 9 deletions TableML/TableMLCompiler/DefaultTemplate.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@


namespace TableML.Compiler
{

/// <summary>
/// Default template, for Unity + KEngine
/// </summary>
public class DefaultTemplate
{
public static string GenCodeTemplate = @"
#region Copyright (c) 2015 KEngine / Kelly <http://github.com/mr-kelly>, All rights reserved.
/// <summary>
/// Default template, for Unity + KEngine
/// </summary>
public class DefaultTemplate
{
#region LicenseStr

public static string LicenseStr = @"#region Copyright (c) 2015 KEngine / Kelly <http://github.com/mr-kelly>, All rights reserved.
// KEngine - Asset Bundle framework for Unity3D
// ===================================
@@ -31,7 +32,12 @@ public class DefaultTemplate
// License along with this library.
#endregion
";
#endregion

#region 全部表的代码生成到一个cs中

public static string GenCodeTemplate = string.Concat(LicenseStr, @"
// This file is auto generated by SettingModuleEditor.cs!
// Don't manipulate me!
// Default Template for KEngine!
@@ -287,6 +293,289 @@ internal void Reload(TableFileRow row)
}
{% endfor %}
}
";
");
#endregion

#region Manager类模版

/// <summary>
/// Manager类模版
/// </summary>
public static string GenManagerCodeTemplate =string.Concat(LicenseStr,@"
// 此代码由工具生成,请勿修改,如需扩展请编写同名Class并加上partial关键字
using System.Collections;
using System.Collections.Generic;
using KEngine;
using KEngine.Modules;
using TableML;
namespace {{ NameSpace }}
{
/// <summary>
/// All settings list here, so you can reload all settings manully from the list.
/// </summary>
public partial class SettingsManager
{
private static IReloadableSettings[] _settingsList;
public static IReloadableSettings[] SettingsList
{
get
{
if (_settingsList == null)
{
_settingsList = new IReloadableSettings[]
{
{{ ClassNames }}
};
}
return _settingsList;
}
}
#if UNITY_EDITOR
[UnityEditor.MenuItem(""KEngine/Settings/Try Reload All Settings Code"")]
#endif
public static void AllSettingsReload()
{
for (var i = 0; i < SettingsList.Length; i++)
{
var settings = SettingsList[i];
if (settings.Count > 0 // if never reload, ignore
#if UNITY_EDITOR
|| !UnityEditor.EditorApplication.isPlaying // in editor and not playing, force load!
#endif
)
{
settings.ReloadAll();
}
}
}
}
}
");
#endregion

#region 每张表(Class)对应的模版(Template)

/// <summary>
/// 单张表(Class)对应的模版(Template)
/// </summary>
public static string GenCodeTemplateOneFile = string.Concat(LicenseStr, @"
// 此代码由工具生成,请勿修改,如需扩展请编写同名Class并加上partial关键字
using System.Collections;
using System.Collections.Generic;
using KEngine;
using KEngine.Modules;
using TableML;
namespace {{ NameSpace }}
{
{% for file in Files %}
/// <summary>
/// Auto Generate for Tab File: {{ file.TabFilePaths }}
/// Excel File: {{ file.TabFileNames }}
/// No use of generic and reflection, for better performance, less IL code generating
/// </summary>>
public partial class {{file.ClassName}}Settings : IReloadableSettings
{
/// <summary>
/// How many reload function load?
/// </summary>>
public static int ReloadCount { get; private set; }
public static readonly string[] TabFilePaths =
{
{{ file.TabFilePaths }}
};
public static {{file.ClassName}}Settings _instance = new {{file.ClassName}}Settings();
Dictionary<{{ file.PrimaryKeyField.FormatType }}, {{file.ClassName}}Setting> _dict = new Dictionary<{{ file.PrimaryKeyField.FormatType }}, {{file.ClassName}}Setting>();
/// <summary>
/// Trigger delegate when reload the Settings
/// </summary>>
public static System.Action OnReload;
/// <summary>
/// Constructor, just reload(init)
/// When Unity Editor mode, will watch the file modification and auto reload
/// </summary>
private {{file.ClassName}}Settings()
{
}
/// <summary>
/// Get the singleton
/// </summary>
/// <returns></returns>
public static {{file.ClassName}}Settings GetInstance()
{
if (ReloadCount == 0)
{
_instance._ReloadAll(true);
#if UNITY_EDITOR
if (SettingModule.IsFileSystemMode)
{
for (var j = 0; j < TabFilePaths.Length; j++)
{
var tabFilePath = TabFilePaths[j];
SettingModule.WatchSetting(tabFilePath, (path) =>
{
if (path.Replace(""\\"", ""/"").EndsWith(path))
{
_instance.ReloadAll();
Log.LogConsole_MultiThread(""File Watcher! Reload success! -> "" + path);
}
});
}
}
#endif
}
return _instance;
}
public int Count
{
get
{
return _dict.Count;
}
}
/// <summary>
/// Do reload the setting file: {{ file.ClassName }}, no exception when duplicate primary key
/// </summary>
public void ReloadAll()
{
_ReloadAll(false);
}
/// <summary>
/// Do reload the setting class : {{ file.ClassName }}, no exception when duplicate primary key, use custom string content
/// </summary>
public void ReloadAllWithString(string context)
{
_ReloadAll(false, context);
}
/// <summary>
/// Do reload the setting file: {{ file.ClassName }}
/// </summary>
void _ReloadAll(bool throwWhenDuplicatePrimaryKey, string customContent = null)
{
for (var j = 0; j < TabFilePaths.Length; j++)
{
var tabFilePath = TabFilePaths[j];
TableFile tableFile;
if (customContent == null)
tableFile = SettingModule.Get(tabFilePath, false);
else
tableFile = TableFile.LoadFromString(customContent);
using (tableFile)
{
foreach (var row in tableFile)
{
var pk = {{ file.ClassName }}Setting.ParsePrimaryKey(row);
{{file.ClassName}}Setting setting;
if (!_dict.TryGetValue(pk, out setting))
{
setting = new {{file.ClassName}}Setting(row);
_dict[setting.{{ file.PrimaryKeyField.Name }}] = setting;
}
else
{
if (throwWhenDuplicatePrimaryKey) throw new System.Exception(string.Format(""DuplicateKey, Class: {0}, File: {1}, Key: {2}"", this.GetType().Name, tabFilePath, pk));
else setting.Reload(row);
}
}
}
}
if (OnReload != null)
{
OnReload();
}
ReloadCount++;
Log.Info(""Reload settings: {0}, Row Count: {1}, Reload Count: {2}"", GetType(), Count, ReloadCount);
}
/// <summary>
/// foreachable enumerable: {{ file.ClassName }}
/// </summary>
public static IEnumerable GetAll()
{
foreach (var row in GetInstance()._dict.Values)
{
yield return row;
}
}
/// <summary>
/// GetEnumerator for `MoveNext`: {{ file.ClassName }}
/// </summary>
public static IEnumerator GetEnumerator()
{
return GetInstance()._dict.Values.GetEnumerator();
}
/// <summary>
/// Get class by primary key: {{ file.ClassName }}
/// </summary>
public static {{file.ClassName}}Setting Get({{ file.PrimaryKeyField.FormatType }} primaryKey)
{
{{file.ClassName}}Setting setting;
if (GetInstance()._dict.TryGetValue(primaryKey, out setting)) return setting;
return null;
}
// ========= CustomExtraString begin ===========
{% if file.Extra %}{{ file.Extra }}{% endif %}
// ========= CustomExtraString end ===========
}
/// <summary>
/// Auto Generate for Tab File: {{ file.TabFilePaths }}
/// Excel File: {{ file.TabFileNames }}
/// Singleton class for less memory use
/// </summary>
public partial class {{file.ClassName}}Setting : TableRowFieldParser
{
{% for field in file.Fields %}
/// <summary>
/// {{ field.Comment }}
/// </summary>
public {{ field.FormatType }} {{ field.Name}} { get; private set;}
{% endfor %}
internal {{file.ClassName}}Setting(TableFileRow row)
{
Reload(row);
}
internal void Reload(TableFileRow row)
{ {% for field in file.Fields %}
{{ field.Name}} = row.Get_{{ field.TypeMethod }}(row.Values[{{ field.Index }}], ""{{ field.DefaultValue }}""); {% endfor %}
}
/// <summary>
/// Get PrimaryKey from a table row
/// </summary>
/// <param name=""row""></param>
/// <returns></returns>
public static {{ file.PrimaryKeyField.FormatType }} ParsePrimaryKey(TableFileRow row)
{
var primaryKey = row.Get_{{ file.PrimaryKeyField.TypeMethod }}(row.Values[{{ file.PrimaryKeyField.Index }}], ""{{ file.PrimaryKeyField.DefaultValue }}"");
return primaryKey;
}
}
{% endfor %}
}
");
#endregion
}
}
14 changes: 14 additions & 0 deletions TableML/TableMLCompiler/ExcelConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace TableML.Compiler
{
public static class ExcelConfig
{
/// <summary>
/// excel的格式是否为ksframework形式的配置表
/// </summary>
public static bool IsKSFrameworkFormat = true;
/// <summary>
/// 默认使用Excel的文件名作为生成类和tsv的名字,如果有特殊需求比如从Excel的指定列读取导出的类名,可以查看定制的范例
/// </summary>
public static bool IsSaveCompileResult = false;
}
}
15 changes: 13 additions & 2 deletions TableML/TableMLCompiler/ITableSourceFile.cs
Original file line number Diff line number Diff line change
@@ -3,9 +3,20 @@
using System.Linq;
using System.Text;

namespace TableMLCompiler
namespace TableML.Compiler
{
class ITableSourceFile
/// <summary>
/// 读取带有头部、声明和注释的文件表格
/// </summary>
public interface ITableSourceFile
{
Dictionary<string, int> ColName2Index { get; set; }
Dictionary<int, string> Index2ColName { get; set; }
Dictionary<string, string> ColName2Statement { get; set; }// string,or something
Dictionary<string, string> ColName2Comment { get; set; }// string comment
int GetRowsCount();
int GetColumnCount();
string GetString(string columnName, int row);
string ExcelFileName { get; set; }
}
}
405 changes: 405 additions & 0 deletions TableML/TableMLCompiler/SimpleCSVFile.cs

Large diffs are not rendered by default.

473 changes: 348 additions & 125 deletions TableML/TableMLCompiler/SimpleExcelFile.cs

Large diffs are not rendered by default.

71 changes: 71 additions & 0 deletions TableML/TableMLCompiler/SimpleTSVFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace TableML.Compiler
{
/// <summary>
/// TSV格式的支持
/// </summary>
public class SimpleTSVFile : ITableSourceFile
{
public Dictionary<string, int> ColName2Index { get; set; }
public Dictionary<int, string> Index2ColName { get; set; }
public Dictionary<string, string> ColName2Statement { get; set; }
public Dictionary<string, string> ColName2Comment { get; set; }
public string ExcelFileName { get; set; }

private TableFile _tableFile;
private int _columnCount;
public SimpleTSVFile(string filePath)
{
ColName2Index = new Dictionary<string, int>();
Index2ColName = new Dictionary<int, string>();
ColName2Statement = new Dictionary<string, string>();
ColName2Comment = new Dictionary<string, string>();
ExcelFileName = Path.GetFileName(filePath);
try
{
ParseTsv(filePath);
}
catch (Exception e)
{
throw new Exception("Error TSV File: " + filePath + " / " + e.Message);
}
}

private void ParseTsv(string filePath)
{
//NOTE 如果报无法打开,可能是文件编码格式的问题!
_tableFile = TableFile.LoadFromFile(filePath);
_columnCount = _tableFile.GetColumnCount();


// 通过TableFile注册头信息
var commentRow = _tableFile.GetRow(1);
foreach (var kv in _tableFile.Headers)
{
var header = kv.Value;
ColName2Index[header.HeaderName] = header.ColumnIndex;
Index2ColName[header.ColumnIndex] = header.HeaderName;
ColName2Statement[header.HeaderName] = header.HeaderMeta;
ColName2Comment[header.HeaderName] = commentRow[header.ColumnIndex];
}
}
public int GetRowsCount()
{
return _tableFile.GetRowCount() - 1; // 减去注释行
}

public int GetColumnCount()
{
return _columnCount;
}

public string GetString(string columnName, int dataRow)
{
return _tableFile.GetRow(dataRow + 1 + 1)[columnName]; // 1行开始,并且多了说明行,+2
}
}
}
7 changes: 5 additions & 2 deletions TableML/TableMLCompiler/TableCompileResult.cs
Original file line number Diff line number Diff line change
@@ -20,11 +20,14 @@ public class TableCompileResult
{
public string TabFileFullPath { get; set; }
public string TabFileRelativePath { get; set; }
public List<TableColumnVars> FieldsInternal { get; set; } // column + type
/// <summary>
/// column + type
/// </summary>
public List<TableColumnVars> FieldsInternal { get; set; }

public string PrimaryKey { get; set; }
public ITableSourceFile ExcelFile { get; internal set; }

public string TabFileNames { get { return ExcelFile.ExcelFileName; } }
public TableCompileResult()
{
FieldsInternal = new List<TableColumnVars>();
50 changes: 34 additions & 16 deletions TableML/TableMLCompiler/TableMLCompiler.csproj
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>TableMLCompiler</RootNamespace>
<AssemblyName>TableMLCompiler</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
@@ -20,6 +20,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -28,32 +29,42 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="ICSharpCode.SharpZipLib">
<HintPath>..\libs\ICSharpCode.SharpZipLib.dll</HintPath>
<Private>False</Private>
<Reference Include="CsvHelper, Version=11.0.0.0, Culture=neutral, PublicKeyToken=8c4959082be5c823, processorArchitecture=MSIL">
<HintPath>..\packages\CsvHelper.11.0.1\lib\net45\CsvHelper.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NPOI, Version=2.2.1.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\libs\NPOI.dll</HintPath>
<Reference Include="Microsoft.CSharp" />
<Reference Include="NPOI, Version=2.3.0.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
<HintPath>..\packages\NPOI.2.3.0\lib\net20\NPOI.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NPOI.OOXML, Version=2.2.1.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\libs\NPOI.OOXML.dll</HintPath>
<Reference Include="NPOI.OOXML, Version=2.3.0.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
<HintPath>..\packages\NPOI.2.3.0\lib\net20\NPOI.OOXML.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NPOI.OpenXml4Net, Version=2.2.1.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\libs\NPOI.OpenXml4Net.dll</HintPath>
<Reference Include="NPOI.OpenXml4Net, Version=2.3.0.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
<HintPath>..\packages\NPOI.2.3.0\lib\net20\NPOI.OpenXml4Net.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NPOI.OpenXmlFormats, Version=2.2.1.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\libs\NPOI.OpenXmlFormats.dll</HintPath>
<Reference Include="NPOI.OpenXmlFormats, Version=2.3.0.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
<HintPath>..\packages\NPOI.2.3.0\lib\net20\NPOI.OpenXmlFormats.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="DotLiquid">
<HintPath>DotLiquid.dll</HintPath>
</Reference>
<Reference Include="System.ValueTuple, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<Choose>
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
@@ -65,14 +76,18 @@
</Choose>
<ItemGroup>
<Compile Include="CompilerConfig.cs" />
<Compile Include="ExcelConfig.cs" />
<Compile Include="ITableSourceFile.cs" />
<Compile Include="SimpleCSVFile.cs" />
<Compile Include="SimpleTSVFile.cs" />
<Compile Include="TableCompileResult.cs" />
<Compile Include="Compiler.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SimpleExcelFile.cs" />
<Compile Include="BatchCompiler.cs" />
<Compile Include="DefaultTemplate.cs" />
<Compile Include="TableColumnVars.cs" />
<Compile Include="TableTemplateVars.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\TableML\TableML.csproj">
@@ -81,6 +96,9 @@
<Private>False</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Choose>
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
<ItemGroup>
117 changes: 117 additions & 0 deletions TableML/TableMLCompiler/TableTemplateVars.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using DotLiquid;

namespace TableML.Compiler
{
/// <summary>
/// 用于liquid模板
/// </summary>
public class TableTemplateVars
{
public delegate string CustomClassNameDelegate(string originClassName, string filePath);

/// <summary>
/// You can custom class name
/// </summary>
public static TableTemplateVars.CustomClassNameDelegate CustomClassNameFunc;

public List<string> RelativePaths = new List<string>();

/// <summary>
/// 构建成一个数组"aaa", "bbb"
/// </summary>
public string TabFilePaths
{
get
{
var paths = "\"" + string.Join("\", \"", RelativePaths.ToArray()) + "\"";
return paths;
}
}

public string TabFileNames { get; set; }

public string ClassName { get; set; }
public List<TableColumnVars> FieldsInternal { get; set; } // column + type

public string PrimaryKey { get; set; }

public List<Hash> Fields
{
get { return (from f in FieldsInternal select Hash.FromAnonymousObject(f)).ToList(); }
}

/// <summary>
/// Get primary key, the first column field
/// </summary>
public Hash PrimaryKeyField
{
get
{ //如果加上判断会导致部分生成的 ParsePrimaryKey() 没有类型
if (Fields != null && Fields.Count > 0)
{
return Fields[0];
}
return null;
// return Fields[0];
}
}

/// <summary>
/// Custom extra strings
/// </summary>
public string Extra { get; private set; }

public List<Hash> Columns2DefaultValus { get; set; } // column + Default Values

public TableTemplateVars(TableCompileResult compileResult, string extraString)
: base()
{
var tabFileRelativePath = compileResult.TabFileRelativePath;
RelativePaths.Add(compileResult.TabFileRelativePath);

TabFileNames = compileResult.ExcelFile.ExcelFileName;
ClassName = DefaultClassNameParse(tabFileRelativePath);
// 可自定义Class Name
if (CustomClassNameFunc != null)
ClassName = CustomClassNameFunc(ClassName, tabFileRelativePath);

FieldsInternal = compileResult.FieldsInternal;
PrimaryKey = compileResult.PrimaryKey;
Columns2DefaultValus = new List<Hash>();

Extra = extraString;
}

/// <summary>
/// get a class name from tab file path, default strategy
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
string DefaultClassNameParse(string tabFilePath)
{
// 未处理路径的类名, 去掉后缀扩展名
var classNameOrigin = Path.ChangeExtension(tabFilePath, null);

// 子目录合并,首字母大写, 组成class name
var className = classNameOrigin.Replace("/", "_").Replace("\\", "_");
className = className.Replace(" ", "");
className = string.Join("", (from name
in className.Split(new[] { '_' }, StringSplitOptions.RemoveEmptyEntries)
select (name[0].ToString().ToUpper() + name.Substring(1, name.Length - 1)))
.ToArray());

// 去掉+或#号后面的字符
var plusSignIndex = className.IndexOf("+");
className = className.Substring(0, plusSignIndex == -1 ? className.Length : plusSignIndex);
plusSignIndex = className.IndexOf("#");
className = className.Substring(0, plusSignIndex == -1 ? className.Length : plusSignIndex);

return className;

}
}
}
6 changes: 4 additions & 2 deletions TableML/TableMLCompiler/packages.config
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NPOI" version="2.2.1" targetFramework="net35" />
<package id="CsvHelper" version="11.0.1" targetFramework="net45" />
<package id="NPOI" version="2.3.0" targetFramework="net35" requireReinstallation="true" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net35" />
</packages>
<package id="System.ValueTuple" version="4.4.0" targetFramework="net45" />
</packages>
136 changes: 126 additions & 10 deletions TableML/TableMLCompilerConsole/Program.cs
Original file line number Diff line number Diff line change
@@ -2,10 +2,11 @@
using CommandLine;
using CommandLine.Text;
using TableML.Compiler;
using System.IO;
using TableML;

namespace TableCompilerConsole
{

class Option
{
[Option('s', "Src", Required = true,
@@ -26,7 +27,7 @@ class Option


[Option('v', "verbose", DefaultValue = true,
HelpText = "Prints all messages to standard output.")]
HelpText = "Prints all messages to standard output.")]
public bool Verbose { get; set; }

[HelpOption]
@@ -35,9 +36,21 @@ public string GetUsage()
return HelpText.AutoBuild(this, (HelpText current) => HelpText.DefaultParsingErrorsHandler(this, current));
}
}

/// <summary>
/// 命令行模式编译Excel,参数通过命令行传递
/// </summary>
class TableCompilerConsole
{
public static void Main(string[] args)
{
ParseArgs(args);
//CompileAllToCSharp();
//CompileAllToLua();
//CompileAllToOneCSharp();
}

static void ParseArgs(string[] args)
{
var options = new Option();
if (CommandLine.Parser.Default.ParseArguments(args, options))
@@ -52,19 +65,122 @@ public static void Main(string[] args)
{
Console.WriteLine(options.TemplateFilePath);
templateString = System.IO.File.ReadAllText(options.TemplateFilePath);

}

//var results =
batchCompiler.CompileTableMLAll(options.Directory, options.OutputDirectory, options.CodeFilePath,
templateString, "AppSettings", ".tml", null, !string.IsNullOrEmpty(options.CodeFilePath));
var genParam = new GenParam(){genCodeFilePath = options.CodeFilePath,genCodeTemplateString = templateString,genCSharpClass = true,forceAll = true};
batchCompiler.CompileAllToOneFile(options.Directory, options.OutputDirectory,genParam);

Console.WriteLine("Done!");
}
}

// var compiler = new Compiler();
// var result = compiler.Compile(options.Directory);
// Console.WriteLine(string.Format("Compile excel file: {0} , to {1}", options.Directory, result.TabFileRelativePath));
#region 测试编译功能

/// <summary>
/// 编译单个excel
/// </summary>
public static void CompileOne()
{
var startPath = Environment.CurrentDirectory;
//源excel文件路径
var srcFile = Path.Combine(startPath, "settingsrc", "Y002 邮件配置表.xlsx");
//输出tml文件路径
var OutputDirectory = Path.Combine(startPath, "setting", "Test.tsv");
//生成的代码路径
//var CodeFilePath = "Code.cs";
if (File.Exists(srcFile) == false)
{
Console.WriteLine("{0} 源文件不存在!", srcFile);
return;
}

Console.WriteLine("当前编译的Excel:{0}", srcFile);
//代码的重新生成
var param = new CompilerParam() {path = srcFile, ExportTsvPath = OutputDirectory};
new Compiler().Compile(param);
Console.WriteLine("Done!");
}

/// <summary>
/// 编译整个目录的excel,每个表生成一个lua文件,不生成c#和tsv
/// </summary>
public static void CompileAllToLua()
{
var startPath = Environment.CurrentDirectory;
Console.WriteLine("当前目录:{0}", startPath);
//源excel文件路径
var srcPath = "./SettingSource/";
//输出tml文件路径
var exportTsvPath = "./Setting/";
var exportLuaPath = "./Lua/configs/";

string settingCodeIgnorePattern = "(I18N/.*)|(StringsTable.*)|(tool/*)|(log/*)|(server/*)|(client/*)";
var genParam = new GenParam()
{
settingCodeIgnorePattern = settingCodeIgnorePattern,
genCSharpClass = false, genCodeFilePath = null, forceAll = true, ExportLuaPath = exportLuaPath
};
var compilerParam = new CompilerParam() {CanExportTsv = false, ExportTsvPath = exportTsvPath, ExportLuaPath = exportLuaPath};
var results = new BatchCompiler().CompileAll(srcPath, exportTsvPath, genParam, compilerParam);

Console.WriteLine("Done!");
}

/// <summary>
/// 编译整个目录的excel为c#+tsv
/// </summary>
public static void CompileAllToCSharp()
{
var startPath = Environment.CurrentDirectory;
Console.WriteLine("当前目录:{0}", startPath);
//源excel文件路径
var srcPath = "./SettingSource/";
//输出tml文件路径
var exportTsvPath = "./Setting/";
var exportCSPath = "./CSharp/";

string settingCodeIgnorePattern = "(I18N/.*)|(StringsTable.*)|(tool/*)|(log/*)|(server/*)|(client/*)";
var genParam = new GenParam()
{
genCodeTemplateString = DefaultTemplate.GenCodeTemplateOneFile, settingCodeIgnorePattern = settingCodeIgnorePattern,
genCSharpClass = true, genCodeFilePath = exportCSPath, forceAll = true
};
var compilerParam = new CompilerParam() {CanExportTsv = true, ExportTsvPath = exportTsvPath, ExportLuaPath = null};
var results = new BatchCompiler().CompileAll(srcPath, exportTsvPath, genParam, compilerParam);

Console.WriteLine("Done!");
}

public static void CompileAllToOneCSharp()
{
var startPath = Environment.CurrentDirectory;
Console.WriteLine("当前目录:{0}", startPath);
//源excel文件路径
var srcPath = "./SettingSource/";
//输出tml文件路径
var exportTsvPath = "./Setting/";
var exportCSPath = "./CSharp/";

string settingCodeIgnorePattern = "(I18N/.*)|(StringsTable.*)|(tool/*)|(log/*)|(server/*)|(client/*)";
var genParam = new GenParam()
{
genCodeTemplateString = DefaultTemplate.GenCodeTemplateOneFile, settingCodeIgnorePattern = settingCodeIgnorePattern,
genCSharpClass = true, genCodeFilePath = exportCSPath, forceAll = true
};
var compilerParam = new CompilerParam() {CanExportTsv = true, ExportTsvPath = exportTsvPath, ExportLuaPath = null};
var results = new BatchCompiler().CompileAll(srcPath, exportTsvPath, genParam, compilerParam);

Console.WriteLine("Done!");
}

public static void LoadTest()
{
var fileContent =
"id\ttype\texp\thp\tattack\nint\tint\tint\tint\tint\t\n1\t1\t100\t1\t1001\n2\t2\t1000\t1\t1002\n3\t3\t2000\t1\t1003\n4\t4\t3000\t1\t1004\n5\t5\t5000\t1\t1005\n6\t6\t6000\t1\t1006\n7\t7\t7000\t1\t1007\n8\t8\t8000\t1\t1008\n9\t9\t9000\t1\t1009\n10\t10\t10000\t1\t1010\n11\t11\t20000\t1\t1010\n12\t12\t40000\t1\t1010\n13\t13\t50000\t1\t1010\n14\t14\t70000\t1\t1010\n15\t15\t80000\t1\t1010\n16\t16\t90000\t1\t1010\n17\t17\t100000\t1\t1010\n18\t18\t122000\t1\t1010\n19\t19\t136000\t1\t1010\n20\t20\t150000\t1\t1010\n21\t21\t235000\t1\t1010\n22\t22\t320000\t1\t1010\n23\t23\t405000\t1\t1010\n24\t24\t490000\t1\t1010\n25\t25\t575000\t1\t1010\n26\t26\t660000\t1\t1010\n27\t27\t745000\t1\t1010\n28\t28\t830000\t1\t1010\n29\t29\t915000\t1\t1010\n30\t30\t1000000\t1\t1010\n31\t31\t1200000\t1\t1010\n32\t32\t1400000\t1\t1010\n33\t33\t1600000\t1\t1010\n34\t34\t1800000\t1\t1010\n35\t35\t2000000\t1\t1010\n36\t36\t2200000\t1\t1010\n37\t37\t2400000\t1\t1010\n38\t38\t2600000\t1\t1010\n39\t39\t2800000\t1\t1010\n40\t40\t3000000\t1\t1010\n41\t41\t3200000\t1\t1010\n42\t42\t3400000\t1\t1010\n43\t43\t3600000\t1\t1010\n44\t44\t3800000\t1\t1010\n45\t45\t4000000\t1\t1010\n46\t46\t4200000\t1\t1010\n47\t47\t4400000\t1\t1010\n48\t48\t4800000\t1\t1010\n49\t49\t5500000\t1\t1010\n50\t50\t6500000\t1\t1010\n51\t51\t7500000\t1\t1010\n52\t52\t9000000\t1\t1010\n53\t53\t12000000\t1\t1010\n54\t54\t15000000\t1\t1010\n55\t55\t18000000\t1\t1010\n56\t56\t21000000\t1\t1010\n57\t57\t24000000\t1\t1010\n58\t58\t27000000\t1\t1010\n59\t59\t30000000\t1\t1010\n60\t60\t34000000\t1\t1010\n61\t61\t38000000\t1\t1010\n62\t62\t42000000\t1\t1010\n63\t63\t46000000\t1\t1010\n64\t64\t50000000\t1\t1010\n65\t65\t54000000\t1\t1010\n66\t66\t58000000\t1\t1010\n67\t67\t62000000\t1\t1010\n68\t68\t66000000\t1\t1010\n69\t69\t70000000\t1\t1010\n70\t70\t75000000\t1\t1010\n71\t71\t80000000\t1\t1010\n72\t72\t85000000\t1\t1010\n73\t73\t100000000\t1\t1010\n74\t74\t115000000\t1\t1010\n75\t75\t130000000\t1\t1010\n76\t76\t145000000\t1\t1010\n77\t77\t160000000\t1\t1010\n78\t78\t175000000\t1\t1010\n79\t79\t195000000\t1\t1010\n80\t80\t215000000\t1\t1010\n81\t81\t250000000\t1\t1010\n82\t82\t280000000\t1\t1010\n83\t83\t310000000\t1\t1010\n84\t84\t350000000\t1\t1010\n85\t85\t390000000\t1\t1010\n86\t86\t440000000\t1\t1010\n87\t87\t624000000\t1\t1010\n88\t88\t780000000\t1\t1010\n89\t89\t952000000\t1\t1010\n90\t90\t1064000000\t1\t1010\n91\t91\t1848000000\t1\t1010\n92\t92\t1900000000\t1\t1010\n93\t93\t2088000000\t1\t1010\n94\t94\t2208000000\t1\t1010\n95\t95\t2328000000\t1\t1010\n96\t96\t2448000000\t1\t1010\n97\t97\t2568000000\t1\t1010\n98\t98\t2750000000\t1\t1010\n99\t99\t2900000000\t1\t1010\n100\t100\t3300000000\t1\t1010\n101\t101\t3700000000\t1\t1010\n102\t102\t4100000000\t1\t1010\n103\t103\t4500000000\t1\t1010\n104\t104\t4900000000\t1\t1010\n105\t105\t5300000000\t1\t1010\n106\t1\t1\t2\t1002\n107\t2\t2\t2\t1003\n108\t3\t3\t2\t1004\n109\t4\t4\t2\t1005\n110\t5\t5\t2\t1006\n111\t6\t6\t2\t1007\n112\t7\t7\t2\t1008\n113\t8\t8\t2\t1009\n114\t9\t9\t2\t1010\n115\t10\t10\t2\t1010\n116\t11\t11\t2\t1010\n117\t12\t12\t2\t1010\n118\t13\t13\t2\t1010\n119\t14\t14\t2\t1010\n120\t15\t15\t2\t1010\n121\t16\t16\t2\t1010\n122\t17\t17\t2\t1010\n123\t18\t18\t2\t1010\n124\t19\t19\t2\t1010\n125\t20\t20\t2\t1010\n126\t21\t21\t2\t1010\n127\t22\t22\t2\t1010\n128\t23\t23\t2\t1010\n129\t24\t24\t2\t1010\n130\t25\t25\t2\t1010\n131\t26\t26\t2\t1010\n132\t27\t27\t2\t1010\n133\t28\t28\t2\t1010\n134\t29\t29\t2\t1010\n135\t30\t30\t2\t1010\n136\t31\t31\t2\t1010\n137\t32\t32\t2\t1010\n138\t33\t33\t2\t1010\n139\t34\t34\t2\t1010\n140\t35\t35\t2\t1010\n141\t36\t36\t2\t1010\n142\t37\t37\t2\t1010\n143\t38\t38\t2\t1010\n144\t39\t39\t2\t1010\n145\t40\t40\t2\t1010\n146\t41\t41\t2\t1010\n147\t42\t42\t2\t1010\n148\t43\t43\t2\t1010\n149\t44\t44\t2\t1010\n150\t45\t45\t2\t1010\n151\t46\t46\t2\t1010\n152\t47\t47\t2\t1010\n153\t48\t48\t2\t1010\n154\t49\t49\t2\t1010\n155\t50\t50\t2\t1010\n156\t51\t51\t2\t1010\n157\t52\t52\t2\t1010\n158\t53\t53\t2\t1010\n159\t54\t54\t2\t1010\n160\t55\t55\t2\t1010\n161\t56\t56\t2\t1010\n162\t57\t57\t2\t1010\n163\t58\t58\t2\t1010\n164\t59\t59\t2\t1010\n165\t60\t60\t2\t1010\n166\t61\t61\t2\t1010\n167\t62\t62\t2\t1010\n168\t63\t63\t2\t1010\n169\t64\t64\t2\t1010\n170\t65\t65\t2\t1010\n171\t66\t66\t2\t1010\n172\t67\t67\t2\t1010\n173\t68\t68\t2\t1010\n174\t69\t69\t2\t1010\n175\t70\t70\t2\t1010\n176\t71\t71\t2\t1010\n177\t72\t72\t2\t1010\n178\t73\t73\t2\t1010\n179\t74\t74\t2\t1010\n180\t75\t75\t2\t1010\n181\t76\t76\t2\t1010\n182\t77\t77\t2\t1010\n183\t78\t78\t2\t1010\n184\t79\t79\t2\t1010\n185\t80\t80\t2\t1010\n186\t81\t81\t2\t1010\n187\t82\t82\t2\t1010\n188\t83\t83\t2\t1010\n189\t84\t84\t2\t1010\n190\t85\t85\t2\t1010\n191\t86\t86\t2\t1010\n192\t87\t87\t2\t1010\n193\t88\t88\t2\t1010\n194\t89\t89\t2\t1010\n195\t90\t90\t2\t1010\n196\t91\t91\t2\t1010\n197\t92\t92\t2\t1010\n198\t93\t93\t2\t1010\n199\t94\t94\t2\t1010\n200\t95\t95\t2\t1010\n201\t96\t96\t2\t1010\n202\t97\t97\t2\t1010\n203\t98\t98\t2\t1010\n204\t99\t99\t2\t1010\n205\t100\t100\t2\t1010\n206\t101\t101\t2\t1010\n207\t102\t102\t2\t1010\n208\t103\t103\t2\t1010\n209\t104\t104\t2\t1010\n210\t105\t105\t2\t1010";
var tab = TableFile.LoadFromString(fileContent);
var aa = tab;
}

#endregion
}
}
}
35 changes: 30 additions & 5 deletions TableML/TableMLCompilerConsole/TableMLCompilerConsole.csproj
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{D3A252A3-78B0-4651-AD16-C6B6A30F7326}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>TableCompilerConsole</RootNamespace>
<AssemblyName>TableML</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<AssemblyName>TableMLConsole</AssemblyName>
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -18,19 +19,42 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ExternalConsole>true</ExternalConsole>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ExternalConsole>true</ExternalConsole>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="CommandLine">
<Reference Include="CommandLine, Version=1.9.71.2, Culture=neutral, PublicKeyToken=de6f01bd326f8c32, processorArchitecture=MSIL">
<HintPath>..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NPOI, Version=2.3.0.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
<HintPath>..\packages\NPOI.2.3.0\lib\net40\NPOI.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NPOI.OOXML, Version=2.3.0.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
<HintPath>..\packages\NPOI.2.3.0\lib\net40\NPOI.OOXML.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NPOI.OpenXml4Net, Version=2.3.0.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
<HintPath>..\packages\NPOI.2.3.0\lib\net40\NPOI.OpenXml4Net.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NPOI.OpenXmlFormats, Version=2.3.0.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
<HintPath>..\packages\NPOI.2.3.0\lib\net40\NPOI.OpenXmlFormats.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
@@ -47,6 +71,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
3 changes: 3 additions & 0 deletions TableML/TableMLCompilerConsole/app.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>
2 changes: 2 additions & 0 deletions TableML/TableMLCompilerConsole/packages.config
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="CommandLineParser" version="1.9.71" targetFramework="net45" />
<package id="NPOI" version="2.3.0" targetFramework="net45" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net45" />
</packages>
51 changes: 51 additions & 0 deletions TableML/TableMLGUI/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<!--
注意:本配置中的路径都是指相对于此Exe(tableGUI.exe)的路径,并不是绝对路径
-->

<!--是否使用绝对路径; 0:所有路径是相对于此exe的; 1:所有路径都是绝对的(c:\xxx\abc.xlsx);-->
<add key="UseAbsolutePath" value="0" />
<!--excel源文件路径-->
<add key="srcExcelPath" value=".\..\SettingSource\" />
<!--是否把结果插入到sqlite ,1启用 0禁用-->
<add key="EnableToSqlite" value="1" />
<!--是否需要生成CSharp代码 ,1启用 0禁用-->
<add key="EnableGenCSharp" value="1" />
<add key="EnableGenLua" value="1" />
<!--是否需要生成tsv文件 ,1启用 0禁用 ,注意:sql依赖于tsv-->
<add key="EnableGenTsv" value="1" />

<!--编译后的文件格式-->
<add key="TmlExtensions" value=".tsv" />
<!--excel编译后的 sql脚本 保存路径-->
<add key="ExportSqlScriptsPath" value=".\..\sql\" />
<!--excel编译后的sql database(data.db)保存路径-->
<add key="ExportDBPath" value=".\..\sql\data.db" />
<!--excel编译后的tsv保存路径-->
<add key="ExportTsvPath" value=".\..\Setting\" />
<!--excel生成的C#代码保存路径-->
<add key="ExportCSharpPath" value=".\..\..\Assets\Code\AppSettings\" />
<!--excel生成的lua代码保存路径-->
<add key="ExportLuaPath" value=".\..\Lua\configs\" />

<!--文件拷贝功能 start-->
<!--客户端读表代码路径-->
<add key="dstClientCodePath" value=".\..\..\Assets\Code\AppSettings\" />
<!--客户端项目tml路径-->
<add key="dstClientTmlPath" value=".\..\Setting\" />
<!--文件拷贝功能 end-->
<!--帮助文档页面-->
<add key="HelpUrl" value="https://github.com/zhaoqingqing/TableML/blob/custom/quick_start.md" />
</appSettings>
<system.data>
<DbProviderFactories>
<remove invariant="System.Data.SQLite" />
<add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
</DbProviderFactories>
</system.data>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
78 changes: 78 additions & 0 deletions TableML/TableMLGUI/AppConfigHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using System;
using System.Windows.Forms;
using System.Xml;

namespace TableMLGUI
{
/// <summary>
/// 提供像xml一样方法修改App.config,因为通过ConfigurationManager修改config文件会丢失注释
/// by qingqing.zhao (569032731@qq.com)
/// </summary>
public static class AppConfigHelper
{
//NOTE:使用系统提供的API会重新生成app.config,导致里面的注释丢失,所以使用AppConfigHelper
/*var newKeyValue = box.Checked ? "1" : "0";
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.AppSettings.Settings["UseSqlite"].Value = newKeyValue;
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");*/
public static void SetValue(string key,string value)
{
XmlDocument doc = new XmlDocument();
doc.Load(GetAppConfigPath());
XmlNode node = doc.SelectSingleNode(@"//appSettings");

var select = node.SelectSingleNode($@"//add[@key='{key}']");
if (select == null)
{
ConsoleHelper.Error($"not find key:{key}");
return;
}
XmlElement ele = (XmlElement)select;
ele.SetAttribute("value", value);
doc.Save(GetAppConfigPath());
}

public static string GetAppConfigPath()
{
//TODO 区分是在vs中运行的,还是独立exe运行环境
if (false)
{
int intPos = Application.StartupPath.Trim().IndexOf("bin") - 1;
string strDirectoryPath = System.IO.Path.Combine(Application.StartupPath.Substring(0, intPos), "App.config");

return strDirectoryPath;
}
else
{
return System.Windows.Forms.Application.ExecutablePath + ".config";
}
}

public static string GetValue(string appKey)
{
XmlDocument xDoc = new XmlDocument();
try
{
xDoc.Load(GetAppConfigPath());
XmlNode xNode;
XmlElement xElem;
xNode = xDoc.SelectSingleNode("//appSettings");    //检查你的app.config 文件中是否包含xml根节点:<appSetting> </appSetting>
xElem = (XmlElement)xNode.SelectSingleNode("//add[@key='" + appKey + "']");
if (xElem != null)
{
return xElem.GetAttribute("value");
}
else
{
ConsoleHelper.Error($"not find key:{appKey}");
return "";
}
}
catch (Exception)
{
return "";
}
}
}
}
28 changes: 28 additions & 0 deletions TableML/TableMLGUI/ConfigData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TableMLGUI
{
/// <summary>
/// 用来存放配置数据
/// </summary>
public static class ConfigData
{
/// <summary>
/// 简单三行格式文件的格式
/// </summary>
public const string SimpleFileEx = ".tsv";
/// <summary>
///可以插入到sqlite中的格式
/// </summary>
public static string[] CanToSqlEx = new string[] { ".tsv","*.tml" };

public static string StartPath
{
get { return Application.StartupPath; }
}
}
}
267 changes: 267 additions & 0 deletions TableML/TableMLGUI/ExcelHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using NPOI.SS.UserModel;

namespace TableMLGUI
{
public enum CheckType
{
/// <summary>
/// 重复
/// </summary>
Repet,
/// <summary>
/// 空白
/// </summary>
Empty,
/// <summary>
/// 是否有关键词
/// </summary>
HasKeyWords,
}
public class ExcelHelper
{
private string keywordFile { get { return Application.StartupPath + "\\csharpkeywords.txt"; } }

public static void UpdateAllTableSyntax()
{
var findPath = System.Environment.CurrentDirectory + ".\\..\\SettingSource";
//var findPath = @"e:\3dsn\plan\005ConfigTable\SettingSource\";
var files = Directory.GetFiles(findPath, "*.xls", SearchOption.AllDirectories);
Console.WriteLine("开始更新{0}张Excel表", files.Length);
var count = 0;
foreach (string file in files)
{
var update = ToCSharpSyntax(file);
if (update) count += 1;
}
Console.WriteLine("更新Excel表完成。");
MessageBox.Show(string.Format("共整理{0}张表的前端字段为C#类型", count), "整理完成", MessageBoxButtons.OK, MessageBoxIcon.Information);
}

/// <summary>
/// 替换成C#的数据类型
/// </summary>
/// <param name="filePath"></param>
/// <returns>文件是否有改变</returns>
public static bool ToCSharpSyntax(string filePath)
{
bool fileChange = false;
IWorkbook Workbook;
ISheet Worksheet;
using (var file = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) // no isolation
{
try
{
Workbook = WorkbookFactory.Create(file);
}
catch (Exception e)
{
throw new Exception(string.Format("无法打开Excel: {0}, 可能原因:正在打开?或是Office2007格式(尝试另存为)? {1}", filePath, e.Message));
}
}
Worksheet = Workbook.GetSheetAt(0);
//检查行数是否超出索引,NOTE 如果有预留行数,还要减去
if (Worksheet.LastRowNum - 1 < 4)
{
ConsoleHelper.Error("{0}行数不足4行",Path.GetFileName(filePath));
return false;
}
List<ICell> cells = Worksheet.GetRow(4).Cells;
foreach (ICell cell in cells)
{
if (cell.StringCellValue == "num")
{
cell.SetCellValue("int");
fileChange = true;
}

if (cell.StringCellValue == "str")
{
cell.SetCellValue("string");
fileChange = true;
}
if (cell.StringCellValue.StartsWith("arr"))
{
cell.SetCellValue("string");
fileChange = true;
}
if (cell.StringCellValue.StartsWith("ssg"))
{
cell.SetCellValue("string");
fileChange = true;
}
}
//文件没有改变,不保存
if (!fileChange) return false;
using (var memStream = new MemoryStream())
{
Workbook.Write(memStream);
memStream.Flush();
memStream.Position = 0;

using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
var data = memStream.ToArray();
fileStream.Write(data, 0, data.Length);
fileStream.Flush();
}
}
Console.WriteLine("更新表数据类型:{0}", filePath);
return true;
}

/// <summary>
///
/// </summary>
/// <param name="filePath"></param>
/// <param name="type"></param>
/// <param name="rowIdx">读取的行,从0开始</param>
/// <returns></returns>
public static bool CheckExcel(string filePath, CheckType type, int rowIdx = 5)
{
IWorkbook Workbook;
ISheet Worksheet;
using (var file = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) // no isolation
{
try
{
Workbook = WorkbookFactory.Create(file);
}
catch (Exception e)
{
throw new Exception(string.Format("无法打开Excel: {0}, 可能原因:正在打开?或是Office2007格式(尝试另存为)? {1}", filePath,
e.Message));
}
}

Worksheet = Workbook.GetSheetAt(0);
List<ICell> cells = Worksheet.GetRow(rowIdx).Cells;
List<string> cellValues = new List<string>();
Dictionary<string, string> dict = new Dictionary<string, string>();
StringBuilder repet = new StringBuilder();
StringBuilder empty = new StringBuilder();
StringBuilder kwSb = new StringBuilder();
string[] keywords = new string[] { };
if (type == CheckType.HasKeyWords)
{
var keywordFile = Application.StartupPath + "/csharpkeywords.txt";
if (File.Exists(keywordFile) == false)
{
MessageBox.Show(keywordFile, "文件不存在", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
var fileContent = File.ReadAllText(keywordFile);
fileContent = fileContent.Replace("\r\n", "\t");
fileContent = fileContent.Replace("\n", "\t");
keywords = fileContent.Split('\t');
Console.WriteLine("C# 关键词数量:{0}\r\n{1}",keywords.Length, fileContent);
}
foreach (ICell cell in cells)
{
if (keywords.Contains(cell.StringCellValue))
{
kwSb.AppendLine(string.Format("row:{0} column:{1} keywords:{2}\t", cell.RowIndex + 1, cell.ColumnIndex + 1, cell.StringCellValue));
}
if (dict.ContainsKey(cell.StringCellValue) == false)
{
dict.Add(cell.StringCellValue, cell.StringCellValue);
}
else
{
repet.AppendFormat("{0}\t", cell.StringCellValue);
}
if (string.IsNullOrEmpty(cell.StringCellValue))
{
empty.AppendFormat("row:{0} column:{1} \t", cell.RowIndex + 1, cell.ColumnIndex + 1);
}
}
if (type == CheckType.HasKeyWords)
{
if (kwSb.Length >= 1)
{
Console.WriteLine("含有关键词的字段:{0}", kwSb.ToString());
MessageBox.Show(kwSb.ToString(), "含有关键词的字段",MessageBoxButtons.OK,MessageBoxIcon.Warning);
}
else
{
MessageBox.Show("没有C#关键词", "关键词检测");
}

return kwSb.Length < 1;
}

switch (type)
{
case CheckType.Repet:
if (repet.Length >= 1)
{
Console.WriteLine("重复字段{0}", repet.ToString());
MessageBox.Show(repet.ToString(), "重复字段");
}
else
{
MessageBox.Show("没有重复字段", "重复字段");
}
return repet.Length == 0;
case CheckType.Empty:
if (empty.Length >= 1)
{
Console.WriteLine("空白字段{0}", empty.ToString());
MessageBox.Show(empty.ToString(), "空白字段");
}
else
{
MessageBox.Show("没有空白字段", "空白字段");
}
return empty.Length == 0;
default:
throw new ArgumentOutOfRangeException(nameof(type), type, null);
}

}

public static void CheckNameRepet(string[] filePaths)
{
int count = 0;
foreach (string filePath in filePaths)
{
if (CheckExcel(filePath, CheckType.Repet))
{
count++;
}
}
Console.WriteLine("check name repet:{0}",count);
}

/// <summary>
/// 检查前端字段名是否重复
/// </summary>
public static void CheckNameRepet(List<string> filePaths)
{
CheckNameRepet(filePaths.ToArray());
}

public static void CheckNameEmpty(string[] filePaths)
{
foreach (string filePath in filePaths)
{
CheckExcel(filePath, CheckType.Empty);
}
}

public static void CheckHasKeyWords(string[] filePaths)
{
foreach (string filePath in filePaths)
{
CheckExcel(filePath, CheckType.HasKeyWords);
}


}
}
}
237 changes: 237 additions & 0 deletions TableML/TableMLGUI/FileHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Security.AccessControl;

public partial class FileHelper
{
/// <summary>
/// 递归获取所有的目录
/// </summary>
/// <param name="strPath"></param>
/// <param name="lstDirect"></param>
public static void GetAllDirectorys(string strPath, ref List<string> lstDirect)
{
if (Directory.Exists(strPath) == false)
{
Console.WriteLine("请检查,路径不存在:{0}", strPath);
return;
}
DirectoryInfo diFliles = new DirectoryInfo(strPath);
DirectoryInfo[] directories = diFliles.GetDirectories();
var max = directories.Length;
for (int dirIdx = 0; dirIdx < max; dirIdx++)
{
try
{
var dir = directories[dirIdx];
//dir.FullName是某个子目录的绝对地址,把它记录起来
lstDirect.Add(dir.FullName);
GetAllDirectorys(dir.FullName, ref lstDirect);
}
catch
{
continue;
}
}
}

/// <summary>
/// 遍历当前目录及子目录,获取所有文件
/// </summary>
/// <param name="strPath">文件路径</param>
/// <returns>所有文件</returns>
public static IList<FileInfo> GetAllFiles(string strPath,string searchPattern = "*")
{
List<FileInfo> lstFiles = new List<FileInfo>();
List<string> lstDirect = new List<string>();
lstDirect.Add(strPath);
DirectoryInfo diFliles = null;
GetAllDirectorys(strPath, ref lstDirect);

var max = lstDirect.Count;
for (int idx = 0; idx < max; idx++)
{
try
{
diFliles = new DirectoryInfo(lstDirect[idx]);
lstFiles.AddRange(diFliles.GetFiles(searchPattern));
}
catch
{
continue;
}
}
return lstFiles;
}

/// <summary>
/// 目录复制
/// </summary>
/// <param name="sourceDir">源目录</param>
/// <param name="targetDir">目标目录</param>
public static void CopyFolder(string sourceDir, string targetDir)
{
DirectoryInfo targetDirInfo;
if (!Directory.Exists(targetDir))
{
targetDirInfo = Directory.CreateDirectory(targetDir);
Console.WriteLine("目标文件夹不存在,已创建");
}
else
{
targetDirInfo = new DirectoryInfo(targetDir);
}

DirectoryInfo sourceDirInfo = new DirectoryInfo(sourceDir);
if (sourceDirInfo.Exists == false)
{
Console.WriteLine("error:源目录不存在!");
return;
}

if (targetDirInfo.FullName.StartsWith(sourceDirInfo.FullName, StringComparison.CurrentCultureIgnoreCase))
{
Console.WriteLine("error:父目录不能拷贝到子目录!");
return;
}

FileInfo[] files = sourceDirInfo.GetFiles();
var fileMax = files.Length;
for (int fileIdx = 0; fileIdx < fileMax; fileIdx++)
{
files[fileIdx].CopyTo(Path.Combine(targetDir, files[fileIdx].Name), true);
}

DirectoryInfo[] direcInfoArr = sourceDirInfo.GetDirectories();
var dirMax = direcInfoArr.Length;
for (int dirIdx = 0; dirIdx < dirMax; dirIdx++)
{
CopyFolder(Path.Combine(sourceDir, direcInfoArr[dirIdx].Name), Path.Combine(targetDir, direcInfoArr[dirIdx].Name));
}
}

public static void CopyFile(string sourceFile, string targetFile, bool overwrite = true)
{
if (File.Exists(sourceFile) == false)
{
Console.WriteLine("{0}找不到", sourceFile);
return;
}
DirectoryInfo targetDir = new DirectoryInfo(targetFile);
if (targetDir.Parent != null && targetDir.Exists == false)
{
Directory.CreateDirectory(targetDir.Parent.FullName);
}
File.Copy(sourceFile, targetFile, overwrite);

}

/// <summary>
/// 给文件添加完全控制权限
/// </summary>
/// <param name="fileName"></param>
public static void AddTopPermissionToFile(string fileName)
{
//给文件添加"Everyone,Users"用户组的完全控制权限
FileInfo fileInfo = new FileInfo(fileName);
System.Security.AccessControl.FileSecurity fileSecurity = fileInfo.GetAccessControl();
fileSecurity.AddAccessRule(new FileSystemAccessRule("Everyone", FileSystemRights.FullControl, AccessControlType.Allow));
fileSecurity.AddAccessRule(new FileSystemAccessRule("Users", FileSystemRights.FullControl, AccessControlType.Allow));
fileInfo.SetAccessControl(fileSecurity);
}

/// <summary>
/// 给文件夹添加完全控制权限
/// </summary>
/// <param name="directoryPath"></param>
public static void AddTopPermissionToDirectory(string directoryPath)
{
if (string.IsNullOrEmpty(directoryPath)) return;
//给文件所在目录添加"Everyone,Users"用户组的完全控制权限
DirectoryInfo directoryInfo = new DirectoryInfo(Path.GetDirectoryName(directoryPath));
if (directoryInfo == null) return;
System.Security.AccessControl.DirectorySecurity dirSecurity = directoryInfo.GetAccessControl();
dirSecurity.AddAccessRule(new FileSystemAccessRule("Everyone", FileSystemRights.FullControl, AccessControlType.Allow));
dirSecurity.AddAccessRule(new FileSystemAccessRule("Users", FileSystemRights.FullControl, AccessControlType.Allow));
directoryInfo.SetAccessControl(dirSecurity);
}

/// <summary>
/// 设置文件和文件夹的属性为正常
/// </summary>
/// <param name="fileName"></param>
public static void SetPermissionToNormal(string fileName)
{
if (string.IsNullOrEmpty(fileName) || File.Exists(fileName) == false)
{
Console.WriteLine("文件不存在");
return;
}

FileInfo fileInfo = new FileInfo(fileName);
DirectoryInfo directoryInfo = fileInfo.Directory;
if (directoryInfo != null)
{
directoryInfo.Attributes = FileAttributes.Normal;
}
fileInfo.Attributes = FileAttributes.Normal;
}

/// <summary>
/// 文件大小格式化转换
/// </summary>
/// <param name="pContentLength"></param>
/// <returns></returns>
public static string FormatSizeType(float pContentLength)
{
string type = "";
float size;
if (pContentLength >= 1073741824)
{
size = pContentLength / 1073741824.00F;
type = "GB";
}
else if (pContentLength >= 1048576)
{
size = pContentLength / 1048576.00F;
type = "MB";
}
else
{
size = pContentLength / 1024.00F;
type = "KB";
}
return size.ToString("0.0") + type;
}

public static void OpenFolder(string path, bool createNew = false)
{
if (Directory.Exists(path) == false && createNew)
{
Directory.CreateDirectory(path);
}

if (Directory.Exists(path))
{
Process.Start(path);
}
else
{
Console.WriteLine("[error] {0} not exist", path);
}
}

/// <summary>
/// 检查目录,如果不存在则创建
/// </summary>
/// <param name="path"></param>
public static void CheckFolder(string path)
{
if (Directory.Exists(path) == false)
{
Directory.CreateDirectory(path);
}
}
}
59 changes: 59 additions & 0 deletions TableML/TableMLGUI/HelpForm.Designer.cs
35 changes: 35 additions & 0 deletions TableML/TableMLGUI/HelpForm.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.Configuration;
using System.Drawing;
using System.Windows.Forms;

namespace TableMLGUI
{
/// <summary>
/// 如果加载慢,可以试试:https://stackoverflow.com/questions/3086063/winform-webbrowser-control-slow-to-load-best-method-for-pre-loading
/// </summary>
public partial class HelpForm : Form
{
public HelpForm()
{
InitializeComponent();
DoStart();
}

public void DoStart()
{
string helpUrl = ConfigurationManager.AppSettings.Get("HelpUrl").Trim();
webBrowser.Navigated += WebBrowser_Navigated;
webBrowser.ScriptErrorsSuppressed = true;
webBrowser.Navigate(helpUrl);
// ConsoleHelper.WriteLine("nav start");
}

private void WebBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
// ConsoleHelper.WriteLine("nav end");
//此方法不能滚动到指定位置
// webBrowser.AutoScrollOffset = new Point(0, 300);
}
}
}
120 changes: 120 additions & 0 deletions TableML/TableMLGUI/HelpForm.resx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
51 changes: 51 additions & 0 deletions TableML/TableMLGUI/LuaHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using TableML.Compiler;

/// <summary>
/// Author:qingqing.zhao (569032731@qq.com)
/// Date:2020/11/5 16:33
/// Desc:配置表转成lua文件
/// 转成lua配置文件请查看Compiler.DoCompilerExcelReader
/// </summary>
public class LuaHelper
{
/// <summary>
/// 仅仅生成lua字段,不包含具体的数据部分,用于sqlite中的代码提示
/// </summary>
public static void GenLuaFile(TableCompileResult compileResult, string exportPath)
{
if (compileResult.FieldsInternal != null)
{
StringBuilder builder = new StringBuilder();
StringBuilder typeBuilder = new StringBuilder();
var fileName = Path.GetFileNameWithoutExtension(exportPath);
typeBuilder.AppendLine("---@class "+fileName);
builder.AppendLine("return {");
var count = compileResult.FieldsInternal.Count;
var end = count - 1;
for (int i = 0; i < count; i++)
{
var t = compileResult.FieldsInternal[i];
builder.AppendLine("\t" + t.Name + (i == end ? "" : ","));
typeBuilder.AppendLine($"---@field public {t.Name} {t.Type}");
}

builder.AppendLine("}");
if (File.Exists(exportPath))
{
File.Delete(exportPath);
}

var dirName = Path.GetDirectoryName(exportPath);
if (Directory.Exists(dirName) == false)
{
Directory.CreateDirectory(dirName);
}

File.WriteAllText(exportPath, typeBuilder.ToString() + builder.ToString());
}
}
}
Loading