LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

读取Excel文件的两种方法

admin
2018年9月8日 18:51 本文热度 5441
第一种方法:传统方法,采用OleDB读取EXCEL文件,

优点:写法简单,缺点:服务器必须安有此组件才能用,不推荐使用
private DataSet GetConnect_DataSet2(string fileName) 
          { 
              DataSet myDataSet = new DataSet(); 
              //创建一个数据链接 
              string strCon = " Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source = " + fileName + ";Extended Properties=Excel 8.0"; 
              OleDbConnection myConn = new OleDbConnection(strCon); 
              string strCom = " SELECT * FROM [Sheet1$] "; 
              //try 
              //{ 
              myConn.Open(); 
              //打开数据链接,得到一个数据集 
              OleDbDataAdapter myCommand = new OleDbDataAdapter(strCom, myConn); 
              //创建一个 DataSet对象 
              myDataSet = new DataSet(); 
              //得到自己的DataSet对象 
              myCommand.Fill(myDataSet, "CodeTable"); 
              //关闭此数据链接 
              myConn.Close(); 
              //} 
              //catch (Exception ex) 
              //{ 
     
              //} 
              return myDataSet; 
          }

第二种方法:用第三方组件:NPOI组件,推荐使用此方法

先去官网:http://npoi.codeplex.com/下载需要引入dll(可以选择.net2.0或者.net4.0的dll),然后在网站中添加引用。

NPOI 是 POI 项目的 .NET 版本。POI是一个开源的Java读写Excel、WORD等微软OLE2组件文档的项目。

使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 WORD/EXCEL 文档进行读写。

NPOI采用的是Apache 2.0许可证(poi也是采用这个许可证),这意味着它可以被用于任何商业或非商业项目,你不用担心因为使用它而必须开放你自己的源代码,所以它对于很多从事业务系统开发的公司来说绝对是很不错的选择。

当然作为一个开源许可证,肯定也是有一些义务的,例如如果你在系统中使用NPOI,你必须保留NPOI中的所有声明信息。对于源代码的任何修改,必须做出明确的标识。
//config中配置的上传的Excel路径 
           static object basePath = ConfigurationManager.AppSettings["FilePath"]; 
           #region 读取Excel文件 
           /// <summary> 
           /// 读取Excel文件到table中 
           /// </summary> 
           /// <param name="filePath">excel文件路径</param> 
           /// <returns></returns> 
           public static DataTable ReadExcel(string fileName) 
           { 
               DataTable dt = new DataTable(); 
               string filePath = ""; 
               if (basePath != null) 
               { 
                   filePath = HostingEnvironment.MapPath((basePath.ToString() + fileName)); 
                   dt = ImportExcelFile(filePath); 
               } 
               //文件是否存在 
               if (System.IO.File.Exists(filePath)) 
               { 
     
               } 
               return dt; 
           } 
           public static DataTable ImportExcelFile(string filePath) 
           { 
               HSSFWorkbook hssfworkbook; 
               #region//初始化信息 
               try 
               { 
                   using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read)) 
                   { 
                       hssfworkbook = new HSSFWorkbook(file); 
                   } 
               } 
               catch (Exception e) 
               { 
                   throw e; 
               } 
               #endregion 
     
               NPOI.SS.UserModel.ISheet sheet = hssfworkbook.GetSheetAt(0); 
               System.Collections.IEnumerator rows = sheet.GetRowEnumerator(); 
               DataTable dt = new DataTable(); 
               rows.MoveNext(); 
               HSSFRow row = (HSSFRow)rows.Current; 
               for (int j = 0; j < (sheet.GetRow(0).LastCellNum); j++) 
               { 
                   //dt.Columns.Add(Convert.ToChar(((int)''A'') + j).ToString()); 
                   //将第一列作为列表头 
                   dt.Columns.Add(row.GetCell(j).ToString ()); 
               } 
               while (rows.MoveNext()) 
               { 
                    row = (HSSFRow)rows.Current; 
                   DataRow dr = dt.NewRow(); 
                   for (int i = 0; i < row.LastCellNum; i++) 
                   { 
                       NPOI.SS.UserModel.ICell cell = row.GetCell(i); 
                       if (cell == null) 
                       { 
                           dr[i] = null; 
                       } 
                       else 
                       { 
                           dr[i] = cell.ToString(); 
                       } 
                   } 
                   dt.Rows.Add(dr); 
               } 
               return dt; 
           } 
           #endregion

