欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ExcelDataReader插件的使用

程序员文章站 2022-05-18 14:21:50
NPOI插件的弊端 刚来公司的时候公司软件导入导出操作都使用微软的office组件来实现,大家应该都知道这个组件有很大的弊端,就是运行主机上面必须安装office组件才可进行使用,不然无法进行导入导出操作,之前公司软件部门给的做法就是直接让客户安装Office就可以解决。 我接手后知道这个弊端,将插 ......

npoi插件的弊端

刚来公司的时候公司软件导入导出操作都使用微软的office组件来实现,大家应该都知道这个组件有很大的弊端,就是运行主机上面必须安装office组件才可进行使用,不然无法进行导入导出操作,之前公司软件部门给的做法就是直接让客户安装office就可以解决。

我接手后知道这个弊端,将插件进行了替换,使用网上比较流行的npoi插件,基本上很少出现关于软件导入导出数据的反馈。但由于之前的软件需求基本都是少量数据的导入导出,npoi都可以满足,现在新需求要求导入导出超过40w行的数据,npoi插件就暴露出来弊端,在数据少的时候使用.xlsx的xffsworkbook类就可以实现,但是数据量超过某一个阀值,xffsworkbook就出现了异常,爆出内存溢出的消息,而且声明和访问时速度特别慢,感觉是组件内部在处理大数据文件时存在问题。

在网上查找发现npoi对于大数据的处理有一个sxssfworkbook,它是npoi专门来处理大数据文件的,我在使用过程中,当写入时,没问题可以使用,但是效率方面很差。可是在读取时,根本无法使用,因为它在使用过程中必须声明xffworkbook才可以,可是声明它的话就会遇到内存溢出问题。网上还有说直接使用xml形式来读取,但是xml格式需要自己去定义和解析,特别麻烦,故没有采用。

//声明处理.xlsx文件的方法(小文件)
iworkbook workbook=new xssfworkbook();

//声明处理.xlsx文件的方法(大文件)
iworkbook workbook=new xssfworkbook();
iworkbook wb=new sxssfworkbook(workbook);

exceldatareader插件

在处理读取.xlsx文件时,在nuget中发现了exceldatareader插件,在做了demo后,对于40w行的读取很方便,而且速度特别快。推荐大家使用。

            filestream fs = null;
            iexceldatareader excelreader = null;
            try
            {
                fs = new filestream(filename, filemode.open, fileaccess.read);
                excelreader = excelreaderfactory.createopenxmlreader(fs);
                int readindex = 0;
                int rowcount = excelreader.rowcount;                                                        //所有的行                
                datarow dr;
                object tempvalue;

                while (excelreader.read())
                {
                    dr = data.newrow();

                    if (readindex == startreadrowcount)
                    {
                        ++readindex;
                        continue;
                    }
                    
                    //读取excel中的头文件信息
                    if (readindex <startreadrowcount)
                    {
                        dr[0] = excelreader.getvalue(0).tostring();
                        tempvalue = excelreader.getvalue(1);
                        if (tempvalue==null)
                        {
                            dr[1] = dbnull.value;
                        }
                        else
                        {
                            dr[1] = excelreader.getvalue(1).tostring();
                        }
                        
                        dr[2] = dbnull.value;
                        dr[3] = dbnull.value;
                        dr[4] = dbnull.value;
                        dr[5] = dbnull.value;
                        dr[6] = dbnull.value;
                    }
                    else
                    {
                        dr[0] = excelreader.getvalue(0).tostring();
                        dr[1] = excelreader.getvalue(1).tostring();
                        dr[2] = convert.todouble(excelreader.getvalue(2));

                        tempvalue = excelreader.getvalue(3);
                        if (tempvalue == null)
                        {
                            dr[3] = dbnull.value;
                        }
                        else
                        {
                            dr[3] = convert.todouble(excelreader.getvalue(3));
                        }
                        dr[4] = convert.todouble(excelreader.getvalue(4));
                        dr[5] = convert.todouble(excelreader.getvalue(5));
                        dr[6] = convert.todouble(excelreader.getvalue(6));
                    }
                    data.rows.add(dr);
                    if (worker.cancellationpending)  // 如果用户取消则跳出处理数据代码 
                    {
                        e.cancel = true;
                        break;
                    }
                    worker.reportprogress(readindex * 100 / rowcount);//加载进度条 
                    ++readindex;
                }
                fs.close();
                fs.dispose();
                excelreader.close();
                excelreader.dispose();
                return data;
            }
            catch (exception ex)
            {
                if (worker.cancellationpending)  // 如果用户取消则跳出处理数据代码 
                {
                    e.cancel = true;
                }

                if (fs != null)
                {
                    fs.close();
                    fs.dispose();
                }

                if (excelreader != null)
                {
                    excelreader.close();
                    excelreader.dispose();
                }
                throw new exception("" + ex.message);
            }

插件下载地址:
https://www.nuget.org/packages/exceldatareader/3.0.0