SpringBoot整合EasyExcel实现Excel导入导出/上传下载至数据库 您所在的位置:网站首页 可以导入excel的数据库 SpringBoot整合EasyExcel实现Excel导入导出/上传下载至数据库

SpringBoot整合EasyExcel实现Excel导入导出/上传下载至数据库

2023-07-16 23:05| 来源: 网络整理| 查看: 265

上一篇写了一个SpringBoot整合poi实现excel导入导出的,但是使用poi会有一些问题,这时阿里带着EasyExcel来了。

Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,能够原本一个3M的excel用POI sax依然需要100M左右内存降低到几M,并且再大的excel不会出现内存溢出,03版依赖POI的sax模式。在上层做了模型转换的封装,让使用者更加简单方便。

这个整合EasyExcel的demo是在上一篇整合poi的基础上改进的,这里给个传送门SpringBoot实现Excel文件上传至数据库及下载数据库数据为Excel 源码已上传至码云 下面贴出修改的地方 先改一下依赖pom.xml

com.alibaba easyexcel 1.1.2-beta5 org.apache.poi poi 3.17 org.apache.poi poi-ooxml 3.17

测试的页面index.html修改如下 在这里插入图片描述

上传excl 上传excl并插入到数据库 ;文件上传poi ;文件上传EasyExcel 数据导出poi 数据导出easyexcel function downloadfile1(){ window.location.href="/user/UserExcelDownloads"; } function downloadfile2(){ window.location.href="/user/UserExcelDownloadsEasyExcel"; }

导出 user实体类 导出 Excel 时,若需要表头,那么相应的实体类需要继承 BaseRowModel,并加入 @ExcelProperty(value = “id”, index = 0) 注解。其中 value 代表在导出 Excel 时,该字段对应的表头名称;index 代表该字段对应的表头位置(从0开始)

package com.thz.excl_upload.entity; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.metadata.BaseRowModel; import java.io.Serializable; import java.util.Date; /** * (User)实体类 * * @author makejava * @since 2020-07-22 09:57:53 */ public class User extends BaseRowModel implements Serializable { private static final long serialVersionUID = -75075031034829113L; @ExcelProperty(value = {"ID"}, index = 0) private Integer id; @ExcelProperty(value = {"neme"}, index = 1) private String name; @ExcelProperty(value = {"性别"}, index = 2) private String sex; @ExcelProperty(value = {"创建时间"}, index = 3) private Date createTime; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } }

UserController中添加下面的方法

@RequestMapping("UserExcelDownloadsEasyExcel") public void UserExcelDownloadsEasyExcel(HttpServletResponse response) throws IOException { ExcelWriter writer = EasyExcelFactory.getWriter(response.getOutputStream()); // 写仅有一个 Sheet 的 Excel 文件, 此场景较为通用 Sheet sheet1 = new Sheet(1, 0, User.class); // 第一个 sheet 名称 sheet1.setSheetName("第一个sheet"); // 写数据到 Writer 上下文中 // 入参1: 数据库查询的数据list集合 // 入参2: 要写入的目标 sheet writer.write(userService.queryAll(new User()), sheet1); // 将上下文中的最终 outputStream 写入到指定文件中 response.setContentType("application/octet-stream"); String fileName = "userinf" + ".xls"; response.setHeader("Content-disposition", "attachment;filename=" + fileName); response.flushBuffer(); writer.finish(); }

导入 因为EasyExcel是依据实体类中的@ExcelProperty注解来解析Excel表中每一列的数据的,如果说上传表中数据和数据库中字段是对应的 ,那我们可以继续使用上面的实体类。但是通常业务传过来的表可能是只有一些关键字段,这时候我们还想进行上传需要修改原先User实体的注解与上传表一致,可这样导出的数据就不全了。为了解决这个问题需要再创建一个专门的上传UserUpLoad实体类。 在这里插入图片描述 我的表是上面这样的,所以新创建了如下UserUpLoad实体

import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.metadata.BaseRowModel; import java.io.Serializable; import java.util.Date; /** * (User)实体类 * * @author makejava * @since 2020-07-22 09:57:53 */ public class UserUpLoad extends BaseRowModel implements Serializable { private static final long serialVersionUID = -75075031034829113L; private Integer id; @ExcelProperty(value = {"neme"}, index = 0) private String name; @ExcelProperty(value = {"性别"}, index = 1) private String sex; private Date createTime; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } }

UserUpLoadDao

/** * (UserUpLoad)表数据库访问层 * * @author makejava * @since 2020-07-27 09:57:53 */ @Mapper @Component public interface UserUpLoadDao { /** * 新增数据 * * @param user 实例对象 * @return 影响行数 */ int insert(UserUpLoad user); }

UserUpLoadDao.xml

insert into excl_test.user(name, sex, create_time) values (#{name}, #{sex}, #{createTime})

实体类的准备工作做完了,下面修改一下Controller

@RequestMapping(value = "/uploadEasyExcl") public @ResponseBody Map uploadEasyExcl(HttpServletRequest request, @RequestParam("file") MultipartFile file) throws IOException { Map result = new HashMap(); userService.saveUser(file); return result; }

UserServiceImpl

@Override public void saveUser(MultipartFile file) throws IOException { if(!file.getOriginalFilename().equals("上传测试.xls") && !file.getOriginalFilename().equals("上传测试.xlsx") ){ return; } InputStream inputStream = new BufferedInputStream(file.getInputStream()); //实例化实现了AnalysisEventListener接口的类 ExcelListener excelListener = new ExcelListener(userUpLoadDao); ExcelReader reader = new ExcelReader(inputStream,null,excelListener); //读取信息 reader.read(new Sheet(1,1,UserUpLoad.class)); }

ExcelListener

package com.thz.excl_upload.listener; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.thz.excl_upload.dao.UserUpLoadDao; import com.thz.excl_upload.entity.UserUpLoad; import java.util.ArrayList; import java.util.Date; import java.util.List; public class ExcelListener extends AnalysisEventListener { private List datas = new ArrayList(); private static final int BATCH_COUNT = 3000; private UserUpLoadDao userUpLoadDao; public ExcelListener(UserUpLoadDao userUpLoadDao){ this.userUpLoadDao = userUpLoadDao; } @Override public void invoke(UserUpLoad user, AnalysisContext analysisContext) { //数据存储到datas,供批量处理,或后续自己业务逻辑处理。 datas.add(user); //达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM if(datas.size() >= BATCH_COUNT){ saveData(); // 存储完成清理datas datas.clear(); } } private void saveData() { for(UserUpLoad user : datas){ user.setCreateTime(new Date()); this.userUpLoadDao.insert(user); } } public List getDatas() { return datas; } public void setDatas(List datas) { this.datas = datas; } /** * 所有数据解析完成了 都会来调用 */ @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { saveData();//确保所有数据都能入库 } }

参考Springboot整合easyExcel导入导出Excel



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有