diff --git a/README.md b/README.md
index d41c038..e145427 100644
--- a/README.md
+++ b/README.md
@@ -112,7 +112,7 @@ luban支持在excel中解析任意复杂的数据结构,哪怕复杂如技能
支持 bool,int,float,string,text,datetime,vector2,vector3,vector4 等等类型,它们的填写跟常规认知一致。
-|##| x1 | x3 | x4 | x5 | x6 | x7 | s1 | s2&sep=# | v2 | v3 | v4 | t1 |
+|##var| x1 | x3 | x4 | x5 | x6 | x7 | s1 | s2&sep=# | v2 | v3 | v4 | t1 |
| -| - | - | - | - | - | - | - | - | - | - | - | - |
|##type|bool|short|int|long|float|double|string|text |vector2|vector3|vector4|datetime|
|##|desc1|id|desc4|desc5|desc6|desc7|desc1|desc2 |desc2|desc3|desc4|desc1|
@@ -126,7 +126,7 @@ array与list类型都能表示列表,它们区别在于array生成的代码为
- | ## |
+ ##var |
id |
arr1 |
arr2 |
@@ -196,7 +196,7 @@ array与list类型都能表示列表,它们区别在于array生成的代码为
或者在 \_\_enums\_\_.xlsx 中 定义
-| ## | full_name | flags | unique | comment | tags | *items |
+| ##var | full_name | flags | unique | comment | tags | *items |
| ##var | | | | | | name | alias | value | comment | tags |
| ItemQuality | false | true | | | WHITE | 白 | 0 | | |
| | | | | | GREEN | 绿 | 1 | | |
@@ -206,7 +206,7 @@ array与list类型都能表示列表,它们区别在于array生成的代码为
数据表如下
-| ##|id| quality| quality2 |
+|##var|id| quality| quality2 |
| -| - | - | - |
|##type|int|ItemQuality|ItemQuality|
| | 1| 白 | RED |
@@ -233,7 +233,7 @@ array与list类型都能表示列表,它们区别在于array生成的代码为
或者在 \_\_beans__.xlsx 里定义
-| ## | full_name | sep | comment | fields |
+| ##var | full_name | sep | comment | fields |
| ##var | | | | name | type | group | comment | tags |
| Reward | | | item_id | int | | 道具id | |
| | | | count | int | | 个数 | |
@@ -244,7 +244,7 @@ array与list类型都能表示列表,它们区别在于array生成的代码为
-| ## |
+##var |
id |
reward |
@@ -296,7 +296,7 @@ xml中定义如下
-| ## |
+##var |
id |
rewards1 |
rewards2&sep=, |
@@ -339,7 +339,7 @@ xml中定义如下
- | ## |
+ ##var |
id |
name |
rewards |
@@ -392,7 +392,7 @@ xml中定义如下
-| ## |
+##var |
id |
name |
*stage2 |
@@ -445,7 +445,7 @@ xml中定义如下
示例数据表
-|##|x|y|z| num|
+|##var|x|y|z| num|
|-|-|-|-|-|
|##type|int|long|string|int|
||1|1|aaa|123|
@@ -466,7 +466,7 @@ xml中定义如下
示例数据表
-|##|key1|key2|key3| num|
+|##var|key1|key2|key3| num|
|-|-|-|-|-|
|##type|int|long|string|int|
||1|1|aaa|123|
@@ -487,7 +487,7 @@ xml中定义如下
示例数据表
-|##|key1|key2|key3| num|
+|##var|key1|key2|key3| num|
|-|-|-|-|-|
|##type|int|long|string|int|
||1|2|aaa|123|
@@ -500,7 +500,7 @@ xml中定义如下
有一些配置全局只有一份,比如 公会模块的开启等级,背包初始大小,背包上限。此时使用单例表来配置这些数据比较合适。
-| ##| guld_open_level | bag_init_capacity | bag_max_capacity | newbie_tasks |
+|##var| guld_open_level | bag_init_capacity | bag_max_capacity | newbie_tasks |
| - |- | - | - | - |
| ##type | int | int | int | list,int|
| ## |desc1 | desc 2 | desc 3 | desc 4 |
@@ -512,7 +512,7 @@ xml中定义如下
-| ##column |
+##var&column |
##type |
## |
|
@@ -545,7 +545,7 @@ xml中定义如下
- | ## |
+ ##var |
id |
item_id |
items |
@@ -592,7 +592,7 @@ xml中定义如下
对于这些字段添加属性 path=unity或者path=ue或path=normal;xxxx。
-| ## | id | icon |
+|##var| id | icon |
| - | - | - |
| ##type| int | string&path=unity|
| ##|id | icon desc |
@@ -610,7 +610,7 @@ xml中定义如下
开发期经常会制作一些仅供开发使用的配置,比如测试道具,比如自动化测试使用的配置,希望在正式发布时不导出这些数据。
-| ## | id | name | |
+|##var| id | name | |
| - | - | - | - |
| ##type | int | string | |
| ## | id | desc1| 注释 |
@@ -632,7 +632,7 @@ xml中定义如下
- | ## |
+ ##var |
id |
name |
stage |
@@ -681,7 +681,7 @@ xml中定义如下
- | ## |
+ ##var |
id |
name |
stages |
@@ -741,7 +741,7 @@ xml中定义如下
- list,bean 的水平展开多级子标题
-| ## | id | name | items |
+| ##var | id | name | items |
| ##type | int | string | list,Item |
@@ -770,7 +770,7 @@ xml中定义如下
-| ## | id | lans |
+| ##var | id | lans |
| ##type | int | map,string,string |
| ##var | | ch-zn | en | jp | fr |
| 1 | 苹果 | apple | aaa | aaa |
@@ -782,7 +782,7 @@ xml中定义如下
配置数据中经常有空值的语义需求,实际项目中往往混杂地使用0或-1表达空值,既不自然清晰也不统一。luban借鉴了c#中的可空变量的概念,特地提供可空数据支持。所有原生数据类型,以及enum、bean、和多态bean类型都有相应的可空数据类型。定义方式为 <类型名>?,与c#里的Nullable类型定义方式相同。例如 bool?,int?,long?,double?, EColor?, DemoType?
-|##|id|x1|x2|x3|x4|x5|
+|##var|id|x1|x2|x3|x4|x5|
| - |-|-|-|-|-|-|
|##type|int|bool?|int?|float?|datetime?|QualityType?|
|##|id|desc1|desc2|desc3|desc4|desc5|
@@ -821,7 +821,7 @@ xml中定义如下
- | ## |
+ ##var |
id |
shapes&sep=, |
@@ -859,7 +859,7 @@ xml中定义如下
如示例,id=2的记录,x1与x2皆为空,x1=0,x2=-1。
-|##|id | x1 | x2&default=-1|
+|##var|id | x1 | x2&default=-1|
| - | - | - | - |
|##type| int | int | int |
|##|id|desc1|desc2|
@@ -878,7 +878,7 @@ xml中定义如下
```
-|##|id| item_id |
+|##var|id| item_id |
|-| - | - |
|##type|int| int&convert=EFunctionItemId|
|##|id| desc|
diff --git a/src/Luban.Job.Cfg/Source/DataSources/Excel/SheetLoadUtil.cs b/src/Luban.Job.Cfg/Source/DataSources/Excel/SheetLoadUtil.cs
index 61432bf..6ff4de2 100644
--- a/src/Luban.Job.Cfg/Source/DataSources/Excel/SheetLoadUtil.cs
+++ b/src/Luban.Job.Cfg/Source/DataSources/Excel/SheetLoadUtil.cs
@@ -135,9 +135,13 @@ namespace Luban.Job.Cfg.DataSources.Excel
ToIndex = cells.Select(r => r.Count).Max() - 1
};
+ if (!TryFindTopTitle(cells, out var topTitleRowIndex))
+ {
+ throw new Exception($"没有定义任何有效 标题行");
+ }
//titleRowNum = GetTitleRowNum(mergeCells, orientRow);
- ParseSubTitles(rootTitle, cells, mergeCells, orientRow, 1);
+ ParseSubTitles(rootTitle, cells, mergeCells, orientRow, topTitleRowIndex + 1);
rootTitle.Init();
@@ -148,6 +152,37 @@ namespace Luban.Job.Cfg.DataSources.Excel
return rootTitle;
}
+ private static bool TryFindTopTitle(List> cells, out int rowIndex)
+ {
+ for (int i = 0; i < cells.Count; i++)
+ {
+ var row = cells[i];
+ if (row.Count == 0)
+ {
+ break;
+ }
+ string rowTag = row[0].Value?.ToString()?.ToLower() ?? "";
+ if (!rowTag.StartsWith("##"))
+ {
+ break;
+ }
+ var tags = rowTag.Substring(2).Split('&').Select(s => s.Trim()).Where(s => !string.IsNullOrEmpty(s)).ToList();
+ if (tags.Contains("field") || tags.Contains("var") || tags.Contains("+"))
+ {
+ rowIndex = i;
+ return true;
+ }
+ // 出于历史兼容性,对第一行特殊处理,如果不包含任何tag或者只包含column,则也认为是标题行
+ if (i == 0 && (tags.Count == 0 || (tags.Count == 1 && tags[0] == "column")))
+ {
+ rowIndex = i;
+ return true;
+ }
+ }
+ rowIndex = 0;
+ return false;
+ }
+
private static bool TryFindNextSubFieldRowIndex(List> cells, int startRowIndex, out int rowIndex)
{
for (int i = startRowIndex; i < cells.Count; i++)
@@ -337,7 +372,6 @@ namespace Luban.Job.Cfg.DataSources.Excel
{
return false;
}
-
foreach (var attr in metaStr.Substring(2).Split('&'))
{
if (string.IsNullOrWhiteSpace(attr))
@@ -350,6 +384,15 @@ namespace Luban.Job.Cfg.DataSources.Excel
string value = sepIndex >= 0 ? attr.Substring(sepIndex + 1) : "";
switch (key)
{
+ case "field":
+ case "+":
+ case "var":
+ case "comment":
+ case "desc":
+ case "type":
+ {
+ break;
+ }
case "row":
{
orientRow = true;
@@ -367,7 +410,7 @@ namespace Luban.Job.Cfg.DataSources.Excel
}
default:
{
- throw new Exception($"非法单元薄 meta 属性定义 {attr}, 合法属性有: row,column,table=");
+ throw new Exception($"非法单元薄 meta 属性定义 {attr}, 合法属性有: +,var,row,column,table=");
}
}
}