diff --git a/src/Luban.Job.Cfg/Source/DataCreators/ExcelNamedRowDataCreator.cs b/src/Luban.Job.Cfg/Source/DataCreators/ExcelNamedRowDataCreator.cs index 72cd09e..304bb33 100644 --- a/src/Luban.Job.Cfg/Source/DataCreators/ExcelNamedRowDataCreator.cs +++ b/src/Luban.Job.Cfg/Source/DataCreators/ExcelNamedRowDataCreator.cs @@ -147,11 +147,11 @@ namespace Luban.Job.Cfg.DataCreators { if (f.CType.IsCollection) { - list.Add(f.CType.Apply(MultiRowExcelDataCreator.Ins, row.GetColumnOfMultiRows(f.Name, sep), f.IsNullable, (DefAssembly)bean.AssemblyBase)); + list.Add(f.CType.Apply(MultiRowExcelDataCreator.Ins, row.GetColumnOfMultiRows(f.Name, sep, f.IsRowOrient), f.IsNullable, (DefAssembly)bean.AssemblyBase)); } else { - list.Add(f.CType.Apply(ExcelDataCreator.Ins, null, row.GetMultiRowStream(f.Name, sep), (DefAssembly)bean.AssemblyBase)); + list.Add(f.CType.Apply(ExcelDataCreator.Ins, null, row.GetMultiRowStream(f.Name, sep, f.IsRowOrient), (DefAssembly)bean.AssemblyBase)); } } catch (DataCreateException dce) diff --git a/src/Luban.Job.Cfg/Source/DataSources/Excel/Sheet.cs b/src/Luban.Job.Cfg/Source/DataSources/Excel/Sheet.cs index 7d826d0..f096ea8 100644 --- a/src/Luban.Job.Cfg/Source/DataSources/Excel/Sheet.cs +++ b/src/Luban.Job.Cfg/Source/DataSources/Excel/Sheet.cs @@ -6,6 +6,7 @@ using Luban.Job.Cfg.RawDefs; using Luban.Job.Cfg.TypeVisitors; using Luban.Job.Cfg.Utils; using Luban.Job.Common.Types; +using Luban.Job.Common.Utils; using System; using System.Collections.Generic; using System.Linq; @@ -240,17 +241,30 @@ namespace Luban.Job.Cfg.DataSources.Excel } } - public IEnumerable GetColumnOfMultiRows(string name, string sep) + public IEnumerable GetColumnOfMultiRows(string name, string sep, bool isRowOrient) { if (Titles.TryGetValue(name, out var title)) { - foreach (var row in Rows) + if (isRowOrient) { - if (IsBlankRow(row, title.FromIndex, title.ToIndex)) + foreach (var row in Rows) { - continue; + 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)) + { + yield return new ExcelStream(Rows.Select(r => r[i]).ToList(), 0, Rows.Count - 1, sep, false); + } } - yield return new ExcelStream(row, title.FromIndex, title.ToIndex, sep, false); } } else @@ -260,13 +274,20 @@ namespace Luban.Job.Cfg.DataSources.Excel } - public ExcelStream GetMultiRowStream(string name, string sep) + public ExcelStream GetMultiRowStream(string name, string sep, bool isRowOrient) { if (Titles.TryGetValue(name, out var title)) { - var totalCells = Rows.SelectMany(r => r.GetRange(title.FromIndex, title.ToIndex - title.FromIndex + 1)) - .Where(c => c.Value != null && !(c.Value is string s && string.IsNullOrWhiteSpace(s))).ToList(); - return new ExcelStream(totalCells, 0, totalCells.Count - 1, sep, false); + if (isRowOrient) + { + var totalCells = Rows.SelectMany(r => r.GetRange(title.FromIndex, title.ToIndex - title.FromIndex + 1)) + .Where(c => c.Value != null && !(c.Value is string s && string.IsNullOrWhiteSpace(s))).ToList(); + return new ExcelStream(totalCells, 0, totalCells.Count - 1, sep, false); + } + else + { + throw new NotSupportedException($"bean类型多行数据不支持纵向填写"); + } } else { @@ -325,17 +346,7 @@ namespace Luban.Job.Cfg.DataSources.Excel { case "orientation": { - switch (value) - { - case "r": - case "row": IsOrientRow = true; break; - case "c": - case "column": IsOrientRow = false; break; - default: - { - throw new Exception($"单元薄 meta 定义 orientation:{value} 属性值只能为row|r|column|c"); - } - } + IsOrientRow = DefUtil.ParseOrientation(value); break; } case "title_rows": @@ -646,6 +657,19 @@ namespace Luban.Job.Cfg.DataSources.Excel return true; } + private static bool IsBlankColumn(List> rows, int column) + { + foreach (List row in rows) + { + var v = row[column].Value; + if (v != null && !(v is string s && string.IsNullOrEmpty(s))) + { + return false; + } + } + return true; + } + public IEnumerable ReadMulti(TBean type) { foreach (var recordNamedRow in NamedRow.CreateMultiRowNamedRow(this._rowColumns, this._rootTitle, type)) diff --git a/src/Luban.Job.Cfg/Source/Defs/CfgDefLoader.cs b/src/Luban.Job.Cfg/Source/Defs/CfgDefLoader.cs index 9169a79..8650675 100644 --- a/src/Luban.Job.Cfg/Source/Defs/CfgDefLoader.cs +++ b/src/Luban.Job.Cfg/Source/Defs/CfgDefLoader.cs @@ -6,6 +6,7 @@ using Luban.Job.Cfg.Utils; using Luban.Job.Common.Defs; using Luban.Job.Common.RawDefs; using Luban.Job.Common.Types; +using Luban.Job.Common.Utils; using Luban.Server.Common; using System; using System.Collections.Generic; @@ -609,6 +610,7 @@ namespace Luban.Job.Cfg.Defs new CfgField() { Name = "path", Type = "string" }, new CfgField() { Name = "comment", Type = "string" }, new CfgField() { Name = "tags", Type = "string" }, + new CfgField() { Name = "orientation", Type = "string" }, } }) { @@ -698,7 +700,8 @@ namespace Luban.Job.Cfg.Defs "", "", (b.GetField("tags") as DString).Value.Trim(), - false + false, + DefUtil.ParseOrientation((b.GetField("orientation") as DString).Value) )).ToList(), }; this._beans.Add(curBean); @@ -728,7 +731,8 @@ namespace Luban.Job.Cfg.Defs "convert", "comment", "tags", - "default" + "default", + "orientation", }; private static readonly List _fieldRequireAttrs = new List { "name", "type" }; @@ -753,12 +757,14 @@ namespace Luban.Job.Cfg.Defs XmlUtil.GetOptionalAttribute(e, "value_validator"), XmlUtil.GetOptionalAttribute(e, "validator"), XmlUtil.GetOptionalAttribute(e, "tags"), - false + false, + DefUtil.ParseOrientation(XmlUtil.GetOptionalAttribute(e, "orientation")) ); } private Field CreateField(string name, string type, string index, string sep, bool isMultiRow, string group, string resource, string converter, - string comment, string refs, string path, string range, string keyValidator, string valueValidator, string validator, string tags, bool ignoreNameValidation) + string comment, string refs, string path, string range, string keyValidator, string valueValidator, string validator, string tags, + bool ignoreNameValidation, bool isRowOrient) { var f = new CfgField() { @@ -772,6 +778,7 @@ namespace Luban.Job.Cfg.Defs Comment = comment, Tags = tags, IgnoreNameValidation = ignoreNameValidation, + IsRowOrient = isRowOrient, }; // 字段与table的默认组不一样。 diff --git a/src/Luban.Job.Cfg/Source/Defs/DefField.cs b/src/Luban.Job.Cfg/Source/Defs/DefField.cs index bd3590f..c194871 100644 --- a/src/Luban.Job.Cfg/Source/Defs/DefField.cs +++ b/src/Luban.Job.Cfg/Source/Defs/DefField.cs @@ -154,6 +154,8 @@ namespace Luban.Job.Cfg.Defs public DType DefalutDtypeValue { get; private set; } + public bool IsRowOrient { get; } + public DefField(DefTypeBase host, CfgField f, int idOffset) : base(host, f, idOffset) { Index = f.Index; @@ -166,6 +168,7 @@ namespace Luban.Job.Cfg.Defs this.Groups = f.Groups; this.RawDefine = f; this.DefaultValue = f.DefaultValue; + this.IsRowOrient = f.IsRowOrient; } public override void Compile() diff --git a/src/Luban.Job.Cfg/Source/RawDefs/CfgField.cs b/src/Luban.Job.Cfg/Source/RawDefs/CfgField.cs index 12dad12..58b0583 100644 --- a/src/Luban.Job.Cfg/Source/RawDefs/CfgField.cs +++ b/src/Luban.Job.Cfg/Source/RawDefs/CfgField.cs @@ -25,6 +25,8 @@ namespace Luban.Job.Cfg.RawDefs public string DefaultValue { get; set; } = ""; + public bool IsRowOrient { get; set; } = false; + public List Groups { get; set; } = new List(); public List KeyValidators { get; } = new List(); diff --git a/src/Luban.Job.Common/Source/Utils/DefUtil.cs b/src/Luban.Job.Common/Source/Utils/DefUtil.cs index ccf0390..6d040a4 100644 --- a/src/Luban.Job.Common/Source/Utils/DefUtil.cs +++ b/src/Luban.Job.Common/Source/Utils/DefUtil.cs @@ -46,5 +46,21 @@ namespace Luban.Job.Common.Utils return (s[..sepIndex], ParseAttrs(s[(sepIndex + 1)..])); } } + + public static bool ParseOrientation(string value) + { + switch (value.Trim()) + { + case "": + case "r": + case "row": return true; + case "c": + case "column": return false; + default: + { + throw new Exception($"orientation 属性值只能为row|r|column|c"); + } + } + } } }