Java EasyExcel读写excel如何解决poi读取大文件内存溢出问题
作者:编程经验分享
这篇文章主要介绍了Java EasyExcel读写excel如何解决poi读取大文件内存溢出问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
问题
以前项目使用 poi 读写 excel,但是 excel 中的数据量太大的话,用 poi 读取时就会导致 OOM 异常,这是因为 poi 在读取数据时,是将全部数据一次性都加载到内存中。
如何解决
使用EasyExcel,以下是使用示例。
使用示例
pom
<dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>3.1.3</version> </dependency>
监听器
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("数据同步完成,总数量为:%s%n",totalCount); } public void saveData(){ if(!list.isEmpty()){ for (Product product : list) { insertIgnore(product); } } } public void insertIgnore(Product product) { try { // 执行数据库操作 System.out.println(product.getName()); ++totalCount; } catch (Exception e) { e.printStackTrace(); } } }
实体类
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) { // 处理异常 } } }
测试类
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); } }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。