EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。
官网地址:https://easyexcel.opensource.alibaba.com/docs/current/
最近在某项目中使用到该工具,现在简要介绍一下其实现excel文件的读写功能实现。
1.引入依赖
我们的项目是基于springboot框架的web项目,首先在maven项目pom.xml文件中添加依赖。
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>4.0.3</version></dependency>
2.读取Excel
以导入用户文件为例,用户包含三个字段姓名、出生日期(date类型)、年龄(数值类型)。
1.创建实体类匹配的导入excel
public class UserModel {private String username;private String birthday;private int age;}
2.控制器controller上传excel文件
public class UserController {private UserService userService;public String upload( MultipartFile file) {return userService.upload(file);}}
3.service层代码
通过EasyExcel.read方法读取导入的文件,并在监听器类UserDataListener中解析读到的数据。
private UserDataListener userDataListener;public String upload(MultipartFile file) {try {EasyExcel.read(file.getInputStream(), UserModel.class, userDataListener).sheet().headRowNumber(1).doRead();} catch (Exception e) {e.printStackTrace();}return "success";}}
3.创建监听器
创建监听器UserDataListener,用来解析导入的数据。
public class UserDataListener extends AnalysisEventListener<UserModel> {public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {System.out.println("处理数据前操作");}public void invoke(UserModel userModel, AnalysisContext analysisContext) {System.out.println("处理数据:" + new Gson().toJson(userModel));}public void doAfterAllAnalysed(AnalysisContext analysisContext) {System.out.println("所有数据解析完成,后置操作处理");}}
在实际的场景中,在invoke中解析数据,并验证数据是否符合导入规范或者再对数据加工等,并把数据暂存到一个list对象中,在doAfterAllAnalysed方法中进行对list对象统一处理,比如数据排序、保存数据库中等。invokeHead方法是导入数据前的操作,比如对上面的list对象清空等,具体操作结合实际业务场景。
4.导入数据验证
通过postman导入excel数据验证。
处理数据前操作处理数据:{"username":"张三1","birthday":"2000-12-20","age":25}处理数据:{"username":"张三2","birthday":"2000-12-21","age":25}处理数据:{"username":"张三3","birthday":"2000-12-22","age":25}处理数据:{"username":"张三4","birthday":"2000-12-23","age":25}处理数据:{"username":"张三5","birthday":"2000-12-24","age":25}处理数据:{"username":"张三6","birthday":"2000-12-25","age":25}所有数据解析完成,后置操作处理
3.写入Excel
1.创建实体类匹配导出的excel
public class UserExportModel {private String username;private String birthday;private int age;private String address;}
2.控制器controller下载excel文件
("/user")public class UserController {private UserService userService;("/download")public void download(HttpServletResponse response) {userService.download(response);}}
3.service代码
/*** 下载文档** @param response*/public void download(HttpServletResponse response) {//输出数据List<UserExportModel> userList = ListUtils.newArrayList();for (int i = 0; i < 10; i++) {UserExportModel data = new UserExportModel();data.setUsername("李四" + i);data.setAge(26);data.setBirthday("1999-12-10");data.setAddress("上海市浦东新区");userList.add(data);}try {response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setCharacterEncoding("utf-8");// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系String fileName = URLEncoder.encode("用户", "UTF-8").replaceAll("\\+", "%20");response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");// 这里需要设置不关闭流EasyExcel.write(response.getOutputStream(), UserExportModel.class).autoCloseStream(Boolean.TRUE)//自定义列宽.registerWriteHandler(new CustomCellWriteWidthConfig())//表格样式可以根据实际情况自定义//.registerWriteHandler(customHorizontalCellStyleStrategy()).sheet("sheet1的名称").doWrite(userList);} catch (Exception e) {e.printStackTrace();}}/*** 自定义设置列宽*/private static class CustomCellWriteWidthConfig implements CellWriteHandler {public void afterCellDispose(CellWriteHandlerContext context) {// 设置第一列宽度为25if (context.getColumnIndex() == 0) {context.getWriteSheetHolder().getSheet().setColumnWidth(0, 25 * 256);}// 设置第二列宽度为15else if (context.getColumnIndex() == 1) {context.getWriteSheetHolder().getSheet().setColumnWidth(1, 15 * 256);}}}private HorizontalCellStyleStrategy customHorizontalCellStyleStrategy(){// 头的策略WriteCellStyle headWriteCellStyle = new WriteCellStyle();headWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);// 背景设置为红色// headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());WriteFont headWriteFont = new WriteFont();// headWriteFont.setFontHeightInPoints((short)20);headWriteCellStyle.setWriteFont(headWriteFont);// 内容的策略WriteCellStyle contentWriteCellStyle = new WriteCellStyle();// 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定//contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);contentWriteCellStyle.setBorderBottom(BorderStyle.DOUBLE);contentWriteCellStyle.setBorderTop(BorderStyle.THIN);contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);contentWriteCellStyle.setBorderRight(BorderStyle.THIN);// 背景绿色//contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());WriteFont contentWriteFont = new WriteFont();// 字体大小// contentWriteFont.setFontHeightInPoints((short)20);contentWriteCellStyle.setWriteFont(contentWriteFont);// 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现HorizontalCellStyleStrategy horizontalCellStyleStrategy =new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);return horizontalCellStyleStrategy;}
4.导出数据验证
通过浏览器输入下载地址http://localhost:8080/user/download下载导出的数据

