使用OpenXML将Excel内容读取到DataTable中
2011-11-22 23:32 ps_zw 阅读(1402) 评论(0) 编辑 收藏 举报前言:前面的几篇文章简单的介绍了如何使用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中有很多种方式,这里就不赘述,本文主要介绍第二步。
源码如下:
/// <summary> /// 根据给定的Excel流组织成Datatable /// </summary> /// <param name="stream">Excel文件流</param> /// <param name="sheetName">需要读取的Sheet</param> /// <returns>组织好的DataTable</returns> private DataTable ReadExcel(string sheetName,Stream stream) { using (SpreadsheetDocument document = SpreadsheetDocument.Open(stream, false)) {//打开Stream IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.Descendants<Sheet>().Where(s => s.Name == sheetName); if (sheets.Count() == 0) {//找出符合条件的sheet,没有则返回 return null; } WorksheetPart worksheetPart = (WorksheetPart)workbookPart.GetPartById(sheets.First().Id); //获取Excel中共享数据 SharedStringTable stringTable = document.WorkbookPart.SharedStringTablePart.SharedStringTable; IEnumerable<Row> rows = worksheetPart.Worksheet.Descendants<Row>();//得到Excel中得数据行 DataTable dt = new DataTable("Excel"); //因为需要将数据导入到DataTable中,所以我们假定Excel的第一行是列名,从第二行开始是行数据 foreach (Row row in rows) { if (row.RowIndex == 1) {//Excel第一行为列名 GetDataColumn(row, stringTable, ref dt); } GetDataRow(row, stringTable, ref dt);//Excel第二行同时为DataTable的第一行数据 } return dt; } } /// <summary> /// 构建DataTable的列 /// </summary> /// <param name="row">OpenXML定义的Row对象</param> /// <param name="stringTablePart"></param> /// <param name="dt">需要返回的DataTable对象</param> /// <returns></returns> public void GetDataColumn(Row row, SharedStringTable stringTable, ref DataTable dt) { DataColumn col = new DataColumn(); foreach (Cell cell in row) { string cellVal = GetValue(cell, stringTable); col = new DataColumn(cellVal); dt.Columns.Add(col); } } /// <summary> /// 构建DataTable的每一行数据,并返回该Datatable /// </summary> /// <param name="row">OpenXML的行</param> /// <param name="stringTablePart"></param> /// <param name="dt">DataTable</param> private void GetDataRow(Row row, SharedStringTable stringTable, ref DataTable dt) { // 读取算法:按行逐一读取单元格,如果整行均是空数据 // 则忽略改行(因为本人的工作内容不需要空行)-_- DataRow dr = dt.NewRow(); int i = 0; int nullRowCount = i; foreach (Cell cell in row) { string cellVal = GetValue(cell, stringTable); if (cellVal == string.Empty) { nullRowCount++; } dr[i] = cellVal; i++; } if (nullRowCount != i) { dt.Rows.Add(dr); } } } /// <summary> /// 获取单元格的值 /// </summary> /// <param name="cell"></param> /// <param name="stringTablePart"></param> /// <returns></returns> private string GetValue(Cell cell, SharedStringTable stringTable) { //由于Excel的数据存储在SharedStringTable中,需要获取数据在SharedStringTable 中的索引 string value = string.Empty; try { if (cell.ChildElements.Count == 0) return value; value = double.Parse(cell.CellValue.InnerText).ToString(); if ((cell.DataType != null) && (cell.DataType == CellValues.SharedString)) { value = stringTable.ChildElements[Int32.Parse(value)].InnerText; } } catch (Exception) { value = "N/A"; } return value; }
作者:ps_zw
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.