ExcelDataReader插件的使用
程序员文章站
2022-11-01 18:54:06
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); }
推荐阅读
-
使用php://input接收数据流(还有多个参数的解决办法)
-
长期使用中型Access数据库的一点经验_PHP教程
-
ThinkPHP3.1新特性之G方法的使用
-
spring mvc使用@InitBinder标签对表单数据绑定的方法
-
Java~反射的API文档使用(利用反射创建对象、反射私有构造方法、反射私有属性、反射私有方法)
-
python队列通信:rabbitMQ的使用(实例讲解)
-
SpringBoot项目中使用AOP的方法
-
PHP使用Redis长连接的方法详解
-
jquery的each(callback) 怎么使用?会实现什么样的效果?
-
MultiValueMap的使用 (Map之一个Key存多个Value的MultiValueMap(一个键多个值))