Npoi是对Excel(或者叫office比较合适)进行操作的一个类库框架,我们可以不再使用office提供的那个恶心的接口(速度慢)来操作了,我们对于office的操作解放了。现在最新版的应该是1.2.5.如果你安装了NuGet的话,可以很容易的获取。

因为Excel 2003极其以前的版本采用的底层代码和Excel 2007 及其以后的不同,所以对于这个分界点是需要我们注意的。为什么会出现这个分界点,大家想一下,现在微软的所有东西都在.net 架构之下,以前的Excel版本和这个架构肯定是不同的。

我们重点来说excel。毕竟这是在我们的工作中用的最多的一个,Excel包括 文件(file,在Npoi.net中称为workBook 工作簿)、工作表(sheet)以及里面的单元格,按照从大到小的分类就是文件中包含若干个sheet,每个sheet中包含很多单元格。这是Excel 的分类。

为了操作Excel,npoi.net当然也需要对应的类来对应不同的分类,其中

HSSFWorkbook对应的就是Excel文件  工作簿,

HSSFSheet对应的就是Excel中sheet 工作表,

HSSFCell对应的就是Excel的单元格,

HSSFRow对应的就是Excel的行。

有了这几个不同的类,我们就可以创建Excel文件,创建sheet,给sheet重命名或删除sheet,创建行,添加单元格,为单元格设置格式,我个人感觉其他的都很简单,唯独这个给单元格设置格式的做法很令人讨厌,没办法用的别人的,只能有苦自己承受了。

public class NpoiNet
    {
        public void CreateWorkBook()
        {
            string filePath = HttpContext.Current.Server.MapPath("~/npoi.xls");
            //表示一个文件流
            FileStream fileStream = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite);
            HSSFWorkbook workBook = new HSSFWorkbook();//相当于创建了一个内存中的Excel 只是还没有写到硬盘上
            try
            {
                /*按照约定在每个Excel文件中至少要包含一个sheet,如果没有任何sheet,打开Excel文件的时候会报错。
               在以前的npoi版本中,如果不是自己手动的创建一个sheet,npoi框架是不会自动创建一个的,但是在最新版的1.2.5中,
               我发现即使你忘记了创建sheet的操作,框架会自动创建一个sheet,当然如果你手动创建了一个sheet,则框架就不会
                自动的创建一个sheet,这就像构造函数,如果没有写任何一个,.Net会默认存在一个,但是你创建了一个构造函数,则
                 * 框架就不会自动创建了
                 * */
                workBook.CreateSheet("guozhiqi");//sheet的名称为guozhiqi
                workBook.CreateSheet();//sheet的名称为sheet1  从1开始命名
                workBook.CreateSheet("yuanjinzhou");
                workBook.CreateSheet();//这个sheet的名称应该为什么?答案是sheet3
                //创建了sheet 下面我们来创建单元格
                HSSFSheet sheetGuozhiqi = (HSSFSheet)workBook.GetSheet("guozhiqi");//获取到sheet名称为guozhiqi的那个工作簿
                //创建了工作簿 添加单元格之前首先要添加行
                //在这里请注意  行和列的下标都是从0开始的 而不是Excel文件中的1
                for (int i = 0; i <= 10; i++)
                {
                    sheetGuozhiqi.CreateRow(i);//创建了11行
                }
                //创建了行之后 就要在每个行中创建单元格
                //如果没有在之前创建行
                //  HSSFRow newRow = (HSSFRow)sheetGuozhiqi.GetRow(12);这是错误的 程序会报异常 这就告诉我们 如果行还没有创建
                //就不可以获取
                HSSFRow newRow = (HSSFRow)sheetGuozhiqi.GetRow(0);
                HSSFCell[] cells = new HSSFCell[11];
                //在第0行的位置创建单元格
                for (int i = 0; i <= 10; i++)
                {
                    cells[i] = (HSSFCell)newRow.CreateCell(i);//为第0行创建了10个单元格
                }
                //这里取得单元格的异常出现位置相同 就是如果没有创建就不要试图获取
                HSSFCell newCell = (HSSFCell)newRow.GetCell(0);//取得第0行第0个单元格
                //获取到了单元格 赋值 为了方便说明 我多获取几个单元格的值
                //Excel单元格有很多类型 例如字符串 数字 bool等类型,
                cells[0].SetCellValue(false);//赋值为bool型
                cells[1].SetCellValue(DateTime.Now);//赋值为日期型
                cells[2].SetCellValue(3.1415926);//赋值为double类型
                cells[3].SetCellValue("guozhiqi");//赋值为字符串guozhiqi
                //为单元格赋值以后 我们就要开始取值了
                bool cell0 = cells[0].BooleanCellValue;
               // string cell00 = cells[0].StringCellValue; 错误 这句话的意思就是说存储的时候是什么类型 就必须用对应的
                //取值方法取值
                DateTime dateTime = cells[1].DateCellValue;
                double cell2 = cells[2].NumericCellValue;
                string cell3 = cells[3].StringCellValue;
                //可以正常创建单元格 从单元格取值是远远不够的 还有就是客户可能会要求合并单元格  为单元格设置样式
                //合并单元格的操作不必要创建所有的行或列,只需要制定范围即可
                sheetGuozhiqi.AddMergedRegion(new NPOI.SS.Util.Region(1,1,20,20));//合并单元格
                HSSFCellStyle cellStyle = (HSSFCellStyle)workBook.CreateCellStyle();
                cellStyle.Alignment = HorizontalAlignment.CENTER;//居中显示
                cellStyle.FillBackgroundColor = 244;
                cellStyle.FillPattern = FillPatternType.BRICKS;//填充模式
                cellStyle.IsHidden = false;//单元格是否隐藏
                cellStyle.IsLocked = false;//单元格是否锁定
                cellStyle.VerticalAlignment = VerticalAlignment.CENTER;//垂直居中
               
                //设置单元格字体
                HSSFFont font =(HSSFFont) workBook.CreateFont();
                font.Color = 200;
                font.FontHeight = 18;//设置字体大小
                font.FontName = "黑体";//设置字体为黑体
                font.IsItalic = false;//是否是斜体
                font.IsStrikeout = true;//是否有中间线
                font.Underline = (byte)FontUnderlineType.DOUBLE;//设置下划线
                cellStyle.SetFont(font);
                //将设置好的样式应用到对应的单元格上 否则是没有效果的
                cells[0].CellStyle = cellStyle;
                if (!workBook.IsWriteProtected)
                {
                    workBook.Write(fileStream);
                }
            }
            catch (Exception ex)
            {
                HttpContext.Current.Response.Write(ex.Message+ex.Source+ex.StackTrace);
            }
            finally
            {
                if (fileStream != null)
                {
                    fileStream.Close();
                }
            }
        }
    }

