保姆级文件导入导出功能开发{POI || EasyExcel},还看不懂,你来咬我啊(二)

简介: 保姆级文件导入导出功能开发{POI || EasyExcel},还看不懂,你来咬我啊

这里我们再来看一下XSSFWorkbook写入数据的速度:


同样的数据量,用时6.633秒


20201117113326939.png


我们再来看一下如果是10万条数据的话,看看时间会是多少:


用时10.013秒,时间还能接受,毕竟在10万条数据的情况下


20201117113352623.png


既然这样我们也来分析一下XSSFWorkbook写入数据的流程,这里XSSFWorkbook和HSSFWorkbook一样,也是直接将数据写入内存中的,但是我们要知道因为XSSFWorkbook支持的数据量更多了,所以就必定会出现OOM即内存爆掉的情况,所以怎么办呢,这里我猜想的是,他是按照一定的量来将数据写入内存之中,就好比我是每10000条写入内存一次,那样的话,既能较快的写入数据,同时又能够支持比较大的数据量----这里也是我自己的猜想,感觉应该是这样.


大致可以通过下面的图来模拟:


20201117135132364.png


07版本进阶-SXSSFWorkbook


 @Test
    public void test07BigDataS()throws Exception{
        Long begin=System.currentTimeMillis();
        Workbook workbook=new SXSSFWorkbook();
        Sheet sheet=workbook.createSheet();
        for(int rownum=0;rownum<65536;rownum++){
            Row row=sheet.createRow(rownum);
            for(int cellnum=0;cellnum<10;cellnum++){
                Cell cell=row.createCell(cellnum);
                cell.setCellValue(cellnum);
            }
        }
        FileOutputStream fileOutputStream=new FileOutputStream(PATH+"test07BigDataS.xlsx");
        workbook.write(fileOutputStream);
        System.out.println("文件生成完毕");
        Long end=System.currentTimeMillis();
        System.out.println("共用时:"+(double)(end-begin)/1000+"秒");
    }

大家看名字就知道这个SXSSFWorkbook其实就是XSSFWorkbook的加强版(Super XSSFWorkbook),他的优点比较明显,既能够支持写入大量的数据,同时写入数据的速度也是非常的快.


这里我们上来就直接测试10万条数据玩玩:


20201117113413986.png


这速度跟闹着玩一样,10万条数据只要1.813秒,属实是牛逼


既然这样我们就更加要深挖一下,这玩意儿为啥这么快呢?


按照网上的说法,其实XSSFWorkbook写入数据的思路和XSSFWorkbook写入数据的思路差不多的,上面我们说过了XSSFWorkbook写入数据是每隔一个数据量进行输入,在已经向内存写入10000条数据后,程序就在进行等待,


等待着10000条数据写入文件之后,他才继续向内存里面写入数据.


SXSSFWorkbook的思路是这样,他一开始也是向内存里面写入数据,但是他有一个临界值默认是100.超过这个数据量之后的数据,他会自动在磁盘上创建一个临时文件,将数据写入该文件中,之后当内存中的数据写完之后就直接从临时文件中将数据拷贝过来,这样就大大的节省了时间,可以看到程序执行过程是没有断开的,是一直在执行的,意味着最耗时的部分一直在工作.所以才会使得SXSSFWorkbook既能写入大量的数据,同时又能够在非常快的时间内完成.


大致可以通过下面的图来模拟:


20201117135116215.png


其次就是SXSSFWorkbook与XSSFWorkbook有本质上的区别,这个我们可以通过他们引入的包名看出来:


20201117150408488.png


可以看到SXSSFWorkbook本质上是通过流来实现的,XSSFWorkbook则还是通过usermodel来实现的.显然流肯定是更快一点的.


并且这个临时文件并不是直接显示在项目路径下的一般都是存储在与该路径类似的路径下:C:\Users\瓤瓤\AppData\Local\Temp


这是我写入数据时生成的临时文件:


文件名一般都是以POI开头


20201117150150484.png


2.5-POI数据读取操作


03版本-HSSFWorkbook:

@Test
public void test03Read()throws Exception{
    //引入输入文件流
    FileInputStream fileInputStream=new FileInputStream(PATH+"test03BigData.xls");
    //创建工作簿
    Workbook workbook=new HSSFWorkbook(fileInputStream);
    //通过索引创建工作表
    Sheet sheet=workbook.getSheetAt(0);
    //通过索引获取行
    Row row=sheet.getRow(0);
    //通过索引获取单元格
    Cell cell=row.getCell(0);
    //打印单元格内容
    System.out.println(cell.getNumericCellValue());
}

这是最简单的读写操作流程.并且其中的工作表,行,单元格都是通过索引来获取,除了索引,POI还为我们提供了其他的获取方法,下面我们来详细说明一下.


获取工作表:


20201117201853405.png


