在parsing(转换/映射)之前,过滤LinqToExcel中的空白行
我正在使用LinqToExcel将Excel行映射到C#/ .NET项目中的对象。
我将validation代码放在我的转换函数中,这样它们不仅可以转换数据,还可以在缺less某些数据时警告用户。 例:
excel.AddTransformation<PaymentObject>(x => x.PaymentPeriod, cellvalue => { if (cellvalue.Length == 0) { throw new Exception(String.Format(Errors.EmptyField, ColumnNames.PaymentPeriod, ColumnNames.EmployeeNumber, lastCheckedEmployeeNumber)); } return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(cellvalue); });
但是,我不希望这个validation是由Excel有时在底部添加的空行触发的(请参阅LinqToExcel空白行 )。
我的问题是,我不能使用在那里提到的解决scheme,因为我不能访问原始行数据时调用类似的东西
excel.Worksheet<SomeType>("WorksheetName").Where(row => row.Any(cell => cell != null));
这是因为首先应用转换,并将Where-method应用于转换结果。
另外 – 在转换函数中我没有访问行中的其他值,所以我不能检查它是一个单一的空单元格(错误)或行是完全空的。
是否有可能在应用转换之前过滤出空行?
您可以将强types的工作表join一个无types的工作表,然后使用无types的工作表来查找总空白行:
List<T> onlyNonBlankRows = _queryFactory.Worksheet<T>(firstWorksheetWithColumnHeaders) // calling ToList here is workaround to avoid Remotion.Data.Linq.Parsing.ParserException for Select((item,index) => ...) - "This overload of the method 'System.Linq.Queryable.Select' is currently not supported, but you can register your own parser if needed." .ToList() .Select((typedRow, index) => new { typedRow, index }) // Join the worksheet to an untyped projection of the same worksheet so that we can find totally blank rows .Join( _queryFactory.Worksheet(firstWorksheetWithColumnHeaders) // calling ToList here is workaround to avoid Remotion.Data.Linq.Parsing.ParserException for Select((item,index) => ...) .ToList() .Select( (untypedRow, indexForUntypedRow) => new { untypedRow, indexForUntypedRow }), // join on row index - row 1 matches row 1 etc arg => arg.index, arg => arg.indexForUntypedRow, (a, b) => new { a.index, a.typedRow, b.untypedRow }) // Exclude rows where all cells are empty .Where(x => x.untypedRow.Any(cell => cell.Value != DBNull.Value)) .Select(joined => joined.typedRow).ToList();
有没有只有整行是空白的单元格是空的?
例如,通常会有一个Id列,除了空白行之外,它总是被填充。 如果是这种情况,那么下面的查询应该适合你。
//assuming Id cell is only blank when the whole row is blank excel.WorkSheet<PaymentObject>().Where(x => x.Id != ""); //the Id cell might be null instead of blank, so use this Where clause instead excel.WorkSheet<PaymentObject>().Where(x => x.Id != null);