From e7066c579b60fffd7b38bc2e4bacc81ab4aba491 Mon Sep 17 00:00:00 2001 From: walon Date: Fri, 6 Aug 2021 19:06:25 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E7=89=B9=E6=80=A7=E3=80=91=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E4=B8=8D=E9=99=90=E5=B1=82=E6=AC=A1=E7=9A=84=E5=B5=8C?= =?UTF-8?q?=E5=A5=97=20multi=5Frows=EF=BC=8C=E5=8D=B3multi=5Frows=E7=9A=84?= =?UTF-8?q?list=EF=BC=8C=E6=AF=8F=E8=A1=8C=E5=85=83=E7=B4=A0=E6=9C=AC?= =?UTF-8?q?=E8=BA=AB=E5=8F=88=E5=8F=AF=E4=BB=A5=E5=8C=85=E5=90=ABmulti=5Fr?= =?UTF-8?q?ows=E7=9A=84=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DataCreators/ExcelNamedRowDataCreator.cs | 35 ++-- .../DataSources/Excel/ExcelDataSource.cs | 2 +- .../Source/DataSources/Excel/Sheet.cs | 170 ++++++++---------- 3 files changed, 92 insertions(+), 115 deletions(-) diff --git a/src/Luban.Job.Cfg/Source/DataCreators/ExcelNamedRowDataCreator.cs b/src/Luban.Job.Cfg/Source/DataCreators/ExcelNamedRowDataCreator.cs index 56391e0..dcd15e2 100644 --- a/src/Luban.Job.Cfg/Source/DataCreators/ExcelNamedRowDataCreator.cs +++ b/src/Luban.Job.Cfg/Source/DataCreators/ExcelNamedRowDataCreator.cs @@ -90,7 +90,7 @@ namespace Luban.Job.Cfg.DataCreators throw new NotSupportedException(); } - public bool IsContainerAndElementNotSepType(TType type) + private static bool IsContainerAndElementNotSepType(TType type) { switch (type) { @@ -119,14 +119,15 @@ namespace Luban.Job.Cfg.DataCreators { try { - if (f.IsMultiRow) - { - list.Add(f.CType.Apply(this, row.GetSubTitleNamedRowOfMultiRows(fname), f.IsMultiRow, f.IsNullable)); - } - else - { - list.Add(f.CType.Apply(this, row.GetSubTitleNamedRow(fname), f.IsMultiRow /* 肯定是 false */, f.IsNullable)); - } + list.Add(f.CType.Apply(this, row.GetSubTitleNamedRow(fname), f.IsMultiRow, f.IsNullable)); + //if (f.IsMultiRow) + //{ + // list.Add(f.CType.Apply(this, row.GetSubTitleNamedRowOfMultiRows(fname), f.IsMultiRow, f.IsNullable)); + //} + //else + //{ + // list.Add(f.CType.Apply(this, row.GetSubTitleNamedRow(fname), f.IsMultiRow /* 肯定是 false */, f.IsNullable)); + //} } catch (DataCreateException dce) { @@ -246,7 +247,8 @@ namespace Luban.Job.Cfg.DataCreators // 如果是多行数据,以当前title为title,每行读入一个element if (multirow) { - foreach (var sub in row.GenerateSubNameRows()) + //foreach (var sub in row.GenerateSubNameRows(elementType)) + foreach (var sub in Sheet.NamedRow.CreateMultiRowNamedRow(row.Rows, row.SelfTitle, elementType)) { list.Add(this.Accept(elementType, sub, false, false)); } @@ -255,17 +257,18 @@ namespace Luban.Job.Cfg.DataCreators { // 如果不是多行,并且定义了子标题的话。以一个子标题所占的列,读入一个数据 - foreach (var sub in row.SelfTitle.SubTitleList) - { - list.Add(this.Accept(elementType, new Sheet.NamedRow(sub, row.Rows), false, false)); - } + //foreach (var sub in row.SelfTitle.SubTitleList) + //{ + // list.Add(this.Accept(elementType, new Sheet.NamedRow(sub, row.Rows), false, false)); + //} + throw new NotSupportedException("只有multi_rows=1的list,bean类型才允许有子title"); } return list; } public DType Accept(TArray type, Sheet.NamedRow x, bool multirow, bool nullable) { - if (!(type.ElementType is TBean bean)) + if (type.ElementType is not TBean bean) { throw new Exception($"NamedRow 只支持 bean 类型的容器"); } @@ -277,7 +280,7 @@ namespace Luban.Job.Cfg.DataCreators public DType Accept(TList type, Sheet.NamedRow x, bool multirow, bool nullable) { - if (!(type.ElementType is TBean bean)) + if (type.ElementType is not TBean bean) { throw new Exception($"NamedRow 只支持 bean 类型的容器"); } diff --git a/src/Luban.Job.Cfg/Source/DataSources/Excel/ExcelDataSource.cs b/src/Luban.Job.Cfg/Source/DataSources/Excel/ExcelDataSource.cs index 1e1254a..f53656e 100644 --- a/src/Luban.Job.Cfg/Source/DataSources/Excel/ExcelDataSource.cs +++ b/src/Luban.Job.Cfg/Source/DataSources/Excel/ExcelDataSource.cs @@ -117,7 +117,7 @@ namespace Luban.Job.Cfg.DataSources.Excel { try { - datas.AddRange(sheet.ReadMulti(type, ((DefBean)type.Bean).IsMultiRow)); + datas.AddRange(sheet.ReadMulti(type)); } 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 fec5b6d..f87717a 100644 --- a/src/Luban.Job.Cfg/Source/DataSources/Excel/Sheet.cs +++ b/src/Luban.Job.Cfg/Source/DataSources/Excel/Sheet.cs @@ -1,6 +1,8 @@ using ExcelDataReader; using Luban.Job.Cfg.DataCreators; using Luban.Job.Cfg.Datas; +using Luban.Job.Cfg.Defs; +using Luban.Job.Cfg.RawDefs; using Luban.Job.Cfg.TypeVisitors; using Luban.Job.Cfg.Utils; using Luban.Job.Common.Types; @@ -103,6 +105,60 @@ namespace Luban.Job.Cfg.DataSources.Excel public class NamedRow { + public static IEnumerable CreateMultiRowNamedRow(List> 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 NamedRow(title, row); + } + } + else + { + List notMultiRowFields = bean.Bean.HierarchyFields.Select(f => (DefField)f).Where(f => !f.IsMultiRow).ToList(); + List> 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); + })) + { + if (recordRows == null) + { + recordRows = new List>(); + } + recordRows.Add(row); + } + else + { + if (recordRows != null) + { + yield return new NamedRow(title, recordRows); + } + recordRows = new List>(); + recordRows.Add(row); + } + } + if (recordRows != null) + { + yield return new NamedRow(title, recordRows); + } + } + } + public Title SelfTitle { get; } public List> Rows { get; } @@ -156,20 +212,20 @@ namespace Luban.Job.Cfg.DataSources.Excel } } - public NamedRow GetSubTitleNamedRow(string name) - { - Title title = this.Titles[name]; - CheckEmptySinceSecondRow(name, title.FromIndex, title.ToIndex); - return new NamedRow(title, this.Rows[0]); - } + //public NamedRow GetSubTitleNamedRow(string name) + //{ + // Title title = this.Titles[name]; + // CheckEmptySinceSecondRow(name, title.FromIndex, title.ToIndex); + // return new NamedRow(title, this.Rows[0]); + //} - public NamedRow GetSubTitleNamedRowOfMultiRows(string name) + public NamedRow GetSubTitleNamedRow(string name) { Title title = Titles[name]; return new NamedRow(title, this.Rows); } - public IEnumerable GenerateSubNameRows() + public IEnumerable GenerateSubNameRows(TBean bean) { foreach (var row in Rows) { @@ -301,7 +357,7 @@ namespace Luban.Job.Cfg.DataSources.Excel return true; } - private string GetRowTag(List row) + private static string GetRowTag(List row) { if (row.Count == 0) { @@ -531,15 +587,14 @@ namespace Luban.Job.Cfg.DataSources.Excel } - - public static bool IsBlankRow(List row) + private static bool IsBlankRow(List row) { // 第一列被策划用于表示是否注释掉此行 // 忽略此列是否空白 return row.GetRange(1, row.Count - 1).All(c => c.Value == null || (c.Value is string s && string.IsNullOrWhiteSpace(s))); } - public static bool IsBlankRow(List row, int fromIndex, int toIndex) + private static bool IsBlankRow(List row, int fromIndex, int toIndex) { for (int i = Math.Max(1, fromIndex), n = Math.Min(toIndex, row.Count - 1); i <= n; i++) { @@ -552,94 +607,13 @@ namespace Luban.Job.Cfg.DataSources.Excel return true; } - private List GetNextRecordRow() + public IEnumerable ReadMulti(TBean type) { - while (curReadIndex < _rowColumns.Count) + foreach (var recordNamedRow in NamedRow.CreateMultiRowNamedRow(this._rowColumns, this._rootTitle, type)) { - var row = _rowColumns[curReadIndex++]; - if (IsBlankRow(row)) - { - continue; - } - - return row; - } - return null; - } - - private bool HasNotMainKey(List row) - { - return string.IsNullOrWhiteSpace(row[1].Value?.ToString()); - } - - private List> GetNextRecordRows() - { - List> rows = null; - while (curReadIndex < _rowColumns.Count) - { - var row = _rowColumns[curReadIndex++]; - if (IsBlankRow(row)) - { - continue; - } - - if (rows == null) - { - rows = new List>() { row }; - } - else - { - if (HasNotMainKey(row)) - { - rows.Add(row); - } - else - { - --curReadIndex; - return rows; - } - } - } - return rows; - } - - - - public List ReadMulti(TBean type, bool enableMultiRowRecord) - { - var datas = new List(); - - for (Record data; (data = ReadOne(type, enableMultiRowRecord)) != null;) - { - datas.Add(data); - } - return datas; - } - - private int curReadIndex = 0; - public Record ReadOne(TBean type, bool enableMultiRowRecord) - { - if (!enableMultiRowRecord) - { - List row = GetNextRecordRow(); - if (row == null) - { - return null; - } - bool isTest = DataUtil.IsTestTag(GetRowTag(row)); - var data = (DBean)ExcelNamedRowDataCreator.Ins.ReadExcel(new NamedRow(_rootTitle, row), type); - return new Record(data, RawUrl, isTest); - } - else - { - List> rows = GetNextRecordRows(); - if (rows == null) - { - return null; - } - bool isTest = DataUtil.IsTestTag(GetRowTag(rows[0])); - var data = (DBean)ExcelNamedRowDataCreator.Ins.ReadExcel(new NamedRow(_rootTitle, rows), type); - return new Record(data, RawUrl, isTest); + bool isTest = DataUtil.IsTestTag(GetRowTag(recordNamedRow.Rows[0])); + var data = (DBean)ExcelNamedRowDataCreator.Ins.ReadExcel(recordNamedRow, type); + yield return new Record(data, RawUrl, isTest); } } }