做项目遇到上传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时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。
本文对比了Java中解析Excel的两种方法:poi和easyExcel。poi虽然功能强大,但在处理大数据时易导致内存溢出。而easyExcel在解决内存问题的同时,提供了简洁的API,使得操作Excel更加高效。
1276

被折叠的 条评论
为什么被折叠?



