2013-04-03 147 views
1

我正在使用LinqToExcel將Excel行映射到C#/ .NET項目中的對象。在解析(轉換/映射)之前過濾LinqToExcel中的空行

我在我的轉換函數中添加了驗證代碼,這樣它們不僅可以轉換數據,還可以在缺少某些數據時警告用戶。 例子:

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

這是因爲應用第一的轉化和凡 - 當我不能訪問原始行數據方法將應用於轉換結果。

另外 - 在轉換函數中,我無法訪問行中的其他值,所以我無法檢查它是單個空單元(錯誤)還是行完全是空的。

在應用轉換之前是否可以過濾掉空行?

+0

的另一個原因是它'excel.Worksheet (「WorksheetName 「).Where(row => row.Any(cell => cell!= null));'不起作用的是LinqToExcel不支持子查詢(異常消息:VisitSubQueryExpression方法未實現) –

回答

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); 
+0

我想過這個選項,但忘記填寫單個單元格可能是用戶的錯誤。 我想過濾*完全*爲空的行,並且轉換方法無法執行此操作,因爲它們只有關於正在轉換的單元的信息。 –

+0

然後唯一的方法是包含一個Where子句來確認每個單元格是空白的。 – Paul

+0

問題是,轉換是在Where子句可以調用之前完成的。在應用轉換之前添加一個過濾器到LinqToExcel來篩選它們可能會有用嗎? –

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