- 什么是easyExcel
- 下载模板
- 读取文件
- 导入
- 导出
EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。
EasyExcel官方文档地址
需要导入数据时,我们一定需要先制定模板,通过模板导入数据。接下来描述的是springBoot读取resource下的文件并下载。templatePath应该是从resource下开始,需要文件名需要加后缀。如"导入律师库模板.xlsx"
//读取文件
try (InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(templatePath)) {
// //fast-fail原则
HttpServletResponse response = context.getHttpServletResponse();
assert resourceAsStream != null;
try (BufferedInputStream fis = new BufferedInputStream(resourceAsStream); OutputStream toClient = new BufferedOutputStream(response.getOutputStream())) {
//获取文件名
String name = FileUtil.getName(templatePath);
int available = fis.available();
byte[] buffer = new byte[4096];
int r;
while (-1 != (r = fis.read(buffer))) {
toClient.write(buffer, 0, r);
}
// 清空response
//response.reset();
// 设置response的Header
response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(name, "utf-8"));
response.addHeader("Content-Length", "" + available);
//response.setContentType("application/octet-stream");
toClient.flush();
}
}
下载的模板可能会出现乱码,因为编译时也编译了模板文件,需要在pom.xml文件中配置不编译模板文件类型的文件。
读取文件org.apache.maven.plugins maven-resources-plugin UTF-8 xls xlsx
- read()
从读取流读取的是一个一个字节,.返回的是字节的(0-255)内的字节值,读一个下次就自动到下一个,如果返回值是-1说明读完了。 - read(byte[] bytes)
从读取流读取一定数量的字节,如果比如文件总共是102个字节,我们定义的数组长度是10,那么默认前面10次都是读取10个长度。最后一次不够十个,那么读取的是2个,这十一次,每次都是放入10个长度的数组。 - read(byte[] bytes,int off ,int len)
从读取流读取一定数量的字节,如果比如文件总共是102个字节,read(bytes,0,9)那么每次往里面添加的(将只会是9个长度),就要读12次,最后一次放入3个。0指的的是每次都从读到的第0个开始放到buffer中,放九个长度.
- 首先需要依赖EasyExcel
com.alibaba easyexcel 3.0.5
- 读导入的excel中的数据
//参数依次是文件流、接收参数的class类【类中通过@ExcelProperty(value = "案件名称")将excel列表头与类对应。】、指定监听器,读取的sheet页,从execl第几行开始读取。 EasyExcel.readread(InputStream inputStream, Class head, ReadListener readListener).sheet().headRowNumber(headRowNumber).doRead();
- 读到excel中的数据时会触发指定的监听器,在监听器中做具体的操作就可以了。
// 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去 @Slf4j public class DemoDataListener implements ReadListener导出{ private static final int BATCH_COUNT = 100; private List cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); private DemoDAO demoDAO; public DemoDataListener() { // 这里是demo,所以随便new一个。实际使用如果到了spring,请使用下面的有参构造函数 demoDAO = new DemoDAO(); } public DemoDataListener(DemoDAO demoDAO) { this.demoDAO = demoDAO; } @Override public void invoke(DemoData data, AnalysisContext context) { log.info("解析到一条数据:{}", JSON.toJSONString(data)); cachedDataList.add(data); // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM if (cachedDataList.size() >= BATCH_COUNT) { saveData(); // 存储完成清理 list cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); } } @Override public void doAfterAllAnalysed(AnalysisContext context) { // 这里也要保存数据,确保最后遗留的数据也存储到数据库 saveData(); log.info("所有数据解析完成!"); } private void saveData() { log.info("{}条数据,开始存储数据库!", cachedDataList.size()); demoDAO.save(cachedDataList); log.info("存储数据库成功!"); } }
- 导出到excel
一定要在获取response后立即写,不同格式的文件浏览器需要使用不同的解析
EasyExcel会自动关闭输出流
try {
HttpServletResponse response = getHttpServletResponse(context, excelName);
EasyExcel.write(response.getOutputStream(), ExportTraderbaseInfoVo.class).includeColumnFiledNames(includeColumnFiledNames).sheet("交易商基础信息表").doWrite(vos);
} catch (Exception e) {
e.printStackTrace();
}
private HttpServletResponse getHttpServletResponse(ServiceHandlerContext context, String excelName) throws UnsupportedEncodingException {
HttpServletResponse response = context.getHttpServletResponse();
// 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman测试
//浏览器解析页面的方式,"application/octet-stream"支持所有格式的文件
response.setContentType("application/octet-stream");
告知客户端响应正文类型
response.setHeader("content-type", "application/octet-stream");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码
String fileName = URLEncoder.encode(excelName, "UTF-8").replaceAll("\+", "%20")+".xlsx";
//attachment表示以附件方式下载,如果在页面中打开,应该修改为Inline
response.setHeader("Content-disposition", "attachment;filename=" + fileName);
return response;
}
- 导出的excel打开后可能出现乱码、文件损坏不能打开,不同文件类型浏览器应该用不同的方式解析。
| 文件类型 | 解析方式 |
|---|---|
| application/pdf | |
| jpe | image/jpeg |
| jpeg | image/jpeg |
| jpg | image/jpeg |
| htm | text/html |
| * | application/octet-stream |
| xls | application/vnd.ms-excel |



