OpenXml方式读取Excel数据

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DocumentFormat.OpenXml.Packaging;
using System.Data;
using System.IO;
using DocumentFormat.OpenXml.Spreadsheet;
using MS.Internal.Hashing.WindowsBase;

namespace OpenXML
{
    class GetDatatable
    {

        #region
        public DataTable GetExcelData(string filePath)
        {
            return  ReadExcel("Sheet1", filePath);
        }
        /// 
        /// 按照给定的Excel流组织成Datatable
        /// 
        /// Excel文件流
        /// 须要读取的Sheet
        /// 组织好的DataTable
        private DataTable ReadExcel(string sheetName, string filePath)
        {
            using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(filePath, false))//从指定的路径读取数据到spreadsheetDocument
            {
                IEnumerable sheets = spreadsheetDocument.WorkbookPart.Workbook.Descendants().Where(s => s.Name == sheetName);

                if (sheets.Count() == 0)//判断workbook中是否存在sheetName
                {
                    return null;
                }

                SharedStringTable sharedStringTable = spreadsheetDocument.WorkbookPart.SharedStringTablePart.SharedStringTable;
                //获取spreadsheetDocument中共享的数据,猜想:SharedStringTablePart指Excel中的用户数据。

                WorksheetPart worksheetPart = (WorksheetPart)spreadsheetDocument.WorkbookPart.GetPartById(sheets.First().Id);
                //工作表

                IEnumerable rows = worksheetPart.Worksheet.Descendants();//获得Excel中得数据行

                DataTable dataTable = new DataTable();
                //因为须要将数据导入到DataTable中,所以我们假定Excel的第一行是列名,从第二行开端是行数据
                foreach (Row row in rows)
                {
                    if (row.RowIndex == 1)
                    {//Excel第一行动列名
                        GetDataColumn(row, sharedStringTable, ref dataTable);
                    }
                    GetDataRow(row, sharedStringTable, ref dataTable);//Excel第二行同时为DataTable的第一行数据
                }
                return dataTable;
            }
        }

        /// 
        /// 构建DataTable的列
        /// 
        /// OpenXML定义的Row对象
        /// 
        /// 须要返回的DataTable对象
        /// 
        public void GetDataColumn(Row row, SharedStringTable stringTable, ref DataTable dt)
        {
            DataColumn col = new DataColumn();
            Dictionary columnCount = new Dictionary();
            foreach (Cell cell in row)
            {
                string cellVal = GetValue(cell, stringTable);
                col = new DataColumn(cellVal);
                if (IsContainsColumn(dt, col.ColumnName))
                {
                    if (!columnCount.ContainsKey(col.ColumnName))
                        columnCount.Add(col.ColumnName, 0);
                    col.ColumnName = col.ColumnName + (columnCount[col.ColumnName]++);
                }
                dt.Columns.Add(col);
            }
        }
        /// 
        /// 构建DataTable的每一行数据,并返回该Datatable
        /// 
        /// OpenXML的行
        /// 
        /// DataTable
        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);
            }
        }


        /// 
        /// 获取单位格的值
        /// 
        /// 
        /// 
        /// 
        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;
        }
        /// 
        /// 判断网格是否存在列
        /// 
        /// 网格
        /// 列名
        /// 
        public bool IsContainsColumn(DataTable dt, string columnName)
        {
            if (dt == null || columnName == null)
            {
                return false;
            }
            return dt.Columns.Contains(columnName);
        }
        #endregion

    }
}

你可能感兴趣的:(C#)