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<
string,
int> columnCount =
new Dictionary<
string,
int>();
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 }