前言:前面的几篇文章简单的介绍了如何使用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中有很多种方式,这里就不赘述,本文主要介绍第二步。

  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() == )
  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 == )
  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, );
  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 = ;
  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 == )
  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. }

使用:

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

via: http://www.cnblogs.com/tewuapple/archive/2012/09/03/2668725.html

使用OpenXML将Excel内容读取到DataTable中的更多相关文章

  1. excel to datatable (c#用NPOI将excel文件内容读取到datatable数据表中)

    将excel文件内容读取到datatable数据表中,支持97-2003和2007两种版本的excel 1.第一种是根据excel文件路径读取excel并返回datatable /// <sum ...

  2. 将文件中的内容读取到map中,并排除不需要的关键字然后输出

  3. NPOI操作Excel导入DataTable中

    using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using System.Data; using System.IO; using NPOI.X ...

  4. 使用NPOI导入导出Excel(xls/xlsx)数据到DataTable中

    using System; using System.Collections.Generic; using System.Text; using System.IO; using NPOI.SS.Us ...

  5. winfrom 使用NPOI导入导出Excel(xls/xlsx)数据到DataTable中

    1.通过NUGET管理器下载nopi,在引入命令空间 using System; using System.Collections.Generic; using System.Text; using ...

  6. C# 实现复制Excel内容到DataGridview中

    业务要求:复制:将Excel内容复制到datagridview中 最终效果:复制Excel内容,点击datagridview中的某个单元格,顺着这个单元格自动填充自动增加行.偷懒了,没写填充在选择哪些 ...

  7. C#如何对DataTable中的数据进行条件搜索

    经常遇到将数据库中的数据读取到DataTable中的时候再次对DataTable进行条件筛选,下面的筛选的一个例子: DataRow[] dr = dt.Select("token = '& ...

  8. .NET小笔记-NPOI读取excel内容到DataTable

    下载比较新的NPOI组件支持excel2007以上的,把.dll添加引用 引入命名空间 using NPOI.HSSF.UserModel;using NPOI.SS.UserModel;using ...

  9. C# 读取Excel内容

    一.方法 1.OleD方法实现该功能. 2.本次随笔内容只包含读取Excel内容,并另存为. 二.代码 (1)找到文档代码 OpenFileDialog openFile = new OpenFile ...

随机推荐

  1. STM32固件库

    一.STM32固件库开发和传统寄存器开发方式的区别 二.CMSIS标准 CMSIS标准--Cortex Microcontroller Software Interface Standard,是ARM ...

  2. Visual Studio Code扩展

    Visual Studio Code扩展 注:本文提到的代码示例下载地址>How to create a simple extension for VS Code VS Code 是微软推出的一 ...

  3. jquery实现抽奖

    用jquery实现抽奖小程序   用jquery实现抽奖小程序 这些日子,到处都可以看到关于微信小程序的新闻或报到,在博客园中写关于微信小程序的也不少.但是今天我要说的不是微信小程序,而是用简单的jq ...

  4. ios开发之C语言第4天

    自增和自减运算 自增运算符 ++ 自增表达式 1>.前自增表达式.     int num = 1;     ++num; 2>.后自增表达式     int num = 1;     n ...

  5. 【转载】JavaEE权限管理分析

    JavaEE权限管理分析 一.背景 在 Web 应用开发中,安全一直是非常重要的一个方面.安全虽然属于应用的非功能性需求,但是应该在应用开发的初期就考虑进来.如果在应用开发的后期才考虑安全的问题,就可 ...

  6. asp.net 登陆后在ashx处理程序中获取不到Session

    登录后存储Session,另一个页面Ajax请求 ashx页面,发现无法获取到Session,Session is NULL  使用“IReadOnlySessionState”这个接口就可以

  7. win7+ubuntu双系统安装攻略

    一1.下载分区软件,为ubuntu安装分出一个区 2.磁盘管理器,选中该区,右键,删除卷,该区变为绿色,成为空闲区 3.成功 二为ubunt添加开机导引项 1,安装好easybcd2.0后,启动软件: ...

  8. QEvent整理归纳:140种类型,29个继承类,7个函数,3种事件来源

    140种事件类型: QEvent::None QEvent::AccessibilityDescription QEvent::AccessibilityHelp QEvent::Accessibil ...

  9. TeeChart的最小步长和最大步长

    /// <summary> /// 坐标轴的最大步长 /// </summary> public double MajorStep { get { return axis.Ca ...

  10. 《大数据Spark企业级实战 》

    基本信息 作者: Spark亚太研究院   王家林 丛书名:决胜大数据时代Spark全系列书籍 出版社:电子工业出版社 ISBN:9787121247446 上架时间:2015-1-6 出版日期:20 ...