阿里开源(EasyExcel)
1.官网与介绍
1.GitHub官网
GitHub地址:https://github.com/alibaba/easyexcel
使用文档地址https://alibaba-easyexcel.github.io/index.html
2.介绍
EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称。Java领域解析、生成Excel比较有名的框架有Apache poi、jxl等。但他们都存在一个严重的问题就是非常的耗内存。如果你的系统并发量不大的话可能还行,但是一旦并发上来后一定会OOM或者JVM频繁的full gc。easyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。
2.easyexcel使用
1.在pom.xml
中加入依赖
<!-- easyexcel start -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.6</version>
</dependency>
<!-- easyexcel end -->
2.ExcelListener(导入时调用)
使用 EasyExcel,需要建一个监听类并继承 AnalysisEventListener
public class CheliangListener extends AnalysisEventListener {
//可以通过实例获取该值
private List<Object> datas = new ArrayList<Object>();
public void invoke(Object o, AnalysisContext analysisContext) {
datas.add(o);//数据存储到list,供批量处理,或后续自己业务逻辑处理。
doSomething(o);//根据自己业务做处理
}
private void doSomething(Object object) {
//1、入库调用接口
}
public List<Object> getDatas() {
return datas;
}
public void setDatas(List<Object> datas) {
this.datas = datas;
}
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
// datas.clear();//解析结束销毁不用的资源
}
}
PS:其中, invoke()
和 doAfterAllAnalysed()
是必须实现的方法。
在 invoke()
中,我们将数据封装到 list
中,再在控制器中,通过 getter()
方法获取数据,这样我们就可以获取到 easyexcel
帮我们解析好的数据,再将数据进行类型转化,这样,我们就可以对数据进行写入操作。
3.建立实体类
这是一个实体类。我们导出 Excel 时,有时需要表头,如果需要表头字段,我们就可以在相应的实体类中加入 @ExcelProperty(value = "id", index = 0)
, @ExcelIgnore
默认所有字段都会和excel去匹配,加了这个注解会忽略该字段,并且继承 BaseRowModel
。其中 value 代表在导出 Excel 时,该字段对应的表头名称;index 代表该字段对应的表头位置。
public class BdCheliangEntity extends BaseRowModel implements Serializable {
/**主键*/
@ExcelIgnore
private String id;
/**创建人名称*/
@ExcelIgnore
private String createName;
/**创建人登录名称*/
@ExcelIgnore
private String createBy;
/**创建日期*/
@ExcelIgnore
private Date createDate;
/**更新人名称*/
@ExcelIgnore
private String updateName;
/**更新人登录名称*/
@ExcelIgnore
private String updateBy;
/**更新日期*/
@ExcelIgnore
private Date updateDate;
/**所属部门*/
@ExcelIgnore
private String sysOrgCode;
/**所属公司*/
@ExcelIgnore
private String sysCompanyCode;
/**流程状态*/
@ExcelIgnore
private String bpmStatus;
/**车牌号*/
@ExcelProperty(value="车牌号",index=0)
private String chepaihao;
/**车型*/
@ExcelProperty(value="车型",index=1)
private String chexing;
/**最大体积*/
@ExcelProperty(value="最大体积",index=2)
private String zuidatiji;
/**载重*/
@ExcelProperty(value="载重",index=3)
private String zaizhong;
/**载人数*/
@ExcelProperty(value="载人数",index=4)
private String zairen;
/**准假驾照*/
@ExcelProperty(value="准假驾照",index=5)
private String jiazhao;
/**是否可用*/
@ExcelProperty(value="是否可用",index=6)
private String zhuangtai;
/**备注*/
@ExcelProperty(value="备注",index=7)
private String beizhu;
/**默认司机*/
@ExcelProperty(value="默认司机",index=8)
private String username;
/**gps*/
@ExcelProperty(value="gps",index=9)
private String gpsid;
@ExcelProperty(value="区域",index=10)
private String quyu;
//查询条件
@ExcelIgnore
private Integer page = 1;
@ExcelIgnore
private Integer rows = 10;
@ExcelIgnore
private Integer pagerows;
@ExcelIgnore
private String searchKey;
@ExcelIgnore
private String searchKey2;
@ExcelIgnore
private String searchKey3;
4.easyexcel导出的使用
controller层
步骤:
- 添加响应头信息;
- 添加 ExcelWriter;
- 添加 Sheet(表单);
- 添加数据;
- 输出。
// 导出
@ResponseBody
@RequestMapping("/exportExcel")
public String exporExcel(BdCheliangEntity bdCheliangEntity, HttpServletResponse response) throws IOException {
String result = null;
ExcelWriter writer = null;
OutputStream outputStream = response.getOutputStream();
try {
String fileName ="车辆信息.xls";
//添加响应头信息
response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(fileName,"UTF-8"));
response.setContentType("application/msexcel;charset=UTF-8");//设置类型
response.setHeader("Pragma", "No-cache");//设置头
response.setHeader("Cache-Control", "no-cache");//设置头
response.setDateHeader("Expires", 0);//设置日期头
//实例化 ExcelWriter
writer = new ExcelWriter(outputStream, ExcelTypeEnum.XLS, true);
//实例化表单
Sheet sheet = new Sheet(1, 0, BdCheliangEntity.class);
sheet.setSheetName("车辆信息");
//获取数据
List<BdCheliangEntity> list = bdCheliangService.outExcel(bdCheliangEntity);
//输出
writer.write(list, sheet);
writer.finish();
outputStream.flush();
outputStream.close();
result = "success";
} catch (IOException e) {
e.printStackTrace();
result = "fail";
} finally {
try {
response.getOutputStream().close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
service层
@Override
public List<BdCheliangEntity> outExcel(BdCheliangEntity bdCheliangEntity) {
List<BdCheliangEntity> list=bdCheliangMapper.outExcel(bdCheliangEntity);
return list;
}
dao层
List<BdCheliangEntity> outExcel(BdCheliangEntity query);
5.easyexcel导入的使用
controller层
// 导入
@RequestMapping("/importExcel")
@ResponseBody
public String importExcel(MultipartFile uploadFile) {
String result = null;
InputStream is = null;
try {
String filename = uploadFile.getOriginalFilename();
if (filename != null && (filename.toLowerCase().endsWith(".xls") || filename.toLowerCase().endsWith(".xlsx"))) {
is = new BufferedInputStream(uploadFile.getInputStream());
} else {
return "导入的文件不是excel文件";
}
result = bdCheliangService.readExcel(is);
} catch (Exception e) {
e.printStackTrace();
return "系统发生错误";
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
service层
步骤:
- 实例化 ExcelListener;
- 实例化 ExcelReader;
- 读取表格信息;
- 向数据库插入数据
// 导入
@Override
public String readExcel(InputStream is) {
IdWorker idWorker=new IdWorker(0,0);
ExcelReader excelReader = null;
CheliangListener listener = new CheliangListener();
// excelReader = new ExcelReader(is, ExcelTypeEnum.XLSX, null, listener);
excelReader = EasyExcelFactory.getReader(is, listener);
excelReader.read(new Sheet(1, 1, BdCheliangEntity.class));
List<Object> importList = listener.getDatas();
List<BdCheliangEntity> list = new ArrayList<>();
BdCheliangEntity info = new BdCheliangEntity();
//转换数据类型,并插入到数据库
for (int i = 0; i < importList.size(); i++) {
info = (BdCheliangEntity) importList.get(i);
String id = String.valueOf(idWorker.nextId());
info.setId(id);
info.setCreateDate(new Date());
list.add(info);
}
if(list.size()>=1) {
bdCheliangMapper.importExcel(list);
list.clear();
}
return "success";
}
dao层
void importExcel(List<BdCheliangEntity> list);
6.效果
导出excel效果:
前端界面效果:
具体代码请查看源代码