项目中多次用到对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.DLL | NPOI.XSSF | Excel 2007(xlsx)格式读写库 | 
| NPOI.OOXML.DLL | NPOI.XWPF | Word 2007(docx)格式读写库 | 
| NPOI.OpenXml4Net.DLL | NPOI.OpenXml4Net | OpenXml底层zip包读写库 | 
| NPOI.OpenXmlFormats.DLL | NPOI.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的上多了一个选择,还是那句话,没有什么好与不好,只能说是在特定的情况下选择更加适合的方式。
更多资料:
原文:http://blog.csdn.net/lfsfxytgb9_lyg/article/details/43058331