java解析excel,poi和easyExcel

本文对比了Java中解析Excel的两种方法:poi和easyExcel。poi虽然功能强大,但在处理大数据时易导致内存溢出。而easyExcel在解决内存问题的同时,提供了简洁的API,使得操作Excel更加高效。

做项目遇到上传excel并解析excel内容组装成结构话json,网上查了很多方法,做了poi和easyExcel两个方法的对比

两者都可以解析excel文件,但是两个也有不同:

一、poi

官方说明:https://poi.apache.org/components/index.html

A、03版excel和07版excel:
1)03版excel最多65536行,最大列数是256列,07版excel没有限制;
2)文件后缀不同,一个xls,另一个是xlsx。
3)poi引入依赖不同
B、写

(1)03版excel和07版excel生成的性能对比
程序执行前时间戳作为begin,程序执行后时间戳作为end,然后后者减前者除以1000并且double强转获得秒级时间。 最后可以看到后者的效率比前者低,但后者没有最多65536行限制。
(2)为了让XSSFWorkbook效率提升,用了Workbook第三个实现类SXSSFWorkbook。
这个实现原理其实就是兼顾前面两者的优点,默认把100条记录保存到内存中,然后写入临时excel文件,即一种流式计算,但需要注意的是一定要在程序结束的时候清除临时文件。
C、读

3.8版本的POI对excel的导出操作,一般只使用HSSFWorkbook以及 SXSSFWorkbook, HSSFWorkbook用来处理较少的数据量, SXSSFWorkbook用来处理大数据量以及超大数据量的导出,只是 SXSSFWorkbook只支持.xlsx格式,不支持.xls格式。

poi易造成内存溢出

我们通过分析其源码,得出其实现步骤为通过InputStream一行行读取到TreeMap类型的HSSFRow结构体中,因此当数据量大时就会造成内存溢出。poi会将内容全部加载到内存

poi的使用:

1、引入jar包

<dependencies>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>3.15</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooml</artifactId>
        <version>3.15</version>
    </dependency>
    <dependency> 
        <groupId>org.apache.poi</groupId> 
        <artifactId>poi-ooml-schemas</artifactId> 
        <version>3.15</version> 
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-scratchpad</artifactId>
        <version>3.11</version>
    </dependency>
    <dependency>
        <groupId>cn.opencsv</groupId>
        <artifactId>opencsv</artifactId>
        <version>5.4</version>
    </dependency>
    <dependency>
        <groupId>org.apache.xmlbeans</groupId>
        <artifactId>xmlbeans</artifactId>
        <version>2.6.0</version>
    </dependency>
</dependencies>

2、使用代码

private void parseExcelFile(MultipartFile file){

        Workbook workbook = WorkbookFactory.create(file.getInputStream);

        if (workbook == null) {

                return;

        }

        for (int sheetNum = 0; sheetNum< workbook.getNumberOfSheets(); sheetNum++){

                Sheet sheet = workbook.getSheetAt(sheetNum);

                if(sheet ==null) {

                        return;

                }

                int firstRowNum = sheet.getFirstRowNum();

                int lastRowNum = sheet.getLastRowNum();

                for (int rowNum = firstRowNum;rowNum <= lastRowNum; rowNum++){

                        Row row = sheet.getRow(rowNum);

                        String a = row.getCell(0).getStringCellValue();

                        //业务逻辑

                }

        }

}

二、easyExcel

该技术是在Apache poi基础上封装和优化,主要是为了解决poi耗内存问题,并且提供了较好的api使用,从而实现不需要太多代码操作excel文件。

1、引入jar包

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.1.2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>4.1.2</version>
</dependency>
<dependency>
    <groupId>com.opencsv</groupId>
    <artifactId>opencsv</artifactId>
    <version>5.4</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-scratchpad</artifactId>
    <version>3.11</version>
</dependency>
<dependency>
    <groupId>org.apache.xmlbeans</groupId>
    <artifactId>xmlbeans</artifactId>
    <version>3.1.0</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.0.5</version>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-compress</artifactId>
    <version>1.19</version>
</dependency>

2、使用

//excel中每行的列可以写成对象

public class ExcelData{

        @ExcelProperty(value='姓名',index=0)        

        private String name;

        @ExcelProperty(value='年龄',index=1)        

        private String age;

        public String getName(){

                return name;

        }

public String getName(){

                return name;

        }

public String setName(String name){

               this.name=name;

        }

public String getAge(){

                return age;

        }

public String setAge(String age){

               this.age=age;

        }

}

private void parseExcelFile(MultipartFile file){

       ExcelListener excelListener = new ExcelListener();

       EasyExcel.read(file.getInputStream, ExcelData.class,excelListener).sheet().doRead();

}

注意事项:

1、poi和poi-ooxml、poi-ooxml-schemas版本号要一致,否则会报错

2、在项目中由poi换到easyExcel,响应时间减少明显

三、总结

在这里插入图片描述

在这里插入图片描述 

POI存在的问题:非常的消耗内存;
EasyExcel 遇到再大的excel都不会出现内存溢出的问题,能够将一个原本3M的excel文件,POI来操作将会占用内存100M,使用EasyExcel降低到几KB,使用起来更加简单。
poi读 1、创建xsshworkbook/hssfworkbook (inputstream in)
2、读取sheet
3、拿到当前sheet所有行row
4、通过当前行去拿到对应的单元格的值。
而easyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值