为解决大数据量的excel文档导入导出存在的内存泄露问题,可使用EasyExcel实现excel文档的解析和生成。
配置
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.6</version></dependency>
使用
excel导出
- 代码示例
- Customer.java(vo) ```java package org.polaris.easyexcel.vo;
public class Customer {
private int index;private String company;private String type;private int cash;private String from;private String others;public Customer(int index, String company, String type, int cash, String from, String others) {this.index = index;this.company = company;this.type = type;this.cash = cash;this.from = from;this.others = others;}public int getIndex() {return index;}public void setIndex(int index) {this.index = index;}public String getCompany() {return company;}public void setCompany(String company) {this.company = company;}public String getType() {return type;}public void setType(String type) {this.type = type;}public int getCash() {return cash;}public void setCash(int cash) {this.cash = cash;}public String getFrom() {return from;}public void setFrom(String from) {this.from = from;}public String getOthers() {return others;}public void setOthers(String others) {this.others = others;}@Overridepublic String toString() {return "Customer{" +"index=" + index +", company='" + company + '\'' +", type='" + type + '\'' +", cash=" + cash +", from='" + from + '\'' +", others='" + others + '\'' +'}';}
}
- **ExcelExportTest.java(测试类)**```javaimport com.alibaba.excel.EasyExcel;import com.alibaba.excel.ExcelWriter;import com.alibaba.excel.util.DateUtils;import com.alibaba.excel.write.metadata.WriteSheet;import org.junit.Test;import org.polaris.easyexcel.vo.Customer;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.util.*;public class ExcelExportTest{@Testpublic void excelExport() throws IOException{String templateFileName=ExcelExportTest.class.getClassLoader().getResource("template1.xls").getPath();BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("output"+ File.separator+"template1-out.xls"));ExcelWriter excelWriter=EasyExcel.write(bos).withTemplate(templateFileName).build();WriteSheet writeSheet=EasyExcel.writerSheet().build();List<Customer> customers=new ArrayList<>();customers.add(new Customer(1,"广州市越秀区东方红幼儿园","002",1000,"01","测试数据1"));customers.add(new Customer(2,"广州市越秀区东山幼儿园","002",2000,"01","测试数据2"));customers.add(new Customer(3,"广州市越秀区太阳升幼儿园","002",3000,"02","测试数据3"));customers.add(new Customer(4,"广州市越秀区红黑蓝幼儿园","005",4000,"01","测试数据4"));customers.add(new Customer(5,"广州市越秀区太阳幼儿园","007",5000,"02","测试数据5"));customers.add(new Customer(6,"广州市越秀区月亮幼儿园","002",6000,"01","测试数据6"));customers.add(new Customer(7,"广州市越秀区星星幼儿园","002",7000,"01","测试数据7"));customers.add(new Customer(8,"广州市越秀区星星幼儿园","008",8000,"01","测试数据8"));excelWriter.fill(customers,writeSheet);Map<String, Object> maps=new HashMap<>();maps.put("date",DateUtils.format(new Date(),DateUtils.DATE_FORMAT_19));excelWriter.fill(maps,writeSheet);excelWriter.finish();bos.flush();bos.close();}}
附件
- 模板:template1.xls
- 导出文件:template1-out.xls
excel解析
代码示例
- PayDetail.java(vo) ```java package org.polaris.easyexcel.vo;
/**
- 缴费明细
@author polaris 450733605@qq.com */ public class PayDetail {
private String id; private String name; private String address; private String area; private String paydate; private String singleAmt; private String totalAmt;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getArea() {
return area;
}
public void setArea(String area) {
this.area = area;
}
public String getPaydate() {
return paydate;
}
public void setPaydate(String paydate) {
this.paydate = paydate;
}
public String getSingleAmt() {
return singleAmt;
}
public void setSingleAmt(String singleAmt) {
this.singleAmt = singleAmt;
}
public String getTotalAmt() {
return totalAmt;
}
public void setTotalAmt(String totalAmt) {
this.totalAmt = totalAmt;
}
@Override public String toString() {
return "PayDetail{" +"id='" + id + '\'' +", name='" + name + '\'' +", address='" + address + '\'' +", area='" + area + '\'' +", paydate='" + paydate + '\'' +", singleAmt='" + singleAmt + '\'' +", totalAmt='" + totalAmt + '\'' +'}';
} } ```
- DataListener.java(vo) ```java package org.polaris.easyexcel.util;
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import org.polaris.easyexcel.vo.PayDetail; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List;
/**
- 分页监听器
@author polaris 450733605@qq.com */ public class DataListener extends AnalysisEventListener
{ private final static Logger log = LoggerFactory.getLogger(DataListener.class);
List
list=new ArrayList<>(); @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) {
doWork(analysisContext);
}
@Override public void invoke(PayDetail payDetail, AnalysisContext analysisContext) {
// 此处进行数据处理log.info(payDetail.toString());list.add(payDetail);// 分批处理从excel文档读取的数据,每次处理若干条数据,防止存储几万条数据在内存,容易OOMint BATCH_SIZE=32;if(list.size()>=BATCH_SIZE){// 每读取${BATCH_SIZE}条数据清空一次列表doWork(analysisContext);list.clear();}
}
private void doWork(AnalysisContext analysisContext){
log.info(String.format("当前批次处理数据条数:%d,累计:%d/%d",list.size(),analysisContext.getCurrentRowNum(),analysisContext.getTotalCount()-1));
} } ```
- ExcelParseTest.java(测试类) ```java package org.polaris.easyexcel;
import com.alibaba.excel.EasyExcel; import com.alibaba.excel.support.ExcelTypeEnum; import org.junit.Test; import org.polaris.easyexcel.util.DataListener; import org.polaris.easyexcel.vo.PayDetail; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.util.List;
/**
- excel解析示例
@author polaris 450733605@qq.com */ public class ExcelParseTest {
private final static Logger log = LoggerFactory.getLogger(ExcelParseTest.class);
/**
- 解析excel
@throws IOException */ @Test public void excelParseSimple() throws IOException { InputStream inputStream=new BufferedInputStream(ExcelParseTest.class.getClassLoader().getResourceAsStream(“template2.xlsx”)); List
voList=EasyExcel.read(inputStream) .excelType(ExcelTypeEnum.XLSX).head(PayDetail.class).sheet().headRowNumber(2).doReadSync();
inputStream.close(); for(int i=0;i<voList.size();i++){
log.info(voList.get(i).toString());
} }
/**
- 分页读取Excel文档中的数据
@throws IOException / @Test public void excelParseBatch() throws IOException { InputStream inputStream=new BufferedInputStream(ExcelParseTest.class.getClassLoader().getResourceAsStream(“template2.xlsx”)); // 方式1:不推荐,结果将再次封装到${voList},若过大可能导致OOM /List
voList=EasyExcel.read(inputStream,new DataListener()) .excelType(ExcelTypeEnum.XLSX).head(PayDetail.class).sheet().headRowNumber(2).doReadSync();*/
// 方式2:推荐,分批处理,不做收集 EasyExcel.read(inputStream,new DataListener())
.excelType(ExcelTypeEnum.XLSX).head(PayDetail.class).sheet().headRowNumber(2).doRead();
inputStream.close();
log.info(“完成——————————————————“); }
} ```
- 附件
- 模板:template2.xlsx
完整示例代码
easyexcel_demo.zip
- 模板:template2.xlsx
