在解析(转换/映射)之前过滤LinqToExcel中的空白行

时间:2013-04-03 15:22:24

标签: c# .net excel transformation linq-to-excel

我正在使用LinqToExcel将Excel行映射到C#/ .NET项目中的对象。

我将验证代码放在我的转换函数中,这样它们不仅可以转换数据,还可以在缺少某些数据时警告用户。 例如:

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);
});

但是,我不希望这个验证是由Excel有时在底部添加的空行触发的(参见LinqToExcel blank rows)。

我的问题是我无法使用那里提到的解决方案,因为我在调用

之类的内容时无法访问原始行数据
excel.Worksheet<SomeType>("WorksheetName").Where(row => row.Any(cell => cell != null));

这是因为首先应用了转换,并且Where方法将应用于转换结果。

另外 - 在转换函数中,我无法访问行中的其他值,因此我无法检查它是否为单个空单元格(错误)或行是否为空。

在应用转换之前是否可以过滤掉空行?

2 个答案:

答案 0 :(得分:3)

您可以使用无类型工作表加入强类型工作表,然后使用无类型工作表查找完整空白行:

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();

答案 1 :(得分:0)

只有当整行为空时,是否有一些单元格为空?

例如,除了空白行之外,通常会始终填充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);