总结,既然这篇博客是Npoi.net的总结,那么我不可能就是举了一个例子就算了事,毕竟博客园中园友们举得例子已经够多了,下面我就把在使用npoi.net会遇到的一些小问题总结一下。

  1. 在实例化了一个WorkBook之后,最好添加一个sheet,虽然在最新版的Npoi.net中自动添加了,但是遇到迁移到原来版本就会出现问题。所以我建议还是最少添加一个sheet
  2. 在从单元格取值时要注意单元格的类型,一定要用对应的类型的方法来取单元格中的对应类型的值,如果不确定,那只能是强制转换成为string类型,毕竟string类型是excel中其他类型都可以转换过来的
  3. 在获取sheet中的某一行或者某一行的某一个单元格的时候,还要注意就是一定要确保创建了该行,并且取单元格还要确保创建了单元格,否则会报Null reference not to object 这个我们经常会看到的异常信息。在外层一定要加上try捕获异常
  4. 合并单元格是sheet的工作,因此需要获取对应的sheet,然后调用其AddMergedRegion方法合并单元格,在合并单元格的时候,我们不需要确保该单元格已经存在或创建。
  5. 在为单元格设置样式的过程中,我们会发现所有和样式相关的类的创建都是通过workBook.Create(Font)..这种方式来执行的,我们不可以直接new一个类的实例。
  6. 如果前面的工作都已经做好,需要把内存中的excel表写到硬盘上时,需要调用 workBook.write()方法,传入一个文件流进行创建。在这里有可能会出现一个问题,就是你要创建的文件你已经打开了,这时程序就会出现异常, 因此我们在调试程序的时候一定要记得打开了excel文件以后要关闭
  7. 最后需要注意的就是文件流,在我们把excel写到硬盘上以后,要显式的调用其close()方法关闭文件流。因为如果不关闭文件流的话,以后就会出现无法重新创建该文件的错误,并且会提示 某文件正由另一进程使用,因此该进程无法访问此文件。

该文章在 2018/9/8 18:51:55 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved