前言
在遇到大数据量excel,50MB大小或数百万级别的数据读取时,使用常用的POI容易导致读取时内存溢出或者cpu飙升。
本文讨论的是针对xlsx格式的excel文件上传,采用com.monitorjbl.xlsx.StreamingReader 。什么是StreamReader?
StreamReader 是 java.io 包中的一个类,用于读取字符流的高级类。它继承自 Reader 类,可以以字符为单位读取文件中的数据。
StreamReader的主要功能?
- 以字符为单位读取文件中的数据
- 提供了多种读取方法,如read()、readLine()等
- 可以指定字符编码,以适应不同类型的文件
StreamReader的优势?
- 简化了文件读取的过程,提供了高层次的读取方法可以处理不同类型的文件,如文本文件、CSV文件等
- 可以读取大型文件,节省内存空间
注:StreamReader只能用遍历形式读取数据
Sheet sheet = wk.getSheetAt(0); //遍历所有的行 for (Row row : sheet) { System.out.println("开始遍历第" + row.getRowNum() + "行数据:"); //遍历所有的列 for (Cell cell : row) { System.out.print(cell.getStringCellValue() + " "); } System.out.println(" "); }
案例步骤
1、导入文件前端接口
Controller.java
/**
* 导入文件前端接口
*/
@PostMapping("/importData")
@ResponseBody
public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception {
// 开始时间
Long begin = new Date().getTime();
// excel转换为List集合(约30s~40s)
List<TpInstallationMaintenanceLabelDetailed> tpInstallationMaintenanceLabelDetailedList = largeFilesUtils.importExcelLargeFile(file, updateSupport);
// 结束时间
Long end = new Date().getTime();
// 数据导入(约30s)
String message = importInstallationMaintenanceLabelDetailed(tpInstallationMaintenanceLabelDetailedList, updateSupport);
// 总用时(约60s~70s)
message = message +"<br/>数据转换花费时间 : "+(end - begin) / 1000 + " s" ;
// 返回
return AjaxResult.success(message);
}
2、Excel数据转为List
largeFilesUtils.java
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.monitorjbl.xlsx.StreamingReader;
import co