亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

用Open XML SDK讀取Excel

系統 1610 0
Excel的便捷使得其在非開發人員的辦公中非常流行,而Excel確實也提供了很多有用的功能。很多時候我們還需要以Excel為數據源來進行處理或者將Excel作為 模板 來生成一些 報表 。在Open XML SDK沒出來之前,我們大多采用引用Office類庫的方法來做處理,但這樣的操作顯得很麻煩。而Open XML SDK的出現,讓我們可以以一個很自然的方式來處理這些數據,本文我們就一起了解一下如何使用Open XML SDK來通過LINQ to XML的方式操作Excel。

這些代碼是建立在Open XML SDK CTP 2基礎上的,使用前請先下載Open XML Format SDK 2.0。點擊 這里 下載。SDK默認會 安裝 在C:\Program Files (x86)\Open XML Format SDK\V2.0 (64bit)目錄下,lib子目錄下的DocumentFormat.OpenXml.dll必須被引用到項目中。

Excel也罷,word也罷,他們都是通過Open XML的標準來組織特定標記的。其實,你只要理解這些標記的含義,你可以不用任何 工具 自己來解析XML得到你想要的內容和格式。而Open XML SDK提供給我們的是更統一的解析方式。通過下邊傳統的DOM解析,你可以得到一個Excel的worksheet集合。
  1. public static List<String> GetSheets(String strFileName)

  2. {

  3. // Fill this collection with a list of all the sheets.

  4. List<String> sheets = new List<String>();



  5. using (SpreadsheetDocument xlPackage = SpreadsheetDocument.Open(strFileName, false))

  6. {

  7. WorkbookPart workbook = xlPackage.WorkbookPart;

  8. Stream workbookstr = workbook.GetStream();

  9. XmlDocument doc = new XmlDocument();

  10. doc.Load(workbookstr);



  11. XmlNamespaceManager nsManager = new XmlNamespaceManager(doc.NameTable);

  12. nsManager.AddNamespace("default", doc.DocumentElement.NamespaceURI);

  13. XmlNodeList nodelist = doc.SelectNodes("http://default:sheets/default:sheet", nsManager);



  14. foreach (XmlNode node in nodelist)

  15. {

  16. String sheetName = String.Empty;

  17. sheetName = node.Attributes["name"].Value;

  18. sheets.Add(sheetName);

  19. }

  20. }



  21. return sheets;

  22. }
復制代碼
對于每一個工作簿而言,Open XML Format SDK將它以不同對象之間的關系來組織。在下邊的圖中你可以看到這些內嵌的對象間的關系。需要說明的是,他們都代表在Excel中不同的應用,例如Columns,你可以通過它得到你的工作簿中的列。TablePart則列舉了在工作簿中以Table(可以理解為以數據表,具有過濾,排序,匯總等功能)方式展現的數據區域。



而我們可能更關心的是如何來得到行、列單元格內的值。當然,worksheet除了這些對象(關系)集合外,它也通過直觀的行(Row)、列(Cell)來組織內容區域。通過LINQ to XML我們可以很容易的通過Descendents來得到。
  1. IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.Descendants<Sheet>().Where(s => s.Name == strSheet);

  2. if (sheets.Count() == 0)

  3. {

  4. // The specified worksheet does not exist.

  5. return null;

  6. }



  7. WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheets.First().Id);

  8. Worksheet worksheet = worksheetPart.Worksheet;



  9. //Ignore row header

  10. IEnumerable<Row> rows = worksheet.Descendants<Row>();

  11. foreach (Row row in rows)

  12. {

  13. foreach (Cell cell in row)

  14. {

  15. ……

  16. }

  17. }
復制代碼
能夠對Row和Cell進行遍歷,這就容易多了。你可以很容易的取出某一行某一列,或者所有列的數據并輸出(當然,同等的道理,你也可以寫入),操作起來是不是很方便呢?但不要忘記了,你很難得到cell的值:cell.InnerText并不是在任何時候都有效的。對于s類型的列(SharedStringTable類型),它的值是 存儲 在子元素內的。
  1. public static String GetValue(Cell cell, SharedStringTablePart stringTablePart)

  2. {

  3. if (cell.ChildElements.Count == 0)

  4. return null;

  5. //get cell value

  6. String value = cell.CellValue.InnerText;

  7. //Look up real value from shared string table

  8. if ((cell.DataType != null) && (cell.DataType == CellValues.SharedString))

  9. value = stringTablePart.SharedStringTable

  10. .ChildElements[Int32.Parse(value)]

  11. .InnerText;

  12. return value;

  13. }
復制代碼
這時,你可以通過String columnValue = GetValue(cell, tablePart);的方式來取得單元格值。tablePart就是WorkbookPart.SharedStringTablePart,它存儲了所有以SharedStringTable方式存儲數據的子元素。

再擴展一下如果你想將一個Excel的工作簿以強類型展示,那該如何做呢?列明,每一個行代表一個對象元素,通過反射來來對對象賦值。請注意在工作簿中并不是每個列都能和你的類屬性對應的,所以必須判斷。當然,你也可以通過中間元素來產生映射擴展。
  1. //get SharedStringTablePart to get the cell value.

  2. SharedStringTablePart tablePart = document.WorkbookPart.SharedStringTablePart;

  3. //Column headers

  4. String[] cellHeaders = null;

  5. String[] cellValues = null;



  6. //Ignore row header

  7. IEnumerable<Row> rows = worksheet.Descendants<Row>();

  8. foreach (Row row in rows)

  9. {

  10. if (row.RowIndex == 1)

  11. {

  12. cellHeaders = new String[row.Count()];

  13. }

  14. cellValues = new String[row.Count()];

  15. int i = 0;



  16. foreach (Cell cell in row)

  17. {

  18. String columnValue = GetValue(cell, tablePart);



  19. //The first row is header

  20. if (row.RowIndex == 1)

  21. {

  22. cellHeaders = columnValue;

  23. }

  24. else

  25. {

  26. cellValues = columnValue;

  27. }

  28. i++;

  29. }

  30. if (row.RowIndex > 1)

  31. {

  32. products.Add(ProductConverter.Convert(cellValues, cellHeaders));

  33. }

  34. }
復制代碼
對最終的單元格值集合到Product對象的轉換,我們通過ProductConverter類來完成。在這里,你可以通過反射來完成,但枚舉出所有你可能用到的類型是你不得不面對的問題。
  1. foreach (PropertyInfo pi in product.GetType().GetProperties())

  2. {

  3. for (int i = 0; i < cellHeader.Length; i++)

  4. {

  5. if (pi.Name.Equals(cellHeader, StringComparison.OrdinalIgnoreCase))

  6. {

  7. //get property type

  8. String propertyType = pi.PropertyType.Name;

  9. switch (propertyType)

  10. {

  11. case "Int32":

  12. pi.SetValue(product, int.Parse(cellValues), null);

  13. break;

  14. case "DateTime":

  15. pi.SetValue(product, System.DateTime.Parse(cellValues), null);

  16. break;

  17. case "Decimal":

  18. pi.SetValue(product, Decimal.Parse(cellValues), null);

  19. break;

  20. case "Double":

  21. pi.SetValue(product, Double.Parse(cellValues), null);

  22. break;

  23. case "String":

  24. pi.SetValue(product, cellValues, null);

  25. break;

  26. }

  27. break;

  28. }

  29. }

  30. }
復制代碼
通過將數據展現到 UI 上,你可以驗證你的工作 是否成功:
  1. List<Product> products = SpreadSheetFunction.GetProducts(strFileName, "Products");

  2. this.dataGridView1.DataSource = products;
復制代碼


其實對于Excel中的Table可能更有意思。因為你可以通過它來實現過濾,排序,匯總,你會感覺它特別方便(起碼比Reporting Service來得快多了)。我們會再介紹如何通過更簡單的辦法來對Excel Table操作。(文/ Allan.

用Open XML SDK讀取Excel


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 一级欧美毛片成人免费视频 | 亚洲欧美国产另类视频 | 特级黄一级播放 | 亚洲欧美成人永久第一网站 | 亚洲欧美另类精品久久久 | 曰本女人一级毛片看一级毛 | 五月亭亭激情五月 | 一区二区三区无码高清视频 | 久久久久久久影院 | 亚洲精彩视频在线观看 | 一级爱爱片一级毛片-一毛 一级白嫩美女毛片免费 | 国产精品高清在线观看地址 | www.精品| 久久久国产精品福利免费 | 日韩毛片免费观看 | 久久香蕉国产线看免费 | 亚洲成人免费网站 | 久久久精品久久久久久久久久久 | 久久嫩草影院免费看夜色 | 色夜影院| 97看吧| 九九视频在线观看视频23 | 97欧美在线看欧美视频免费 | 成人激情免费视频 | 日韩精品中文字幕在线 | 久热官网 | 在线看欧美三级中文经典 | 亚洲国产综合网 | 欧美三级午夜理伦三级小说 | 热久久国产欧美一区二区精品 | 色偷偷成人网免费视频男人的天堂 | 久久香蕉久久 | 国产福利在线视频 | 亚洲最大免费视频网 | 午夜精品久久久久久久第一页 | 久久青草精品一区二区三区 | 伊人久久免费视频 | 奇米影音第四色 | 亚洲综合成人在线 | 毛茸茸free牲交| 性a爱片免费视频性 |