使用OpenXML将Excel内容读取到DataTable中

View Code
  1          ///   <summary>
  2           ///  按照给定的Excel流组织成Datatable
  3           ///   </summary>
  4           ///   <param name="stream"> Excel文件流 </param>
  5           ///   <param name="sheetName"> 须要读取的Sheet </param>
  6           ///   <returns> 组织好的DataTable </returns>
  7           private DataTable ReadExcel( string sheetName, Stream stream)
  8         {
  9              using (SpreadsheetDocument document = SpreadsheetDocument.Open(stream,  false))
 10             { // 打开Stream
 11                  IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.Descendants<Sheet>().Where(s => s.Name == sheetName);
 12                  if (sheets.Count() ==  0)
 13                 { // 找出合适前提的sheet,没有则返回
 14                       return  null;
 15                 }
 16                 WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheets.First().Id);
 17                  // 获取Excel中共享数据
 18                  SharedStringTable stringTable = document.WorkbookPart.SharedStringTablePart.SharedStringTable;
 19                 IEnumerable<Row> rows = worksheetPart.Worksheet.Descendants<Row>(); // 获得Excel中得数据行
 20                  DataTable dt =  new DataTable( " Excel ");
 21                  // 因为须要将数据导入到DataTable中,所以我们假定Excel的第一行是列名,从第二行开端是行数据
 22                   foreach (Row row  in rows)
 23                 {
 24                      if (row.RowIndex ==  1)
 25                     { // Excel第一行动列名
 26                          GetDataColumn(row, stringTable,  ref dt);
 27                     }
 28                     GetDataRow(row, stringTable,  ref dt); // Excel第二行同时为DataTable的第一行数据
 29                  }
 30                  return dt;
 31             }
 32         }
 33          ///   <summary>
 34           ///  构建DataTable的列
 35           ///   </summary>
 36           ///   <param name="row"> OpenXML定义的Row对象 </param>
 37           ///   <param name="stringTablePart"></param>
 38           ///   <param name="dt"> 须要返回的DataTable对象 </param>
 39           ///   <returns></returns>
 40           public  void GetDataColumn(Row row, SharedStringTable stringTable,  ref DataTable dt)
 41         {
 42             DataColumn col =  new DataColumn();
 43             Dictionary< stringint> columnCount =  new Dictionary< stringint>();
 44              foreach (Cell cell  in row)
 45             {
 46                  string cellVal = GetValue(cell, stringTable);
 47                 col =  new DataColumn(cellVal);
 48                  if (IsContainsColumn(dt, col.ColumnName))
 49                 {
 50                      if(!columnCount.ContainsKey(col.ColumnName))
 51                         columnCount.Add(col.ColumnName,  0);
 52                     col.ColumnName = col.ColumnName + (columnCount[col.ColumnName]++);
 53                 }
 54                 dt.Columns.Add(col);
 55             }
 56         }
 57          ///   <summary>
 58           ///  构建DataTable的每一行数据,并返回该Datatable
 59           ///   </summary>
 60           ///   <param name="row"> OpenXML的行 </param>
 61           ///   <param name="stringTablePart"></param>
 62           ///   <param name="dt"> DataTable </param>
 63           private  void GetDataRow(Row row, SharedStringTable stringTable,  ref DataTable dt)
 64         {
 65              //  读取算法:按行一一读取单位格,若是整行均是空数据
 66               //  则忽视改行(因为本人的工作内容不须要空行)-_-
 67              DataRow dr = dt.NewRow();
 68              int i =  0;
 69              int nullRowCount = i;
 70              foreach (Cell cell  in row)
 71             {
 72                  string cellVal = GetValue(cell, stringTable);
 73                  if (cellVal ==  string.Empty)
 74                 {
 75                     nullRowCount++;
 76                 }
 77                 dr[i] = cellVal;
 78                 i++;
 79             }
 80              if (nullRowCount != i)
 81             {
 82                 dt.Rows.Add(dr);
 83             }
 84         }
 85          ///   <summary>
 86           ///  获取单位格的值
 87           ///   </summary>
 88           ///   <param name="cell"></param>
 89           ///   <param name="stringTablePart"></param>
 90           ///   <returns></returns>
 91           private  string GetValue(Cell cell, SharedStringTable stringTable)
 92         {
 93              // 因为Excel的数据存储在SharedStringTable中,须要获取数据在SharedStringTable 中的索引
 94               string value =  string.Empty;
 95              try
 96             {
 97                  if (cell.ChildElements.Count ==  0)
 98                      return value;
 99                 value =  double.Parse(cell.CellValue.InnerText).ToString();
100                  if ((cell.DataType !=  null) && (cell.DataType == CellValues.SharedString))
101                 {
102                     value = stringTable.ChildElements[Int32.Parse(value)].InnerText;
103                 }
104             }
105              catch (Exception)
106             {
107                 value =  " N/A ";
108             }
109              return value;
110         }
111          ///   <summary>
112           ///  判断网格是否存在列
113           ///   </summary>
114           ///   <param name="dt"> 网格 </param>
115           ///   <param name="columnName"> 列名 </param>
116           ///   <returns></returns>
117           public  bool IsContainsColumn(DataTable dt,  string columnName)
118         {
119              if (dt ==  null || columnName ==  null)
120             {
121                  return  false;
122             }
123              return dt.Columns.Contains(columnName);
124         }

  前言:前面的几篇文章简单的介绍了如何使用OpenXML创建Excel文档。由于在平时的工作中需要经常使用到Excel的读写操作,简单的介绍下使用OpenXML读取Excel中得数据。当然使用OpenXML将数据读取成什么格式并不重要,本文仅仅介绍如何读取到DataTable中。

准备工作:

      1. Excel2007文档一个;

      2. OpenXML库:DocumentFormat.OpenXml.dll;

      3. Console项目一个,添加对OpenXML库和WindowsBase.dll的引用。

废话不多说,进入正题.

本文介绍的读取Excel的思路如下:

1. 将Excel加载到流Stream;

2. 使用OpenXML操作Stream,并写入DataTable中。

将文件加载到Stream中有很多种方式,这里就不赘述,本文主要介绍第二步。


使用:

 


View Code
1       FileStream fs =  new FileStream( @" D:\工作簿1.xlsx ", FileMode.Open, FileAccess.Read, FileShare.Read);
2         DataTable dt=ReadExcel( " Sheet1 ",fs);

你可能感兴趣的:(Datatable)