Java EasyExcel讀寫excel如何解決poi讀取大文件內(nèi)存溢出問題
問題
以前項(xiàng)目使用 poi 讀寫 excel,但是 excel 中的數(shù)據(jù)量太大的話,用 poi 讀取時(shí)就會(huì)導(dǎo)致 OOM 異常,這是因?yàn)?poi 在讀取數(shù)據(jù)時(shí),是將全部數(shù)據(jù)一次性都加載到內(nèi)存中。
如何解決
使用EasyExcel,以下是使用示例。
使用示例
pom
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.3</version>
</dependency>監(jiān)聽器
public class ProductListener extends AnalysisEventListener<Product> {
private static final int BATCH_COUNT = 1000;
private final List<Product> list = new ArrayList<>();
private int totalCount;
public ProductListener() {}
@Override
public void invoke(Product product, AnalysisContext analysisContext) {
list.add(product);
if(list.size() >= BATCH_COUNT){
saveData();
list.clear();
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
saveData();
System.out.printf("數(shù)據(jù)同步完成,總數(shù)量為:%s%n",totalCount);
}
public void saveData(){
if(!list.isEmpty()){
for (Product product : list) {
insertIgnore(product);
}
}
}
public void insertIgnore(Product product) {
try {
// 執(zhí)行數(shù)據(jù)庫操作
System.out.println(product.getName());
++totalCount;
} catch (Exception e) {
e.printStackTrace();
}
}
}實(shí)體類
public class Product {
private Long id;
@ExcelProperty("name")
private String name;
@ExcelProperty("quantity")
private Long quantity;
@ExcelProperty("desc")
private String desc;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getQuantity() {
return quantity;
}
public void setQuantity(Long quantity) {
this.quantity = quantity;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}讀寫方法
public class MyEasyExcel {
public static void read(String filePath) {
try (InputStream inputStream = Files.newInputStream(Paths.get(filePath))) {
EasyExcel.read(inputStream, Product.class, new ProductListener())
.sheet()
.doRead();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void write(List<Product> data, String filePath) {
try (OutputStream outputStream = Files.newOutputStream(Paths.get(filePath))) {
ExcelWriterBuilder writerBuilder = EasyExcel.write(outputStream, Product.class);
writerBuilder.sheet("Data").doWrite(data);
} catch (Exception e) {
// 處理異常
}
}
}測(cè)試類
class MyEasyExcelTest {
@Test
void read() {
String filePath = "C:\\Users\\XXX\\Desktop\\excel.xlsx";
MyEasyExcel.read(filePath);
}
@Test
void write() {
List<Product> products = new ArrayList<>();
Product product = new Product();
product.setId(1L);
product.setName("qwe");
product.setDesc("abc");
product.setQuantity(1342L);
products.add(product);
String filePath = "C:\\Users\\XXX\\Desktop\\excel.xlsx";
MyEasyExcel.write(products, filePath);
}
}總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot集成Redis—使用RedisRepositories詳解
這篇文章主要介紹了SpringBoot集成Redis—使用RedisRepositories詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
Java 中文字符按Unicode排序的實(shí)現(xiàn)方法
這篇文章主要介紹了Java 中文字符按Unicode排序的實(shí)現(xiàn)方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-10-10
Spring boot學(xué)習(xí)教程之快速入門篇
這篇文章主要給大家介紹了關(guān)于Spring boot的相關(guān)資料,本文屬于基礎(chǔ)入門教程,對(duì)各位學(xué)習(xí)Spring boot的新手們具有一定的參考學(xué)習(xí)價(jià)值,,要的朋友們下面來一起看看吧。2017-04-04
使用spring aop統(tǒng)一處理異常和打印日志方式
這篇文章主要介紹了使用spring aop統(tǒng)一處理異常和打印日志方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06

