【重构】完成数据生成重构
parent
1c22887e69
commit
a7dcb7f64d
|
|
@ -277,6 +277,7 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
|
|
||||||
public DType Accept(TText type, ExcelStream x)
|
public DType Accept(TText type, ExcelStream x)
|
||||||
{
|
{
|
||||||
|
x = SepIfNeed(type, x);
|
||||||
string key = ParseString(x.Read());
|
string key = ParseString(x.Read());
|
||||||
if (key == null)
|
if (key == null)
|
||||||
{
|
{
|
||||||
|
|
@ -302,15 +303,15 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string sep = f.Tags.TryGetValue("tag", out var s) ? s : null;
|
//string sep = f.Tags.TryGetValue("tag", out var s) ? s : null;
|
||||||
if (string.IsNullOrWhiteSpace(sep))
|
//if (string.IsNullOrWhiteSpace(sep))
|
||||||
{
|
//{
|
||||||
list.Add(f.CType.Apply(this, stream));
|
list.Add(f.CType.Apply(this, stream));
|
||||||
}
|
//}
|
||||||
else
|
//else
|
||||||
{
|
//{
|
||||||
list.Add(f.CType.Apply(this, new ExcelStream(stream.ReadCell(), sep)));
|
// list.Add(f.CType.Apply(this, new ExcelStream(stream.ReadCell(), sep)));
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
catch (DataCreateException dce)
|
catch (DataCreateException dce)
|
||||||
{
|
{
|
||||||
|
|
@ -327,9 +328,23 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ExcelStream SepIfNeed(TType type, ExcelStream stream)
|
||||||
|
{
|
||||||
|
string sep = DataUtil.GetSep(type);
|
||||||
|
if (!string.IsNullOrEmpty(sep))
|
||||||
|
{
|
||||||
|
return new ExcelStream(stream.ReadCell(), sep);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public DType Accept(TBean type, ExcelStream x)
|
public DType Accept(TBean type, ExcelStream x)
|
||||||
{
|
{
|
||||||
var originBean = (DefBean)type.Bean;
|
var originBean = (DefBean)type.Bean;
|
||||||
|
x = SepIfNeed(type, x);
|
||||||
|
|
||||||
if (originBean.IsAbstractType)
|
if (originBean.IsAbstractType)
|
||||||
{
|
{
|
||||||
|
|
@ -372,46 +387,38 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
// 因为貌似没意义?
|
// 因为貌似没意义?
|
||||||
public List<DType> ReadList(TType type, ExcelStream stream)
|
public List<DType> ReadList(TType type, ExcelStream stream)
|
||||||
{
|
{
|
||||||
string sep = type is TBean bean ? ((DefBean)bean.Bean).Sep : null;
|
|
||||||
var datas = new List<DType>();
|
var datas = new List<DType>();
|
||||||
while (!stream.TryReadEOF())
|
while (!stream.TryReadEOF())
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(sep))
|
datas.Add(type.Apply(this, stream));
|
||||||
{
|
|
||||||
datas.Add(type.Apply(this, stream));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
datas.Add(type.Apply(this, new ExcelStream(stream.ReadCell(), sep))); ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return datas;
|
return datas;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DType Accept(TArray type, ExcelStream x)
|
public DType Accept(TArray type, ExcelStream x)
|
||||||
{
|
{
|
||||||
return new DArray(type, ReadList(type.ElementType, x));
|
return new DArray(type, ReadList(type.ElementType, SepIfNeed(type, x)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public DType Accept(TList type, ExcelStream x)
|
public DType Accept(TList type, ExcelStream x)
|
||||||
{
|
{
|
||||||
return new DList(type, ReadList(type.ElementType, x));
|
return new DList(type, ReadList(type.ElementType, SepIfNeed(type, x)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public DType Accept(TSet type, ExcelStream x)
|
public DType Accept(TSet type, ExcelStream x)
|
||||||
{
|
{
|
||||||
return new DSet(type, ReadList(type.ElementType, x));
|
return new DSet(type, ReadList(type.ElementType, SepIfNeed(type, x)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public DType Accept(TMap type, ExcelStream x)
|
public DType Accept(TMap type, ExcelStream x)
|
||||||
{
|
{
|
||||||
string sep = type.ValueType is TBean bean ? ((DefBean)bean.Bean).Sep : null;
|
x = SepIfNeed(type, x);
|
||||||
|
|
||||||
var datas = new Dictionary<DType, DType>();
|
var datas = new Dictionary<DType, DType>();
|
||||||
while (!x.TryReadEOF())
|
while (!x.TryReadEOF())
|
||||||
{
|
{
|
||||||
var key = type.KeyType.Apply(this, x);
|
var key = type.KeyType.Apply(this, x);
|
||||||
var value = string.IsNullOrWhiteSpace(sep) ? type.ValueType.Apply(this, x) : type.ValueType.Apply(this, new ExcelStream(x.ReadCell(), sep));
|
var value = type.ValueType.Apply(this, x);
|
||||||
if (!datas.TryAdd(key, value))
|
if (!datas.TryAdd(key, value))
|
||||||
{
|
{
|
||||||
throw new InvalidExcelDataException($"map 的 key:{key} 重复");
|
throw new InvalidExcelDataException($"map 的 key:{key} 重复");
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
|
|
||||||
public DType Accept(TBool type, Sheet sheet, TitleRow row)
|
public DType Accept(TBool type, Sheet sheet, TitleRow row)
|
||||||
{
|
{
|
||||||
object x = row.Current.Value;
|
object x = row.Current;
|
||||||
if (CheckNull(type.IsNullable, x))
|
if (CheckNull(type.IsNullable, x))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -49,7 +49,7 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
|
|
||||||
public DType Accept(TByte type, Sheet sheet, TitleRow row)
|
public DType Accept(TByte type, Sheet sheet, TitleRow row)
|
||||||
{
|
{
|
||||||
object x = row.Current.Value;
|
object x = row.Current;
|
||||||
if (CheckNull(type.IsNullable, x))
|
if (CheckNull(type.IsNullable, x))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -63,7 +63,7 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
|
|
||||||
public DType Accept(TShort type, Sheet sheet, TitleRow row)
|
public DType Accept(TShort type, Sheet sheet, TitleRow row)
|
||||||
{
|
{
|
||||||
object x = row.Current.Value;
|
object x = row.Current;
|
||||||
if (CheckNull(type.IsNullable, x))
|
if (CheckNull(type.IsNullable, x))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -77,7 +77,7 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
|
|
||||||
public DType Accept(TFshort type, Sheet sheet, TitleRow row)
|
public DType Accept(TFshort type, Sheet sheet, TitleRow row)
|
||||||
{
|
{
|
||||||
object x = row.Current.Value;
|
object x = row.Current;
|
||||||
if (CheckNull(type.IsNullable, x))
|
if (CheckNull(type.IsNullable, x))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -91,7 +91,7 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
|
|
||||||
public DType Accept(TInt type, Sheet sheet, TitleRow row)
|
public DType Accept(TInt type, Sheet sheet, TitleRow row)
|
||||||
{
|
{
|
||||||
object x = row.Current.Value;
|
object x = row.Current;
|
||||||
if (CheckNull(type.IsNullable, x))
|
if (CheckNull(type.IsNullable, x))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -105,7 +105,7 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
|
|
||||||
public DType Accept(TFint type, Sheet sheet, TitleRow row)
|
public DType Accept(TFint type, Sheet sheet, TitleRow row)
|
||||||
{
|
{
|
||||||
object x = row.Current.Value;
|
object x = row.Current;
|
||||||
if (CheckNull(type.IsNullable, x))
|
if (CheckNull(type.IsNullable, x))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -119,7 +119,7 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
|
|
||||||
public DType Accept(TLong type, Sheet sheet, TitleRow row)
|
public DType Accept(TLong type, Sheet sheet, TitleRow row)
|
||||||
{
|
{
|
||||||
object x = row.Current.Value;
|
object x = row.Current;
|
||||||
if (CheckNull(type.IsNullable, x))
|
if (CheckNull(type.IsNullable, x))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -133,7 +133,7 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
|
|
||||||
public DType Accept(TFlong type, Sheet sheet, TitleRow row)
|
public DType Accept(TFlong type, Sheet sheet, TitleRow row)
|
||||||
{
|
{
|
||||||
object x = row.Current.Value;
|
object x = row.Current;
|
||||||
if (CheckNull(type.IsNullable, x))
|
if (CheckNull(type.IsNullable, x))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -147,7 +147,7 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
|
|
||||||
public DType Accept(TFloat type, Sheet sheet, TitleRow row)
|
public DType Accept(TFloat type, Sheet sheet, TitleRow row)
|
||||||
{
|
{
|
||||||
object x = row.Current.Value;
|
object x = row.Current;
|
||||||
if (CheckNull(type.IsNullable, x))
|
if (CheckNull(type.IsNullable, x))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -161,7 +161,7 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
|
|
||||||
public DType Accept(TDouble type, Sheet sheet, TitleRow row)
|
public DType Accept(TDouble type, Sheet sheet, TitleRow row)
|
||||||
{
|
{
|
||||||
object x = row.Current.Value;
|
object x = row.Current;
|
||||||
if (CheckNull(type.IsNullable, x))
|
if (CheckNull(type.IsNullable, x))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -175,7 +175,7 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
|
|
||||||
public DType Accept(TEnum type, Sheet sheet, TitleRow row)
|
public DType Accept(TEnum type, Sheet sheet, TitleRow row)
|
||||||
{
|
{
|
||||||
object x = row.Current.Value;
|
object x = row.Current;
|
||||||
if (CheckNull(type.IsNullable, x))
|
if (CheckNull(type.IsNullable, x))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -224,12 +224,17 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
|
|
||||||
public DType Accept(TText type, Sheet sheet, TitleRow row)
|
public DType Accept(TText type, Sheet sheet, TitleRow row)
|
||||||
{
|
{
|
||||||
if (row.Row.Count != 2)
|
if (row.CellCount != 2)
|
||||||
{
|
{
|
||||||
throw new Exception($"text 要求两个字段");
|
throw new Exception($"text 要求两个字段");
|
||||||
}
|
}
|
||||||
var key = ParseString(row.Row[0].Value);
|
int startIndex = row.SelfTitle.FromIndex;
|
||||||
var text = ParseString(row.Row[1].Value);
|
var key = ParseString(row.Row[startIndex].Value);
|
||||||
|
var text = ParseString(row.Row[startIndex + 1].Value);
|
||||||
|
if (type.IsNullable && key == null && text == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
DataUtil.ValidateText(key, text);
|
DataUtil.ValidateText(key, text);
|
||||||
return new DText(key, text);
|
return new DText(key, text);
|
||||||
}
|
}
|
||||||
|
|
@ -238,6 +243,7 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
{
|
{
|
||||||
var list = new List<DType>();
|
var list = new List<DType>();
|
||||||
foreach (DefField f in bean.HierarchyFields)
|
foreach (DefField f in bean.HierarchyFields)
|
||||||
|
|
||||||
{
|
{
|
||||||
string fname = f.Name;
|
string fname = f.Name;
|
||||||
TitleRow field = row.GetSubTitleNamedRow(fname);
|
TitleRow field = row.GetSubTitleNamedRow(fname);
|
||||||
|
|
@ -266,7 +272,7 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
|
|
||||||
public DType Accept(TBean type, Sheet sheet, TitleRow row)
|
public DType Accept(TBean type, Sheet sheet, TitleRow row)
|
||||||
{
|
{
|
||||||
string sep = GetSep(type);
|
string sep = DataUtil.GetSep(type);
|
||||||
|
|
||||||
if (row.Row != null)
|
if (row.Row != null)
|
||||||
{
|
{
|
||||||
|
|
@ -284,7 +290,7 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
var originBean = (DefBean)type.Bean;
|
var originBean = (DefBean)type.Bean;
|
||||||
if (originBean.IsAbstractType)
|
if (originBean.IsAbstractType)
|
||||||
{
|
{
|
||||||
string subType = row.GetSubTitleNamedRow(DefBean.TYPE_NAME_KEY).Current.Value.ToString().Trim();
|
string subType = row.GetSubTitleNamedRow(DefBean.TYPE_NAME_KEY).Current.ToString().Trim();
|
||||||
if (subType.ToLower() == DefBean.BEAN_NULL_STR)
|
if (subType.ToLower() == DefBean.BEAN_NULL_STR)
|
||||||
{
|
{
|
||||||
if (!type.IsNullable)
|
if (!type.IsNullable)
|
||||||
|
|
@ -305,7 +311,7 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
{
|
{
|
||||||
if (type.IsNullable)
|
if (type.IsNullable)
|
||||||
{
|
{
|
||||||
string subType = row.GetSubTitleNamedRow(DefBean.TYPE_NAME_KEY).Current.Value.ToString().Trim();
|
string subType = row.GetSubTitleNamedRow(DefBean.TYPE_NAME_KEY).Current.ToString().Trim();
|
||||||
if (subType == DefBean.BEAN_NULL_STR)
|
if (subType == DefBean.BEAN_NULL_STR)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -331,23 +337,8 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const string SimpleContainerSep = ",;";
|
|
||||||
|
|
||||||
public string GetSep(TType type)
|
|
||||||
{
|
|
||||||
if (type.Tags.TryGetValue("sep", out var s) && !string.IsNullOrWhiteSpace(s))
|
|
||||||
{
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case TBean tb: return (tb.Bean as DefBean).Sep;
|
|
||||||
case TArray ta: return ta.ElementType.Apply(IsNotSepTypeVisitor.Ins) ? SimpleContainerSep : "";
|
|
||||||
case TList ta: return ta.ElementType.Apply(IsNotSepTypeVisitor.Ins) ? SimpleContainerSep : "";
|
|
||||||
case TSet ta: return ta.ElementType.Apply(IsNotSepTypeVisitor.Ins) ? SimpleContainerSep : "";
|
|
||||||
default: return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<DType> ReadList(TType type, ExcelStream stream)
|
public List<DType> ReadList(TType type, ExcelStream stream)
|
||||||
{
|
{
|
||||||
|
|
@ -374,7 +365,7 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
|
|
||||||
public DType Accept(TArray type, Sheet sheet, TitleRow row)
|
public DType Accept(TArray type, Sheet sheet, TitleRow row)
|
||||||
{
|
{
|
||||||
string sep = GetSep(type);
|
string sep = DataUtil.GetSep(type);
|
||||||
|
|
||||||
if (row.Row != null)
|
if (row.Row != null)
|
||||||
{
|
{
|
||||||
|
|
@ -402,7 +393,7 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
|
|
||||||
public DType Accept(TList type, Sheet sheet, TitleRow row)
|
public DType Accept(TList type, Sheet sheet, TitleRow row)
|
||||||
{
|
{
|
||||||
string sep = GetSep(type);
|
string sep = DataUtil.GetSep(type);
|
||||||
|
|
||||||
if (row.Row != null)
|
if (row.Row != null)
|
||||||
{
|
{
|
||||||
|
|
@ -430,7 +421,7 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
|
|
||||||
public DType Accept(TSet type, Sheet sheet, TitleRow row)
|
public DType Accept(TSet type, Sheet sheet, TitleRow row)
|
||||||
{
|
{
|
||||||
string sep = GetSep(type);
|
string sep = DataUtil.GetSep(type);
|
||||||
|
|
||||||
if (row.Row != null)
|
if (row.Row != null)
|
||||||
{
|
{
|
||||||
|
|
@ -458,7 +449,7 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
|
|
||||||
public DType Accept(TMap type, Sheet sheet, TitleRow row)
|
public DType Accept(TMap type, Sheet sheet, TitleRow row)
|
||||||
{
|
{
|
||||||
string sep = GetSep(type);
|
string sep = DataUtil.GetSep(type);
|
||||||
|
|
||||||
if (row.Row != null)
|
if (row.Row != null)
|
||||||
{
|
{
|
||||||
|
|
@ -494,6 +485,10 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
foreach (var e in row.Fields)
|
foreach (var e in row.Fields)
|
||||||
{
|
{
|
||||||
var keyData = type.KeyType.Apply(StringDataCreator.Ins, e.Key);
|
var keyData = type.KeyType.Apply(StringDataCreator.Ins, e.Key);
|
||||||
|
if (Sheet.IsBlankRow(e.Value.Row, e.Value.SelfTitle.FromIndex, e.Value.SelfTitle.ToIndex))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
var valueData = type.ValueType.Apply(ExcelStreamDataCreator.Ins, e.Value.AsStream(sep));
|
var valueData = type.ValueType.Apply(ExcelStreamDataCreator.Ins, e.Value.AsStream(sep));
|
||||||
datas.Add(keyData, valueData);
|
datas.Add(keyData, valueData);
|
||||||
}
|
}
|
||||||
|
|
@ -501,7 +496,15 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
}
|
}
|
||||||
else if (row.Elements != null)
|
else if (row.Elements != null)
|
||||||
{
|
{
|
||||||
throw new NotSupportedException();
|
var datas = new Dictionary<DType, DType>();
|
||||||
|
foreach (var e in row.Elements)
|
||||||
|
{
|
||||||
|
var stream = e.AsStream("");
|
||||||
|
var keyData = type.KeyType.Apply(ExcelStreamDataCreator.Ins, stream);
|
||||||
|
var valueData = type.ValueType.Apply(ExcelStreamDataCreator.Ins, stream);
|
||||||
|
datas.Add(keyData, valueData);
|
||||||
|
}
|
||||||
|
return new DMap(type, datas);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -511,37 +514,49 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
|
|
||||||
public DType Accept(TVector2 type, Sheet sheet, TitleRow row)
|
public DType Accept(TVector2 type, Sheet sheet, TitleRow row)
|
||||||
{
|
{
|
||||||
var d = row.Current.Value;
|
var d = row.Current;
|
||||||
if (CheckNull(type.IsNullable, d))
|
if (CheckNull(type.IsNullable, d))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (CheckDefault(d))
|
||||||
|
{
|
||||||
|
return DVector2.Default;
|
||||||
|
}
|
||||||
return DataUtil.CreateVector(type, d.ToString());
|
return DataUtil.CreateVector(type, d.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public DType Accept(TVector3 type, Sheet sheet, TitleRow row)
|
public DType Accept(TVector3 type, Sheet sheet, TitleRow row)
|
||||||
{
|
{
|
||||||
var d = row.Current.Value;
|
var d = row.Current;
|
||||||
if (CheckNull(type.IsNullable, d))
|
if (CheckNull(type.IsNullable, d))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (CheckDefault(d))
|
||||||
|
{
|
||||||
|
return DVector3.Default;
|
||||||
|
}
|
||||||
return DataUtil.CreateVector(type, d.ToString());
|
return DataUtil.CreateVector(type, d.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public DType Accept(TVector4 type, Sheet sheet, TitleRow row)
|
public DType Accept(TVector4 type, Sheet sheet, TitleRow row)
|
||||||
{
|
{
|
||||||
var d = row.Current.Value;
|
var d = row.Current;
|
||||||
if (CheckNull(type.IsNullable, d))
|
if (CheckNull(type.IsNullable, d))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (CheckDefault(d))
|
||||||
|
{
|
||||||
|
return DVector4.Default;
|
||||||
|
}
|
||||||
return DataUtil.CreateVector(type, d.ToString());
|
return DataUtil.CreateVector(type, d.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public DType Accept(TDateTime type, Sheet sheet, TitleRow row)
|
public DType Accept(TDateTime type, Sheet sheet, TitleRow row)
|
||||||
{
|
{
|
||||||
var d = row.Current.Value;
|
var d = row.Current;
|
||||||
if (CheckNull(type.IsNullable, d))
|
if (CheckNull(type.IsNullable, d))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using ExcelDataReader;
|
using ExcelDataReader;
|
||||||
using Luban.Job.Cfg.DataCreators;
|
using Luban.Job.Cfg.DataCreators;
|
||||||
using Luban.Job.Cfg.Datas;
|
using Luban.Job.Cfg.Datas;
|
||||||
|
using Luban.Job.Cfg.Utils;
|
||||||
using Luban.Job.Common.Types;
|
using Luban.Job.Common.Types;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
@ -26,6 +27,7 @@ namespace Luban.Job.Cfg.DataSources.Excel
|
||||||
{
|
{
|
||||||
var sheet = new Sheet(rawUrl, sheetName);
|
var sheet = new Sheet(rawUrl, sheetName);
|
||||||
sheet.Load(rawSheet);
|
sheet.Load(rawSheet);
|
||||||
|
_sheets.Add(sheet);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_sheets.Count == 0)
|
if (_sheets.Count == 0)
|
||||||
|
|
@ -36,7 +38,7 @@ namespace Luban.Job.Cfg.DataSources.Excel
|
||||||
|
|
||||||
public RawSheetTableDefInfo LoadTableDefInfo(string rawUrl, string sheetName, Stream stream)
|
public RawSheetTableDefInfo LoadTableDefInfo(string rawUrl, string sheetName, Stream stream)
|
||||||
{
|
{
|
||||||
return null;
|
return SheetLoadUtil.LoadSheetTableDefInfo(rawUrl, sheetName, stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override List<Record> ReadMulti(TBean type)
|
public override List<Record> ReadMulti(TBean type)
|
||||||
|
|
@ -48,8 +50,14 @@ namespace Luban.Job.Cfg.DataSources.Excel
|
||||||
{
|
{
|
||||||
foreach (TitleRow row in sheet.GetRows())
|
foreach (TitleRow row in sheet.GetRows())
|
||||||
{
|
{
|
||||||
|
var tagRow = row.GetSubTitleNamedRow(TAG_KEY);
|
||||||
|
string tagStr = tagRow?.Current?.ToString();
|
||||||
|
if (DataUtil.IsIgnoreTag(tagStr))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
var data = (DBean)type.Apply(SheetDataCreator.Ins, sheet, row);
|
var data = (DBean)type.Apply(SheetDataCreator.Ins, sheet, row);
|
||||||
datas.Add(new Record(data, sheet.RawUrl, row.Tags));
|
datas.Add(new Record(data, sheet.RawUrl, DataUtil.ParseTags(tagStr)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (DataCreateException dce)
|
catch (DataCreateException dce)
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,39 @@ namespace Luban.Job.Cfg.DataSources.Excel
|
||||||
private readonly int _toIndex;
|
private readonly int _toIndex;
|
||||||
private int _curIndex;
|
private int _curIndex;
|
||||||
|
|
||||||
public ExcelStream(List<Cell> datas, int fromIndex, int toIndex, string sep)
|
private readonly string _overrideDefault;
|
||||||
|
|
||||||
|
public ExcelStream(List<Cell> datas, int fromIndex, int toIndex, string sep, string overrideDefault)
|
||||||
{
|
{
|
||||||
|
_overrideDefault = overrideDefault;
|
||||||
if (string.IsNullOrWhiteSpace(sep))
|
if (string.IsNullOrWhiteSpace(sep))
|
||||||
{
|
{
|
||||||
this._datas = datas;
|
if (string.IsNullOrEmpty(overrideDefault))
|
||||||
this._toIndex = toIndex;
|
{
|
||||||
this._curIndex = fromIndex;
|
this._datas = datas;
|
||||||
|
this._toIndex = toIndex;
|
||||||
|
this._curIndex = fromIndex;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this._datas = new List<Cell>();
|
||||||
|
for (int i = fromIndex; i <= toIndex; i++)
|
||||||
|
{
|
||||||
|
var cell = datas[i];
|
||||||
|
object d = cell.Value;
|
||||||
|
if (!IsSkip(d))
|
||||||
|
{
|
||||||
|
this._datas.Add(cell);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this._datas.Add(new Cell(cell.Row, cell.Column, _overrideDefault));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._curIndex = 0;
|
||||||
|
this._toIndex = this._datas.Count - 1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -33,13 +59,20 @@ namespace Luban.Job.Cfg.DataSources.Excel
|
||||||
{
|
{
|
||||||
var cell = datas[i];
|
var cell = datas[i];
|
||||||
object d = cell.Value;
|
object d = cell.Value;
|
||||||
if (d is string s)
|
if (!IsSkip(d))
|
||||||
{
|
{
|
||||||
this._datas.AddRange(DataUtil.SplitStringByAnySepChar(s, sep).Select(x => new Cell(cell.Row, cell.Column, x)));
|
if (d is string s)
|
||||||
|
{
|
||||||
|
this._datas.AddRange(DataUtil.SplitStringByAnySepChar(s, sep).Select(x => new Cell(cell.Row, cell.Column, x)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this._datas.Add(cell);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (!string.IsNullOrEmpty(_overrideDefault))
|
||||||
{
|
{
|
||||||
this._datas.Add(cell);
|
this._datas.Add(new Cell(cell.Row, cell.Column, _overrideDefault));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this._curIndex = 0;
|
this._curIndex = 0;
|
||||||
|
|
|
||||||
|
|
@ -30,12 +30,10 @@ namespace Luban.Job.Cfg.DataSources.Excel
|
||||||
|
|
||||||
public void Load(RawSheet rawSheet)
|
public void Load(RawSheet rawSheet)
|
||||||
{
|
{
|
||||||
bool anyMultiRows = rawSheet.Title.SubTitleList.Any(t => t.SelfMultiRows);
|
|
||||||
|
|
||||||
var cells = rawSheet.Cells;
|
var cells = rawSheet.Cells;
|
||||||
Title title = rawSheet.Title;
|
Title title = rawSheet.Title;
|
||||||
|
|
||||||
if (!anyMultiRows)
|
if (!title.HierarchyMultiRows)
|
||||||
{
|
{
|
||||||
foreach (var row in cells)
|
foreach (var row in cells)
|
||||||
{
|
{
|
||||||
|
|
@ -86,14 +84,14 @@ namespace Luban.Job.Cfg.DataSources.Excel
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (title.SubTitleList.All(t => !t.SelfMultiRows && IsBlankRow(row, t.FromIndex, t.ToIndex)))
|
if (title.SubTitleList.All(t => t.SelfMultiRows || IsBlankRow(row, t.FromIndex, t.ToIndex)))
|
||||||
{
|
{
|
||||||
oneRecordRows.Add(row);
|
oneRecordRows.Add(row);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
yield return oneRecordRows;
|
yield return oneRecordRows;
|
||||||
oneRecordRows = null;
|
oneRecordRows = new List<List<Cell>>() { row };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -118,43 +116,45 @@ namespace Luban.Job.Cfg.DataSources.Excel
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (title.SelfMultiRows)
|
var fields = new Dictionary<string, TitleRow>();
|
||||||
|
foreach (var subTitle in title.SubTitleList)
|
||||||
{
|
{
|
||||||
var eles = new List<TitleRow>();
|
if (subTitle.SelfMultiRows)
|
||||||
foreach (var eleRow in SplitRows(title, rows))
|
|
||||||
{
|
{
|
||||||
var fields = new Dictionary<string, TitleRow>();
|
var eles = new List<TitleRow>();
|
||||||
foreach (var subTitle in title.SubTitleList)
|
if (subTitle.SubHierarchyMultiRows)
|
||||||
{
|
{
|
||||||
if (subTitle.SelfMultiRows)
|
foreach (var eleRows in SplitRows(subTitle, rows))
|
||||||
{
|
{
|
||||||
fields.Add(subTitle.Name, ParseMultiLineTitleRow(title, eleRow));
|
eles.Add(ParseMultiLineTitleRow(subTitle, eleRows));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
fields.Add(subTitle.Name, ParseOneLineTitleRow(title, eleRow[0]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
eles.Add(new TitleRow(title, fields));
|
|
||||||
}
|
|
||||||
return new TitleRow(title, eles);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var fields = new Dictionary<string, TitleRow>();
|
|
||||||
foreach (var subTitle in title.SubTitleList)
|
|
||||||
{
|
|
||||||
if (subTitle.SelfMultiRows)
|
|
||||||
{
|
|
||||||
fields.Add(subTitle.Name, ParseMultiLineTitleRow(title, rows));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fields.Add(subTitle.Name, ParseOneLineTitleRow(title, rows[0]));
|
foreach (var eleRow in rows)
|
||||||
|
{
|
||||||
|
if (IsBlankRow(eleRow, subTitle.FromIndex, subTitle.ToIndex))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
eles.Add(ParseOneLineTitleRow(subTitle, eleRow));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fields.Add(subTitle.Name, new TitleRow(subTitle, eles));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (subTitle.SubHierarchyMultiRows)
|
||||||
|
{
|
||||||
|
fields.Add(subTitle.Name, ParseMultiLineTitleRow(subTitle, rows));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fields.Add(subTitle.Name, ParseOneLineTitleRow(subTitle, rows[0]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new TitleRow(title, fields);
|
|
||||||
}
|
}
|
||||||
|
return new TitleRow(title, fields);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,7 +163,7 @@ namespace Luban.Job.Cfg.DataSources.Excel
|
||||||
return Rows;
|
return Rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsBlankRow(List<Cell> row, int fromIndex, int toIndex)
|
public static bool IsBlankRow(List<Cell> row, int fromIndex, int toIndex)
|
||||||
{
|
{
|
||||||
for (int i = Math.Max(1, fromIndex), n = Math.Min(toIndex, row.Count - 1); i <= n; i++)
|
for (int i = Math.Max(1, fromIndex), n = Math.Min(toIndex, row.Count - 1); i <= n; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -175,40 +175,5 @@ namespace Luban.Job.Cfg.DataSources.Excel
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsSameRow(List<Cell> row1, List<Cell> row2, int fromIndex, int toIndex)
|
|
||||||
{
|
|
||||||
if (row2.Count < toIndex - 1)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (int i = Math.Max(1, fromIndex), n = Math.Min(toIndex, row1.Count - 1); i <= n; i++)
|
|
||||||
{
|
|
||||||
var v1 = row1[i].Value;
|
|
||||||
var v2 = row2[i].Value;
|
|
||||||
if (v1 != v2)
|
|
||||||
{
|
|
||||||
if (v1 == null)
|
|
||||||
{
|
|
||||||
if (!(v2 is string s && string.IsNullOrWhiteSpace(s)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (v2 == null)
|
|
||||||
{
|
|
||||||
if (!(v1 is string s && string.IsNullOrWhiteSpace(s)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return v1.ToString() == v2.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,12 @@ namespace Luban.Job.Cfg.DataSources.Excel
|
||||||
|
|
||||||
public static Title ParseTitle(List<List<Cell>> cells, CellRange[] mergeCells, bool orientRow, out int titleRowNum)
|
public static Title ParseTitle(List<List<Cell>> cells, CellRange[] mergeCells, bool orientRow, out int titleRowNum)
|
||||||
{
|
{
|
||||||
var rootTitle = new Title() { Root = true, Name = "__root__", FromIndex = 0, ToIndex = cells.Select(r => r.Count).Max() - 1 };
|
var rootTitle = new Title() {
|
||||||
|
Root = true, Name = "__root__",
|
||||||
|
Tags = new Dictionary<string, string>(),
|
||||||
|
FromIndex = 0,
|
||||||
|
ToIndex = cells.Select(r => r.Count).Max() - 1
|
||||||
|
};
|
||||||
|
|
||||||
titleRowNum = GetTitleRowNum(mergeCells, orientRow);
|
titleRowNum = GetTitleRowNum(mergeCells, orientRow);
|
||||||
|
|
||||||
|
|
@ -150,52 +155,55 @@ namespace Luban.Job.Cfg.DataSources.Excel
|
||||||
{
|
{
|
||||||
|
|
||||||
var titleRow = cells[curDepth - 1];
|
var titleRow = cells[curDepth - 1];
|
||||||
foreach (var mergeCell in mergeCells)
|
if (mergeCells != null)
|
||||||
{
|
{
|
||||||
Title subTitle = null;
|
foreach (var mergeCell in mergeCells)
|
||||||
if (orientRow)
|
|
||||||
{
|
{
|
||||||
//if (mergeCell.FromRow <= 1 && mergeCell.ToRow >= 1)
|
Title subTitle = null;
|
||||||
if (mergeCell.FromRow == curDepth)
|
if (orientRow)
|
||||||
{
|
{
|
||||||
var nameAndAttrs = titleRow[mergeCell.FromColumn].Value?.ToString()?.Trim();
|
//if (mergeCell.FromRow <= 1 && mergeCell.ToRow >= 1)
|
||||||
if (IsIgnoreTitle(nameAndAttrs))
|
if (mergeCell.FromRow == curDepth && mergeCell.FromColumn >= title.FromIndex && mergeCell.FromColumn <= title.ToIndex)
|
||||||
{
|
{
|
||||||
continue;
|
var nameAndAttrs = titleRow[mergeCell.FromColumn].Value?.ToString()?.Trim();
|
||||||
|
if (IsIgnoreTitle(nameAndAttrs))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var (titleName, tags) = ParseNameAndMetaAttrs(nameAndAttrs);
|
||||||
|
subTitle = new Title() { Name = titleName, Tags = tags, FromIndex = mergeCell.FromColumn, ToIndex = mergeCell.ToColumn };
|
||||||
|
//s_logger.Info("=== sheet:{sheet} title:{title}", Name, newTitle);
|
||||||
}
|
}
|
||||||
var (titleName, tags) = ParseNameAndMetaAttrs(nameAndAttrs);
|
|
||||||
subTitle = new Title() { Name = titleName, Tags = tags, FromIndex = mergeCell.FromColumn, ToIndex = mergeCell.ToColumn };
|
|
||||||
//s_logger.Info("=== sheet:{sheet} title:{title}", Name, newTitle);
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
|
||||||
{
|
|
||||||
if (mergeCell.FromColumn == curDepth - 1)
|
|
||||||
{
|
{
|
||||||
// 标题 行
|
if (mergeCell.FromColumn == curDepth - 1 && mergeCell.FromRow - 1 >= title.FromIndex && mergeCell.FromRow - 1 <= title.ToIndex)
|
||||||
var nameAndAttrs = titleRow[mergeCell.FromRow - 1].Value?.ToString()?.Trim();
|
|
||||||
if (IsIgnoreTitle(nameAndAttrs))
|
|
||||||
{
|
{
|
||||||
continue;
|
// 标题 行
|
||||||
|
var nameAndAttrs = titleRow[mergeCell.FromRow - 1].Value?.ToString()?.Trim();
|
||||||
|
if (IsIgnoreTitle(nameAndAttrs))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var (titleName, tags) = ParseNameAndMetaAttrs(nameAndAttrs);
|
||||||
|
subTitle = new Title() { Name = titleName, Tags = tags, FromIndex = mergeCell.FromRow - 1, ToIndex = mergeCell.ToRow - 1 };
|
||||||
}
|
}
|
||||||
var (titleName, tags) = ParseNameAndMetaAttrs(nameAndAttrs);
|
|
||||||
subTitle = new Title() { Name = titleName, Tags = tags, FromIndex = mergeCell.FromRow - 1, ToIndex = mergeCell.ToRow - 1 };
|
|
||||||
}
|
}
|
||||||
}
|
if (subTitle == null)
|
||||||
if (subTitle == null)
|
{
|
||||||
{
|
continue;
|
||||||
continue;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (curDepth < maxDepth)
|
if (curDepth < maxDepth)
|
||||||
{
|
{
|
||||||
ParseSubTitles(subTitle, cells, mergeCells, orientRow, curDepth + 1, maxDepth);
|
ParseSubTitles(subTitle, cells, mergeCells, orientRow, curDepth + 1, maxDepth);
|
||||||
}
|
}
|
||||||
title.AddSubTitle(subTitle);
|
title.AddSubTitle(subTitle);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < titleRow.Count; i++)
|
for (int i = title.FromIndex; i <= title.ToIndex; i++)
|
||||||
{
|
{
|
||||||
var nameAndAttrs = titleRow[i].Value?.ToString()?.Trim();
|
var nameAndAttrs = titleRow[i].Value?.ToString()?.Trim();
|
||||||
if (IsIgnoreTitle(nameAndAttrs))
|
if (IsIgnoreTitle(nameAndAttrs))
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,14 @@ namespace Luban.Job.Cfg.DataSources.Excel
|
||||||
|
|
||||||
public string Sep { get; private set; }
|
public string Sep { get; private set; }
|
||||||
|
|
||||||
|
public string Default { get; private set; }
|
||||||
|
|
||||||
public bool SelfMultiRows { get; private set; }
|
public bool SelfMultiRows { get; private set; }
|
||||||
|
|
||||||
public bool HierarchyMultiRows { get; private set; }
|
public bool HierarchyMultiRows { get; private set; }
|
||||||
|
|
||||||
|
public bool SubHierarchyMultiRows { get; private set; }
|
||||||
|
|
||||||
public void AddSubTitle(Title title)
|
public void AddSubTitle(Title title)
|
||||||
{
|
{
|
||||||
if (!SubTitles.TryAdd(title.Name, title))
|
if (!SubTitles.TryAdd(title.Name, title))
|
||||||
|
|
@ -55,6 +59,7 @@ namespace Luban.Job.Cfg.DataSources.Excel
|
||||||
SortSubTitles();
|
SortSubTitles();
|
||||||
Sep = Tags.TryGetValue("sep", out var v) && !string.IsNullOrWhiteSpace(v) ? v : null;
|
Sep = Tags.TryGetValue("sep", out var v) && !string.IsNullOrWhiteSpace(v) ? v : null;
|
||||||
SelfMultiRows = Tags.TryGetValue("multi_rows", out var v2) && (v2 == "1" || v2 == "true");
|
SelfMultiRows = Tags.TryGetValue("multi_rows", out var v2) && (v2 == "1" || v2 == "true");
|
||||||
|
Default = Tags.TryGetValue("default", out var v3) ? v3 : null;
|
||||||
if (SubTitleList.Count > 0)
|
if (SubTitleList.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var sub in SubTitleList)
|
foreach (var sub in SubTitleList)
|
||||||
|
|
@ -62,7 +67,8 @@ namespace Luban.Job.Cfg.DataSources.Excel
|
||||||
sub.Init();
|
sub.Init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HierarchyMultiRows = SelfMultiRows || SubTitleList.Any(t => t.HierarchyMultiRows);
|
SubHierarchyMultiRows = SubTitleList.Any(t => t.HierarchyMultiRows); ;
|
||||||
|
HierarchyMultiRows = SelfMultiRows || SubHierarchyMultiRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
|
|
||||||
|
|
@ -10,78 +10,61 @@ namespace Luban.Job.Cfg.DataSources.Excel
|
||||||
{
|
{
|
||||||
public List<string> Tags { get; }
|
public List<string> Tags { get; }
|
||||||
|
|
||||||
|
|
||||||
//public static IEnumerable<TitleRow> CreateMultiRowNamedRow(List<List<Cell>> rows, Title title, TBean bean)
|
|
||||||
//{
|
|
||||||
// if (!((DefBean)bean.Bean).IsMultiRow)
|
|
||||||
// {
|
|
||||||
// foreach (var row in rows)
|
|
||||||
// {
|
|
||||||
// if (Sheet.IsBlankRow(row, title.FromIndex, title.ToIndex))
|
|
||||||
// {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// yield return new TitleRow(title, row);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// List<DefField> notMultiRowFields = bean.Bean.HierarchyFields.Select(f => (DefField)f).Where(f => !f.IsMultiRow && f.IsRowOrient).ToList();
|
|
||||||
// List<List<Cell>> recordRows = null;
|
|
||||||
// foreach (var row in rows)
|
|
||||||
// {
|
|
||||||
// // 忽略全空的行
|
|
||||||
// if (Sheet.IsBlankRow(row, title.FromIndex, title.ToIndex))
|
|
||||||
// {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// // 如果非多行数据全空,或者跟记录第一行完全相同说明该行属于多行数据
|
|
||||||
// if (notMultiRowFields.All(f =>
|
|
||||||
// {
|
|
||||||
// var fieldTitle = title.SubTitles[f.Name];
|
|
||||||
// return Sheet.IsBlankRow(row, fieldTitle.FromIndex, fieldTitle.ToIndex);
|
|
||||||
// }) || (title.Root && recordRows != null && notMultiRowFields.All(f =>
|
|
||||||
// {
|
|
||||||
// var fieldTitle = title.SubTitles[f.Name];
|
|
||||||
// return Sheet.IsSameRow(row, recordRows[0], fieldTitle.FromIndex, fieldTitle.ToIndex);
|
|
||||||
// })))
|
|
||||||
// {
|
|
||||||
// if (recordRows == null)
|
|
||||||
// {
|
|
||||||
// recordRows = new List<List<Cell>>();
|
|
||||||
// }
|
|
||||||
// recordRows.Add(row);
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// if (recordRows != null)
|
|
||||||
// {
|
|
||||||
// yield return new TitleRow(title, recordRows);
|
|
||||||
// }
|
|
||||||
// recordRows = new List<List<Cell>>();
|
|
||||||
// recordRows.Add(row);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (recordRows != null)
|
|
||||||
// {
|
|
||||||
// yield return new TitleRow(title, recordRows);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
public Title SelfTitle { get; }
|
public Title SelfTitle { get; }
|
||||||
|
|
||||||
public Cell Current => Row[0];
|
public object Current
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var v = Row[SelfTitle.FromIndex].Value;
|
||||||
|
if (v == null || (v is string s && string.IsNullOrEmpty(s) && !string.IsNullOrEmpty(SelfTitle.Default)))
|
||||||
|
{
|
||||||
|
return SelfTitle.Default;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public List<Cell> Row { get; }
|
public List<Cell> Row { get; }
|
||||||
|
|
||||||
|
public int CellCount => SelfTitle.ToIndex - SelfTitle.FromIndex + 1;
|
||||||
|
|
||||||
public List<List<Cell>> Rows { get; }
|
public List<List<Cell>> Rows { get; }
|
||||||
|
|
||||||
public Dictionary<string, TitleRow> Fields { get; }
|
public Dictionary<string, TitleRow> Fields { get; }
|
||||||
|
|
||||||
public List<TitleRow> Elements { get; }
|
public List<TitleRow> Elements { get; }
|
||||||
|
|
||||||
public ExcelStream AsStream(string sep) => new ExcelStream(Row, 0, Row.Count - 1, sep);
|
public ExcelStream AsStream(string sep)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(SelfTitle.Sep))
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(sep))
|
||||||
|
{
|
||||||
|
return new ExcelStream(Row, SelfTitle.FromIndex, SelfTitle.ToIndex, "", SelfTitle.Default);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new ExcelStream(Row, SelfTitle.FromIndex, SelfTitle.ToIndex, sep, SelfTitle.Default);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//if (string.IsNullOrEmpty(sep) || sep == SelfTitle.Sep)
|
||||||
|
//{
|
||||||
|
// return new ExcelStream(Row, SelfTitle.FromIndex, SelfTitle.ToIndex, sep);
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// SelfTitle.Sep 设置覆盖 bean的 sep设置(只有这个可能)
|
||||||
|
return new ExcelStream(Row, SelfTitle.FromIndex, SelfTitle.ToIndex, SelfTitle.Sep, SelfTitle.Default);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public bool HasSubFields => Fields != null || Elements != null;
|
public bool HasSubFields => Fields != null || Elements != null;
|
||||||
|
|
||||||
|
|
@ -111,49 +94,11 @@ namespace Luban.Job.Cfg.DataSources.Excel
|
||||||
|
|
||||||
public int RowCount => Rows.Count;
|
public int RowCount => Rows.Count;
|
||||||
|
|
||||||
//private void CheckEmptySinceSecondRow(string name, int fromIndex, int toIndex)
|
|
||||||
//{
|
|
||||||
// for (int i = 1; i < Rows.Count; i++)
|
|
||||||
// {
|
|
||||||
// var row = Rows[i];
|
|
||||||
// if (!IsBlankRow(row, fromIndex, toIndex))
|
|
||||||
// {
|
|
||||||
// throw new Exception($"字段:{name} 不是多行字段,只能第一行填值. {Bright.Common.StringUtil.CollectionToString(row)}");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
public Title GetTitle(string name)
|
public Title GetTitle(string name)
|
||||||
{
|
{
|
||||||
return SelfTitle.SubTitles.TryGetValue(name, out var title) ? title : null;
|
return SelfTitle.SubTitles.TryGetValue(name, out var title) ? title : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//public ExcelStream GetColumn(string name)
|
|
||||||
//{
|
|
||||||
// var field = GetSubTitleNamedRow(name);
|
|
||||||
// if (field != null)
|
|
||||||
// {
|
|
||||||
// return field.AsStream;
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// throw new Exception($"单元薄 缺失 列:{name},请检查是否写错或者遗漏");
|
|
||||||
// }
|
|
||||||
// //if (Titles.TryGetValue(name, out var title))
|
|
||||||
// //{
|
|
||||||
// // // 只有顶级root支持才允许非multi_rows字段与第一行相同时,判定为同个记录
|
|
||||||
// // if (!this.SelfTitle.Root)
|
|
||||||
// // {
|
|
||||||
// // CheckEmptySinceSecondRow(name, title.FromIndex, title.ToIndex);
|
|
||||||
// // }
|
|
||||||
// // var es = new ExcelStream(Rows[0], title.FromIndex, title.ToIndex, sep, namedMode);
|
|
||||||
// // return es;
|
|
||||||
// //}
|
|
||||||
// //else
|
|
||||||
// //{
|
|
||||||
// // throw new Exception($"单元薄 缺失 列:{name},请检查是否写错或者遗漏");
|
|
||||||
// //}
|
|
||||||
//}
|
|
||||||
|
|
||||||
public TitleRow GetSubTitleNamedRow(string name)
|
public TitleRow GetSubTitleNamedRow(string name)
|
||||||
{
|
{
|
||||||
|
|
@ -162,53 +107,12 @@ namespace Luban.Job.Cfg.DataSources.Excel
|
||||||
return Fields.TryGetValue(name, out var r) ? r : null;
|
return Fields.TryGetValue(name, out var r) ? r : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//public IEnumerable<TitleRow> GenerateSubNameRows(TBean bean)
|
|
||||||
//{
|
|
||||||
// foreach (var row in Rows)
|
|
||||||
// {
|
|
||||||
// if (SelfTitle != null ? IsBlankRow(row, SelfTitle.FromIndex, SelfTitle.ToIndex) : IsBlankRow(row))
|
|
||||||
// {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// yield return new TitleRow(SelfTitle, row);
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
public IEnumerable<ExcelStream> GetColumnOfMultiRows(string name, string sep)
|
public IEnumerable<ExcelStream> GetColumnOfMultiRows(string name, string sep)
|
||||||
{
|
{
|
||||||
foreach (var ele in GetSubTitleNamedRow(name).Elements)
|
foreach (var ele in GetSubTitleNamedRow(name).Elements)
|
||||||
{
|
{
|
||||||
yield return ele.AsStream(sep);
|
yield return ele.AsStream(sep);
|
||||||
}
|
}
|
||||||
//if (Titles.TryGetValue(name, out var title))
|
|
||||||
//{
|
|
||||||
// if (isRowOrient)
|
|
||||||
// {
|
|
||||||
// foreach (var row in Rows)
|
|
||||||
// {
|
|
||||||
// if (IsBlankRow(row, title.FromIndex, title.ToIndex))
|
|
||||||
// {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// yield return new ExcelStream(row, title.FromIndex, title.ToIndex, sep, false);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// for (int i = title.FromIndex; i <= title.ToIndex; i++)
|
|
||||||
// {
|
|
||||||
// if (!IsBlankColumn(Rows, i))
|
|
||||||
// {
|
|
||||||
// var cells = Rows.Where(r => r.Count > i).Select(r => r[i]).Where(v => !(v.Value == null || (v.Value is string s && string.IsNullOrEmpty(s)))).ToList();
|
|
||||||
// yield return new ExcelStream(cells, 0, cells.Count - 1, sep, false);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
// throw new Exception($"单元薄 缺失 列:{name},请检查是否写错或者遗漏");
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ namespace Luban.Job.Cfg.Datas
|
||||||
|
|
||||||
public static DFshort ValueOf(short x)
|
public static DFshort ValueOf(short x)
|
||||||
{
|
{
|
||||||
return x == 0 ? Default : new DFshort(0);
|
return x == 0 ? Default : new DFshort(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string TypeName => "fshort";
|
public override string TypeName => "fshort";
|
||||||
|
|
|
||||||
|
|
@ -566,15 +566,10 @@ namespace Luban.Job.Cfg.Defs
|
||||||
{
|
{
|
||||||
new CfgField() { Name = "name", Type = "string" },
|
new CfgField() { Name = "name", Type = "string" },
|
||||||
new CfgField() { Name = "type", Type = "string" },
|
new CfgField() { Name = "type", Type = "string" },
|
||||||
new CfgField() { Name = "sep", Type = "string" },
|
|
||||||
new CfgField() { Name = "is_multi_rows", Type = "bool" },
|
|
||||||
new CfgField() { Name = "index", Type = "string" },
|
new CfgField() { Name = "index", Type = "string" },
|
||||||
new CfgField() { Name = "group", Type = "string" },
|
new CfgField() { Name = "group", Type = "string" },
|
||||||
new CfgField() { Name = "ref", Type = "string", IgnoreNameValidation = true },
|
|
||||||
new CfgField() { Name = "path", Type = "string" },
|
|
||||||
new CfgField() { Name = "comment", Type = "string" },
|
new CfgField() { Name = "comment", Type = "string" },
|
||||||
new CfgField() { Name = "tags", Type = "string" },
|
new CfgField() { Name = "tags", Type = "string" },
|
||||||
new CfgField() { Name = "orientation", Type = "string" },
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
|
|
@ -613,7 +608,6 @@ namespace Luban.Job.Cfg.Defs
|
||||||
defTableRecordType.PreCompile();
|
defTableRecordType.PreCompile();
|
||||||
defTableRecordType.Compile();
|
defTableRecordType.Compile();
|
||||||
defTableRecordType.PostCompile();
|
defTableRecordType.PostCompile();
|
||||||
ass.MarkMultiRows();
|
|
||||||
var tableRecordType = TBean.Create(false, defTableRecordType);
|
var tableRecordType = TBean.Create(false, defTableRecordType);
|
||||||
|
|
||||||
foreach (var file in inputFileInfos)
|
foreach (var file in inputFileInfos)
|
||||||
|
|
@ -672,21 +666,11 @@ namespace Luban.Job.Cfg.Defs
|
||||||
private static readonly List<string> _fieldOptionalAttrs = new()
|
private static readonly List<string> _fieldOptionalAttrs = new()
|
||||||
{
|
{
|
||||||
"index",
|
"index",
|
||||||
"sep",
|
|
||||||
"validator",
|
|
||||||
"key_validator",
|
|
||||||
"value_validator",
|
|
||||||
"ref",
|
"ref",
|
||||||
"path",
|
"path",
|
||||||
"range",
|
|
||||||
"multi_rows",
|
|
||||||
"group",
|
"group",
|
||||||
"res",
|
|
||||||
"convert",
|
|
||||||
"comment",
|
"comment",
|
||||||
"tags",
|
"tags",
|
||||||
"default",
|
|
||||||
"orientation",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly List<string> _fieldRequireAttrs = new List<string> { "name", "type" };
|
private static readonly List<string> _fieldRequireAttrs = new List<string> { "name", "type" };
|
||||||
|
|
@ -695,8 +679,20 @@ namespace Luban.Job.Cfg.Defs
|
||||||
{
|
{
|
||||||
ValidAttrKeys(defineFile, e, _fieldOptionalAttrs, _fieldRequireAttrs);
|
ValidAttrKeys(defineFile, e, _fieldOptionalAttrs, _fieldRequireAttrs);
|
||||||
|
|
||||||
|
string refStr = XmlUtil.GetOptionalAttribute(e, "ref");
|
||||||
|
string typeStr = XmlUtil.GetRequiredAttribute(e, "type");
|
||||||
|
if (!string.IsNullOrWhiteSpace(refStr))
|
||||||
|
{
|
||||||
|
typeStr = typeStr + "&ref=" + refStr;
|
||||||
|
}
|
||||||
|
string pathStr = XmlUtil.GetOptionalAttribute(e, "path");
|
||||||
|
if (!string.IsNullOrWhiteSpace(pathStr))
|
||||||
|
{
|
||||||
|
typeStr = typeStr + "&path=" + pathStr;
|
||||||
|
}
|
||||||
|
|
||||||
return CreateField(defineFile, XmlUtil.GetRequiredAttribute(e, "name"),
|
return CreateField(defineFile, XmlUtil.GetRequiredAttribute(e, "name"),
|
||||||
XmlUtil.GetRequiredAttribute(e, "type"),
|
typeStr,
|
||||||
XmlUtil.GetOptionalAttribute(e, "index"),
|
XmlUtil.GetOptionalAttribute(e, "index"),
|
||||||
XmlUtil.GetOptionalAttribute(e, "group"),
|
XmlUtil.GetOptionalAttribute(e, "group"),
|
||||||
XmlUtil.GetOptionalAttribute(e, "comment"),
|
XmlUtil.GetOptionalAttribute(e, "comment"),
|
||||||
|
|
|
||||||
|
|
@ -263,43 +263,6 @@ namespace Luban.Job.Cfg.Defs
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 丑陋. 怎么写更好?
|
|
||||||
|
|
||||||
// 递归 设置DefBean及DefField 的 IsMultiRow
|
|
||||||
|
|
||||||
MarkMultiRows();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void MarkMultiRows()
|
|
||||||
{
|
|
||||||
var multiRowBeans = new HashSet<DefBean>();
|
|
||||||
for (bool anyMark = true; anyMark;)
|
|
||||||
{
|
|
||||||
anyMark = false;
|
|
||||||
foreach (var type in this.Types.Values)
|
|
||||||
{
|
|
||||||
if (type is DefBean beanType && !beanType.IsMultiRow)
|
|
||||||
{
|
|
||||||
bool isMultiRows;
|
|
||||||
if (beanType.IsNotAbstractType)
|
|
||||||
{
|
|
||||||
isMultiRows = beanType.HierarchyFields.Any(f => ((DefField)f).ComputeIsMultiRow());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
isMultiRows = beanType.HierarchyNotAbstractChildren.Any(c => ((DefBean)c).IsMultiRow);
|
|
||||||
}
|
|
||||||
if (isMultiRows)
|
|
||||||
{
|
|
||||||
beanType.IsMultiRow = true;
|
|
||||||
//s_logger.Info("bean:{bean} is multi row", beanType.FullName);
|
|
||||||
anyMark = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,29 +16,6 @@ namespace Luban.Job.Cfg.Defs
|
||||||
{
|
{
|
||||||
public DefAssembly Assembly => (DefAssembly)HostType.AssemblyBase;
|
public DefAssembly Assembly => (DefAssembly)HostType.AssemblyBase;
|
||||||
|
|
||||||
|
|
||||||
public bool RawIsMultiRow { get; }
|
|
||||||
|
|
||||||
public bool IsMultiRow { get; private set; }
|
|
||||||
|
|
||||||
public bool ComputeIsMultiRow()
|
|
||||||
{
|
|
||||||
if (IsMultiRow)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (CType)
|
|
||||||
{
|
|
||||||
case TBean b: { return IsMultiRow = ((DefBean)b.Bean).IsMultiRow; }
|
|
||||||
case TList b: { return IsMultiRow = b.ElementType is TBean b2 && ((DefBean)b2.Bean).IsMultiRow; }
|
|
||||||
case TArray b: { return IsMultiRow = b.ElementType is TBean b2 && ((DefBean)b2.Bean).IsMultiRow; }
|
|
||||||
case TMap b: { return IsMultiRow = b.ValueType is TBean b2 && ((DefBean)b2.Bean).IsMultiRow; }
|
|
||||||
default: return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public string Index { get; }
|
public string Index { get; }
|
||||||
|
|
||||||
public List<string> Groups { get; }
|
public List<string> Groups { get; }
|
||||||
|
|
@ -212,11 +189,6 @@ namespace Luban.Job.Cfg.Defs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsMultiRow && !CType.IsCollection && !CType.IsBean)
|
|
||||||
{
|
|
||||||
throw new Exception($"只有容器类型才支持 multi_line 属性");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Index))
|
if (!string.IsNullOrEmpty(Index))
|
||||||
{
|
{
|
||||||
if ((CType is TArray tarray) && (tarray.ElementType is TBean b))
|
if ((CType is TArray tarray) && (tarray.ElementType is TBean b))
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,6 @@ namespace Luban.Job.Cfg.TypeVisitors
|
||||||
//#if !LUBAN_LITE
|
//#if !LUBAN_LITE
|
||||||
// || f1.ResourceTag != f2.ResourceTag
|
// || f1.ResourceTag != f2.ResourceTag
|
||||||
//#endif
|
//#endif
|
||||||
|| f1.IsMultiRow != f2.IsMultiRow
|
|
||||||
|| f1.CType.IsNullable != f2.CType.IsNullable
|
|| f1.CType.IsNullable != f2.CType.IsNullable
|
||||||
|| f1.CType.GetType() != f2.CType.GetType()
|
|| f1.CType.GetType() != f2.CType.GetType()
|
||||||
//|| !IsValidatorEquals(f1.RawDefine.Validators, f2.RawDefine.Validators)
|
//|| !IsValidatorEquals(f1.RawDefine.Validators, f2.RawDefine.Validators)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
using Luban.Job.Cfg.Datas;
|
using Luban.Job.Cfg.Datas;
|
||||||
|
using Luban.Job.Cfg.Defs;
|
||||||
|
using Luban.Job.Cfg.TypeVisitors;
|
||||||
using Luban.Job.Common.Types;
|
using Luban.Job.Common.Types;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
@ -137,6 +139,24 @@ namespace Luban.Job.Cfg.Utils
|
||||||
return tags.Count > 0 ? tags : null;
|
return tags.Count > 0 ? tags : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const string SimpleContainerSep = ",;";
|
||||||
|
|
||||||
|
public static string GetSep(TType type)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (type.Tags != null && type.Tags.TryGetValue("sep", out var s) && !string.IsNullOrWhiteSpace(s))
|
||||||
|
{
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case TBean tb: return (tb.Bean as DefBean).Sep;
|
||||||
|
case TArray ta: return ta.ElementType.Apply(IsNotSepTypeVisitor.Ins) ? SimpleContainerSep : "";
|
||||||
|
case TList ta: return ta.ElementType.Apply(IsNotSepTypeVisitor.Ins) ? SimpleContainerSep : "";
|
||||||
|
case TSet ta: return ta.ElementType.Apply(IsNotSepTypeVisitor.Ins) ? SimpleContainerSep : "";
|
||||||
|
default: return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
//public static string Data2String(DType data)
|
//public static string Data2String(DType data)
|
||||||
//{
|
//{
|
||||||
// var s = new StringBuilder();
|
// var s = new StringBuilder();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue