- `easyexcel` 简介
- `EasyExcel` 和 `POI` 的对比
- `SpringBoot` 整合 `easyexcel`
- `Maven` 依赖
- 数据库 `SQL` 脚本
- 实体类
- 导入导出 `dao` 层
- 导入导出 `service` 层
- 导入导出 `controller` 层
- 表格事件监听器
- 导入 `excel` 报表页面
- `excel` 报表的导出
- `excel` 报表的导入
Java 解析、生成 Excel 比较有名的框架有 Apache POI,但存在一个严重的问题就是非常的耗内存,针对这个问题阿里出品了用来处理 Excel 的开源工具 easyexcel
GitHub 官网:https://github.com/alibaba/easyexcel
官方文档:https://alibaba-easyexcel.github.io/
- 相比于 POI,EasyExcel 简化了开发量,能够用更少的代码实现更多的功能
- 相比于 POI,EasyExcel 使用简单
- 相比于 POI,EasyExcel 能够使用更少的内存占用
主要依赖如下,其他依赖自行依赖导入
数据库 SQL 脚本com.alibaba easyexcel2.2.6
CREATE TABLE `excel_user` ( `user_id` int(11) NOT NULL AUTO_INCREMENT, `dept_id` int(11) NOT NULL COMMENT '部门ID', `loginName` varchar(255) NOT NULL COMMENT '登录账号rn', `phone` varchar(255) NOT NULL, `password` varchar(255) NOT NULL COMMENT '密码', `status` int(255) NOT NULL COMMENT '帐号状态', `createTime` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATe CURRENT_TIMESTAMP, `updateTime` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`user_id`), UNIQUE KEY `index_ln` (`loginName`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;实体类
@Data public class ExcelUser { // 定义表头名称和位置,0代表第一列 @ExcelProperty(value = "编号", index = 0) private Integer userId; @ExcelProperty(value = "部门编号", index = 1) private Integer deptId; @ExcelProperty(value = "登录账号", index = 2) private String loginname; @ExcelProperty(value = "用户手机号", index = 3) private String phone; @ExcelProperty(value = "密码", index = 4) private String password; @ExcelProperty(value = "账户状态", index = 5) private Integer status; @ExcelProperty(value = "创建时间",index = 6) private Date createtime; @ExcelProperty(value = "更新时间",index = 7) private Date updatetime; }
- easyexcel 中的常用注解:https://blog.csdn.net/weixin_45151960/article/details/109095332
mapper 接口
@Mapper public interface ExcelUserMapper { ListgetAll(); int insertAll(List excelUserDtoList); }
mapper.xml
导入导出 service 层insert into excel_user (dept_id, loginName, phone, password, status) values (#{excelUserDto.deptId}, #{excelUserDto.loginname}, #{excelUserDto.phone}, #{excelUserDto.password}, #{excelUserDto.status})
@Slf4j @Service public class ExcelServiceImpl implements ExcelService { @Autowired private ExcelUserMapper excelUserMapper; @Override public ResultMap excelExport(@NotNull HttpServletResponse response) { // 获取需要导出的数据 List导入导出 controller 层excelUserList = excelUserMapper.getAll(); log.info("记录导出数据行数:{}", excelUserList.size()); try { response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); String fileName = URLEncoder.encode("用户名单表", "UTF-8"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); // 向Excel中写入数据 ExcelWriterBuilder write = EasyExcel.write(response.getOutputStream(), ExcelUser.class); ExcelWriterSheetBuilder excelWriterSheetBuilder = write.sheet("用户名单表"); excelWriterSheetBuilder.doWrite(excelUserList); return new ResultMap().success(); } catch (Exception e) { log.error("数据导出失败!!!"); return new ResultMap().fail(); } } @Transactional @Override public ResultMap excelimport(@NotNull MultipartFile multipartFile) { try { ExcelListener excelListener = new ExcelListener(); // 读取数据 ExcelReaderBuilder excelReaderBuilder = EasyExcel.read(multipartFile.getInputStream(), ExcelUser.class, excelListener); ExcelReaderSheetBuilder excelReaderSheetBuilder = excelReaderBuilder.sheet(); excelReaderSheetBuilder.doRead(); // 获取excel读取到的数据 List list = excelListener.getList(); // 比较loginname字段去重,数据库有唯一索引 List excelUserList = this.removeDuplicateOrder(list); // 数据库表不用插入userId列,它是主键列 List excelUserDtoList = new ArrayList<>(); excelUserList.forEach(item -> { ExcelUserDto excelUserDto = new ExcelUserDto(); BeanUtils.copyProperties(item, excelUserDto); excelUserDtoList.add(excelUserDto); }); // 数据的持久化 int i = excelUserMapper.insertAll(excelUserDtoList); if (i > 0) { return new ResultMap().success(); } return new ResultMap().fail(); } catch (IOException e) { log.error("数据导入失败!!!"); return new ResultMap().fail(); } } @NotNull private List removeDuplicateOrder(List list) { Set set = new TreeSet<>((a, b) -> { // 等于0表示重复 int compareToResult = 1; if (a.getLoginname().equals(b.getLoginname())) { compareToResult = 0; } return compareToResult; }); set.addAll(list); return new ArrayList<>(set); } }
@Slf4j @Controller public class ExcelController { @Autowired private ExcelService excelService; @GetMapping(path = "/excelExport") @ResponseBody public ResultMap excelExport(HttpServletResponse response) { return excelService.excelExport(response); } @GetMapping(path = "/fileUpload") public String uploadPage(){ return "fileUpload"; } @PostMapping(path = "/excelimport") @ResponseBody public ResultMap excelimport(MultipartFile file) { return excelService.excelimport(file); } }表格事件监听器
@Slf4j public class ExcelListener extends AnalysisEventListener导入 excel 报表页面{ @Getter @Setter private List list = new ArrayList<>(); @Override public void invoke(ExcelUser excelUser, AnalysisContext analysisContext) { log.info("--------------------------------------------"); log.info("导入数据{}", JSON.toJSONString(excelUser)); // 数据存储到list,供批量处理,或后续自己业务逻辑处理 list.add(excelUser); } @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { } }
Insert title here 文件上传
- 此处的选择文件的 input 标签中的 name 属性值务必要与 controller 接口中的入参变量名 MultipartFile file 保持一致,否则会报错参数 MultipartFile 不能为 null
浏览器请求接口 http://127.0.0.1:8080/excelimport,结果如下
导出 excel 中的数据
数据库表数据
准备要导入的 excel 报表的数据如下
浏览器访问接口 http://127.0.0.1:8080/fileUpload,页面如下
选择相应的 excel 报表文件,点击提交,结果如下
数据库表新增数据如下
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)