2012-01-18 50 views
3

我使用OpenXML打開電子表格並循環顯示電子表格的行。我有一個linq查詢返回一行內的所有單元格。 linq查詢直接從MSDN上的演示中剝離。OpenXML linq查詢

IEnumerable<String> textValues = 
    from cell in row.Descendants<Cell>() 
    where cell.CellValue != null 
    select (cell.DataType != null 
      && cell.DataType.HasValue 
      && cell.DataType == CellValues.SharedString 
      ? sharedString.ChildElements[int.Parse(cell.CellValue.InnerText)].InnerText 
      : cell.CellValue.InnerText); 

LINQ查詢在返回擁有一個值,所有細胞是偉大的,但它不返回沒有值細胞。這反過來使得不可能確定哪個單元是哪個單元。讓我再解釋一下。假設我們的電子表格中有三列:名稱,SSN和地址。這個linq查詢的工作方式是隻返回給定行有值的單元格。因此,如果有一行數據具有「John」,「」,「173 Sycamore」,那麼linq查詢只會在枚舉中返回「John」和「173 Sycamore」,這反過來使我無法知道是否「173 Sycamore」是SSN或地址字段。

讓我在這裏重申:我需要的是返回所有單元格,而不僅僅是包含值的單元格。我試圖以我能想到的每種方式來搗亂linq查詢,但我沒有任何運氣(即 - 刪除where子句不是訣竅)。任何幫助,將不勝感激。謝謝!

回答

4

OpenXML標準沒有爲沒有數據的單元定義佔位符。換句話說,它在XML中的底層存儲是稀疏的。你可以工作,這一輪的兩種方法之一:

  1. 創建所有「可用」或「可能」小區的名單(可能通過使用CROSS JOIN類型的操作),那麼「左」加入到row.Descendants<Cell>()集合查看單元格引用是否具有值
  2. 利用第三方工具(如ClosedXMLEPPlus)作爲Excel數據的包裝並查詢它們的接口,這些接口對開發人員更友好。
+0

我已經使用ClosedXML導出Excel電子表格,但我並不認爲它確實導入了。可以?今天早些時候,我甚至在他們的網站上看到了真正的快速,並沒有看到它的確如此(儘管這是一個非常快速的樣子)。不過我會看看EPPlus。實際上,每次我嘗試使用OpenXML做任何事情時,我都驚訝於看起來應該簡單的事情,但最終卻變成了一切! – Jagd 2012-01-19 00:22:08

+0

如果通過導入您的意思是讀取和寫入數據的能力,那麼OpenXML和EPPlus都可以這樣做。我同意試圖直接使用OpenXML是一件痛苦的事情,但是使用上述工具和Document Explorer作爲SDK的一部分,它比我們以前必須處理的舊的COM Interop要好得多! – jklemmack 2012-01-19 02:31:33

+1

ClosedXML效果很好。我希望從第一個開始就使用它,而不是使用OpenXML。再次感謝! – Jagd 2012-01-23 18:19:18

3

隨着ClosedXML:

var wb = new XLWorkbook("YourWorkbook.xlsx"); 
var ws = wb.Worksheet("YourWorksheetName"); 
var range = ws.RangeUsed(); 
foreach(var row in range.Rows()) 
{ 
    // Do something with the row... 
    // ... 

    foreach(var cell in row.Cells()) 
    { 
     // Now do something with every cell in the row 
     // ... 
    } 
} 
+0

太棒了!我會檢查出來的! – Jagd 2012-01-19 15:07:15

+0

啊,這麼多努力凝結了這麼少的代碼。謝謝 – 2016-03-10 11:15:57

0

我推薦的一種方式是填補所有空細胞與空白數據,因此他們會通過你的LINQ語句返回。請參閱answer瞭解如何操作。