第一种就是直接通过工作表的表名来进行获取,第二种就是直接通过工作簿内工作表的索引来进行获取.


获取行就是只能通过索引来获取


剩下的就是获取单元格了:


20201117201908175.png


第一种也是直接通过索引来进行获取,第二种只不是多加了一层的判断语句,这个我们可以点进源码里面看一下:


20201117201908302.png


主要有这三个


RETURN_NULL_AND_BLANK


英文解释: Missing cells are returned as null, Blank cells are returned as normal


缺失的单元格会返回为空,空的单元格就正常返回即可。


RETURN_BLANK_AS_NULL


英文解释: Missing cells are returned as null, as are blank cells


缺失的单元格返回为空,空的单元格也是如此。


RETURN_BLANK_AS_NULL


英文解释: A new, blank cell is created for missing cells. Blank cells are returned as normal


缺失的单元格不仅返回为空,同时还将为这个缺失的单元格创建一个新的单元格。空的单元格就正常返回即可。


其实这三种概念的理念差不多,基本上主要都是用来处理如果出现缺失的单元格情况时,可能会影响后续数据的读写操作。


07版本-XSSFWorkbook:

@Test
    public void test07Read()throws Exception{
        FileInputStream fileInputStream=new FileInputStream(PATH+"test07BigData.xlsx");
        Workbook workbook=new XSSFWorkbook(fileInputStream);
        Sheet sheet=workbook.getSheetAt(0);
        Row row=sheet.getRow(0);
        Cell cell[]=new Cell[4];
        cell[0]=row.getCell(0);
        cell[1]=row.getCell(1,Row.RETURN_NULL_AND_BLANK);
        cell[2]=row.getCell(2);
        cell[3]=row.getCell(3);
        for(int i=0;i<4;i++){
            System.out.println(cell[i]);
        }
    }

可以看到我们只是简单的修改了一下对象,其他的操作我们都是没有改的,所以我们在编写的时候,只需要注意我们版本对应的对象就行了.

相关文章
|
分布式计算 资源调度 Hadoop
Flink安装部署{单机模式、会话模式(集群部署)、yarn模式(包含hadoop3.1.3部署)}
Flink安装部署{单机模式、会话模式(集群部署)、yarn模式(包含hadoop3.1.3部署)}
755 0
Idea 项目结构不显示解决方案
Idea 项目结构不显示解决方案
1024 0
Idea 项目结构不显示解决方案
|
监控 Java easyexcel
面试官:POI大量数据读取内存溢出?如何解决?
【10月更文挑战第14天】 在处理大量数据时,使用Apache POI库读取Excel文件可能会导致内存溢出的问题。这是因为POI在读取Excel文件时,会将整个文档加载到内存中,如果文件过大,就会消耗大量内存。以下是一些解决这一问题的策略:
1485 1
|
11月前
|
SQL 数据库
UPDATE
【11月更文挑战第04天】
419 1
|
数据可视化 大数据 定位技术
GIS:开源webgl大数据地图类库整理
GIS:开源webgl大数据地图类库整理
463 0
|
机器学习/深度学习 运维 监控
高效运维:从自动化到智能化的演进之路
在当今信息技术飞速发展的时代,运维作为保障信息系统稳定、高效运行的重要环节,正经历着从传统手工操作向自动化、智能化转变的历史进程。本文将探讨自动化运维的实践价值与实施策略,阐述智能化运维的理念框架及其关键技术,并通过案例分析揭示这一演进路径如何助力企业提升运维效率、降低运营成本,并增强对复杂系统的掌控能力。通过深入剖析,本文旨在为读者呈现一幅从自动化迈向智能化的运维全景图,为寻求运维转型的企业提供参考与启示。
|
存储 人工智能 开发者
三文带你轻松上手鸿蒙的AI语音02-声音文件转文本
三文带你轻松上手鸿蒙的AI语音02-声音文件转文本
354 0
三文带你轻松上手鸿蒙的AI语音02-声音文件转文本
|
NoSQL Java Redis
[已解决]报异常java.io.InvalidClassException的解决方法|对象序列化实现Serializable会出现java.io.InvalidClassException的异常
[已解决]报异常java.io.InvalidClassException的解决方法|对象序列化实现Serializable会出现java.io.InvalidClassException的异常
|
安全 数据安全/隐私保护
支付系统之微信支付08-身份认证,公钥和私钥的含义,私钥自己有的,作为唯一的控制系统,私钥加密,公钥解密是为了身份认证
支付系统之微信支付08-身份认证,公钥和私钥的含义,私钥自己有的,作为唯一的控制系统,私钥加密,公钥解密是为了身份认证
|
监控 网络协议 关系型数据库
Keepalived集群软件高级使用(工作原理和状态通知)
Keepalived集群软件高级使用(工作原理和状态通知)