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


          前言:前面的几篇文章简单的介绍了如何使用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
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    vue长按事件
    video标签视频自动播放
    express路由的使用
    Java的堆栈和堆
    MongoDB建库db、建集合collection以及其他常用命令
    计算机网络基础-目录
    如何清除tomcat缓存
    tomcat/logs目录下各日志文件的解析
    在Windows系统和Linux服务器安装MongoDB和基本使用
    [转]/tomcat/conf/server.xml配置文件的源码解析
  • 原文地址:https://www.cnblogs.com/pszw/p/2259599.html
Copyright © 2020-2023  润新知