首页 > 代码库 > C#解析Excel汇总

C#解析Excel汇总

    项目中多次用到对Excel的操作,想想有必要对这些方式、方法进行汇总,以便能够在整体上有个清晰的认识,本篇文章主要讨论使用C#对Excel操作、解析的三种方式:OleDb、Com组件、NPOI


1.OleDb

    该方法简单快速,能够操作高版本的Excel,缺点是不够灵活,只能对Excel进行简单的读写操作。在最开始接触编程的时候,便有所耳闻:Object Link andembed(对象连接与嵌入),其主要目的是为了兼容更多类型的数据源。是较底层化的操作,在使用上非常复杂,另外一个特点是可以直接使用SQL语句对Excel数据源进行操作:

   

<span style="white-space:pre">	</span>/// <summary>
        /// 从Excel中读取数据到DataTable的方法
        /// </summary>
        /// <param name="strSavePath">文件保存路径</param>
        /// <param name="strSheetName">Sheet名称</param>
        /// <returns></returns>
        protected DataTable ExcelToDataTable(string strSavePath, string strSheetName)
        {
            #region 读取文件Sheet,转换为DataTable
            string strConn;
			string strFileType = System.IO.Path.GetExtension(strSavePath);  
            if (string.IsNullOrEmpty(strFileType)) return null;
			
			if (strFileType == ".xls")  
                strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + strSavePath+ ";" + ";Extended Properties=\"Excel 8.0;HDR=YES;IMEX=1\"";  
            else 
                strConn = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + strSavePath+ ";" + ";Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\""; 
			
            OleDbConnection conn = new OleDbConnection(strConn);
            conn.Open();
            OleDbDataAdapter myCommand = new OleDbDataAdapter("select * from [" + strSheetName + "$]", strConn);
            DataSet myDataSet = new DataSet();
            try
            {
                myCommand.Fill(myDataSet, "ExcelInfo");
            }
            catch
            {
                throw new Exception("配置文件的Sheet名称配置错误!");
            }
            finally
            {
                if (conn.State == ConnectionState.Open)  
                {  
                    conn.Close();  
                    myCommand.Dispose();  
                    conn.Dispose();  
                }
            }
            DataTable table = myDataSet.Tables["ExcelInfo"].DefaultView.ToTable();
            return table;

            #endregion 读取文件Sheet,转换为DataTable
        }

2.Com组件

    非常灵活、完全的操作Excel,精确控制Excel文档的各种属性(储存格式、样式、内容、公式以及条件等),前提是电脑必须安装Excel,会启动Excel进程。程序需要添加引用:Microsoft.Office.Interop.Excel

    使用此方式对Excel的基本操作,可参考:C#操作Excel总结


3.NPOI

         顾名思义,NPOI是POI项目的.NET版本。POI是一个开源的Java读写Excel、Word等微软OLE2组件文档的项目。此种方式则避免了使用Com组件的缺点,不用在相应的环境机器上安装Office,同时也结合了操作灵活的特点,读取速度也相对较快。

    NPOI2.0主要组成:

    

Assembly名称模块/命名空间说明
NPOI.DLL
NPOI.POIFS
OLE2/ActiveX文档属性读写库
NPOI.DLL
NPOI.DDF
微软Office Drawing读写库
NPOI.DLL
NPOI.HPSF
OLE2/ActiveX文档读写库
NPOI.DLL
NPOI.HSSF
微软Excel BIFF(Excel 97-2003, doc)格式读写库
NPOI.DLL
NPOI.SS
Excel公用接口及Excel公式计算引擎
NPOI.DLL
NPOI.Util
基础类库,提供了很多实用功能,可用于其他读写文件格式项目的开发
NPOI.OOXML.DLLNPOI.XSSFExcel 2007(xlsx)格式读写库
NPOI.OOXML.DLLNPOI.XWPFWord 2007(docx)格式读写库
NPOI.OpenXml4Net.DLLNPOI.OpenXml4NetOpenXml底层zip包读写库
NPOI.OpenXmlFormats.DLLNPOI.OpenXmlFormats微软Office OpenXml对象关系库


        使用NPOI导入Excel如下:

<pre name="code" class="csharp">public static DataTable RenderFromExcel<T>(Stream excelFileStream) where T : new()
{
    using (excelFileStream)
    {
        using (IWorkbook workbook = new HSSFWorkbook(excelFileStream))
        {
            using (ISheet sheet = workbook.GetSheetAt(0))//取第一个表
            {
                DataTable table = new DataTable();
                IRow headerRow = sheet.GetRow(0);//第一行为标题行
                int cellCount = headerRow.LastCellNum;//LastCellNum = PhysicalNumberOfCells
                int rowCount = sheet.LastRowNum;//LastRowNum = PhysicalNumberOfRows - 1
                //定义存取DB字段名称的数组
                String[] strArrayHeader = new String[cellCount - headerRow.FirstCellNum];
                //定义数组所需用的索引值
                int intArrayIndex = 0;
                //handling header.得到Excel导入文件的标题行字符串数组
                for (int i = 0; i < strArrayHeader.Length; i++)
                {
                    strArrayHeader[intArrayIndex] = headerRow.GetCell(i).StringCellValue;
                    ++intArrayIndex;
                }
                //调用方法,将标题行文字描述转换为对应的属性名称
                strArrayHeader = ConfigOperater.QueryImportEntityProperty<T>(strArrayHeader);
                intArrayIndex = 0;
                for (int i = headerRow.FirstCellNum; i < cellCount; i++)
                {
                    //DataColumn column = new DataColumn(headerRow.GetCell(i).StringCellValue);
                    DataColumn column = new DataColumn(strArrayHeader[intArrayIndex]);
                    table.Columns.Add(column);
                    ++intArrayIndex;
                }
                for (int i = (sheet.FirstRowNum + 1); i <= rowCount; i++)
                {
                    IRow row = sheet.GetRow(i);
                    DataRow dataRow = table.NewRow();
                    if (row != null)
                    {
                        for (int j = row.FirstCellNum; j < cellCount; j++)
                        {
                            if (row.GetCell(j) != null)
                                dataRow[j] = GetCellValue(row.GetCell(j));
                        }
                    }
                    table.Rows.Add(dataRow);
                }
                return table;
            }
        }
    }
}



总结:

    在解析Excel上,三种方式各有千秋,其中NPOI更像是对前面两种方式的中和,让我们在操作Excel的上多了一个选择,还是那句话,没有什么好与不好,只能说是在特定的情况下选择更加适合的方式。


更多资料:

    C#操作Excel

       NPOI1.2教程

       C#读取Excel几种方法的体会




C#解析Excel汇总