在实际的开发中,我们可能需要读写word或者Excel的内容,在我开发的项目中,需要读取Excel的内容,并将相对应的内容存储到数据库中,这里简单跟大家分享一下,希望能够帮助一些人。

  我相信在读写word和Excel文件时,大家普遍会遇到的一个问题就是,针对office2003以前的版本和2003以后的版本的兼容性问题,在这个问题上,我也是纠结了很久,最后,通过一个简单的技巧解决了,下边,给大家贴出源码供大家参考。

        Stream stream = null;
            IWorkbook workbook = null;
            ISheet sheet = null;//上边这几行都是固定格式,如果你不深究,急着就行
            try 
            {
         //重点是这个try、catch。可以仔细观察,两个workbook和sheet的创建和读取是不一样的,07年以后的版本使用XSSFWorkbook和XSSFSheet,03年以前的使用HSSFWorkbook和HSSFSheet
         //创建和读取。我在这里使用了try、catch的方法区分,但是有些人会使用if来判断文件的后缀名,我觉得这种方式不保险,因为office文件的后缀名我们可以手动修改的。
stream
= new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); workbook = new XSSFWorkbook(stream); sheet = (XSSFSheet)workbook.GetSheetAt(0); } catch { stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); workbook = new HSSFWorkbook(stream); sheet = (HSSFSheet)workbook.GetSheetAt(0); }

   到这里,我们完成了文件的读取和空工作表的创建。那么下面的问题就是,在读取Excel表格的时候,我们会关注标题行的顺序问题以及标题行字段多少的问题。很多人都会制作一个导入的模板,这个模板制作的比较严格,就是标题行的顺序要固定,标题行有多少列也要固定,这在实际应用中比较麻烦,因为我们实际应用中可能有些需要导入的数据时从别的系统导出来的,这样就可能导致标题行的顺序和列数都不固定,遇到这样的问题,我们需要能够灵活处理。我给出我的代码:

            ArrayList AL = new ArrayList();//创建一个集合,用来存放Excel的标题
            int CellsCount = sheet.GetRow(0).Cells.Count;//获得这个表的第一行的列数,也就是标题行的列数
            for (int i = 0; i<CellsCount; i++)//将标题行的每一列存储到集合中
            {
                AL.Add(sheet.GetRow(0).GetCell(i).StringCellValue);
            }
            IRow row = null;
            ICell cell = null;
            for (int i = 1; i <= sheet.LastRowNum; i++)//从标题行一下,也就是第二行开始遍历此表
            {
         //try/catch 来处理07版office之后与之前的版本问题
                //try
                //{
                //    row = (XSSFRow) sheet.GetRow(i);//读取第i行
                //}
                //catch (Exception)
                //{
                //    row = (HSSFRow) sheet.GetRow(i);
                //}

                //之前采用try。catch 来进行版本的判断,后期发现这种判断虽然能够解决问题,但比较麻烦
                //后期在工作中发现了新的方法,这里跟大家说一下。
                //由于前边已经对sheet进行版本判断,因此它的类型已经确定,所以在这里我们使用C#关键字Dynamic来处理
                //代码会简单很多,而且也不会跑异常
                row = (Dynamic) sheet.GetRow(i);
                ArrayList arr = new ArrayList();
                for (int j = 0; j<CellsCount; j++)
                {
          //try/catch 来处理07版office之后与之前的版本问题
                    //try
                    //{
                    //    cell = (XSSFCell) row.GetCell(j);//读取第i行的第j列
                    //}
                    //catch (Exception)
                    //{
                    //    cell = (HSSFCell) row.GetCell(j);
                    //}

                    cell = (Dynamic) row.GetCell(j);
                    if (cell == null)//这句话的意思就是,遇到当前列为空的时候,继续遍历。因为我们的Excel表格有单元格是没有数据或者不存在的,这也解决了单元格的列数不固定问题。
                    {
                        continue;
                    }
                    string data = "";
                    try
                    {
                        data = row.GetCell(j).ToString().Trim();//把当前单元格的内容赋给string字符串。
                    }
                    catch { }
            //CellType是一个枚举类型(Unknown = -1,Numeric = 0,String = 1,Formula = 2,Blank = 3,Boolean = 4, Error = 5,)
            //对时间格式(2015.12.5、2015/12/5、2015-12-5等)的处理,我这里只对时间格式做了处理,其他都当做string来处理
                    if (cell.CellType == CellType.Numeric)
                    {
                        try
                        {
                            short format = cell.CellStyle.DataFormat;
                            if (format == 14 || format == 31 || format == 57 || format == 58)
                            {
                                DateTime date = cell.DateCellValue;
                                data = date.ToString("yyy-MM-dd");
                            }
                        }
                        catch { }
                    }
                    string data2 = "";
                    try
                    {
                        data2 = AL[j].ToString().Trim();//读取第j列的标题
                    }
                    catch { }
                    // Global.Global.ShowMessage(""+ row.GetCell(j));
                    switch (data2)//用switch、case来解决标题咧顺序不固定问题。
                    {
               case:"程序中的字段"
                ....
            }       
            ...
            //最后,记得关闭文件流

   这里我们就完成了对Excel表格内容的读取,并且把相应的内容赋给了我们的字段。最后在实际操作的时候,我们还需要注意一点,就是Excel内容本身也有格式,什么文本啊、货币啊这些格式,那么在我们这个处理过程中,除了你日期列你需要把它设置成日期格式外,其它的都用常规。

  也算是写完了,希望对大家有点帮助,我没有贴全部的代码啊,只是一些关键代码。

posted on 2017-08-12 10:14  振仔仔  阅读(2423)  评论(0编辑  收藏  举报