Springboot整合easyExcel导入导出Excel

2021-03-17 21:26

阅读:582

标签:lazy   -o   入库   测试   ons   ota   func   cep   val   

背景:

最近公司有个需求要求可以导入、导出excel,因此在此记录学习一下如何使用Springboot整合easyExcel;
需求:
数据库中有张user表,有个业务要求可以导入、导出“用户名单.xls”表

一、准备:

创建项目:
关于springboot项目如何创建这里不再赘述,放一张项目结构图:
技术图片
1、导入easyexcel、mybatis、mysql依赖

		!-- easyexcel相关依赖 -->
		>
            >com.alibaba/groupId>
            >easyexcel/artifactId>
            >1.1.2-beta5/version>
        /dependency>
        >
            >org.apache.poi/groupId>
            >poi/artifactId>
            >3.17/version>
        /dependency>
        >
            >org.apache.poi/groupId>
            >poi-ooxml/artifactId>
            >3.17/version>
        /dependency>
		!-- mybatis、mysql相关依赖 -->
		>
            >org.mybatis.spring.boot/groupId>
            >mybatis-spring-boot-starter/artifactId>
            >1.3.1/version>
        /dependency>
        >
            >mysql/groupId>
            >mysql-connector-java/artifactId>
            >5.1.6/version>
        /dependency>

2、application.yml

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=utf-8
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver

3、导出excel

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

//@Data是lombok的一个注解,加上它会自动生成getter、setter方法
@Data
public class User extends BaseRowModel {
    @ExcelProperty(value = "ID", index = 0)
    private String id;
    @ExcelProperty(value = "姓名", index = 1)
    private String name;
    @ExcelProperty(value = "年龄", index = 2)
    private Integer age;
}

(2)Usercontroller

    @GetMapping("/user/excel")
    public void excelExport(HttpServletResponse response) throws IOException {
        userService.excelExport(response);
    }

(3)Userservice

public void excelExport(HttpServletResponse response) throws IOException {
        List> list = userDao.queryAllUsers();
        String fileName = "用户名单";
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename=" + new String( fileName.getBytes("gb2312"), "ISO8859-1" ) + ".xls");
        ServletOutputStream out = response.getOutputStream();
        ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLS,true);
        Sheet sheet = new Sheet(1,0,User.class);
        //设置自适应宽度
        sheet.setAutoWidth(Boolean.TRUE);
        sheet.setSheetName("用户名单");
        writer.write(list,sheet);
        writer.finish();
        out.flush();
        response.getOutputStream().close();
        out.close();
    }

4、导入excel

(1)Usercontroller

   @PostMapping("/user/excel")
    public String excelImport(@RequestParam("file")MultipartFile file) throws IOException {
        userService.excelImport(file);
        return "success";
    }

 

(2)Userservice

public void excelImport(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(userDao);
        ExcelReader reader = new ExcelReader(inputStream,null,excelListener);
        //读取信息
        reader.read(new Sheet(1,1,User.class));
    }

参考easyExcel官方GitHub demo
(3)ExcelListener

public class ExcelListener extends AnalysisEventListener> {
    private List> datas = new ArrayList>();
    private static final int BATCH_COUNT = 3000;
    private UserDao userDao;

    public ExcelListener(UserDao userDao){
        this.userDao = userDao;
    }

    @Override
    public void invoke(User user, AnalysisContext analysisContext) {
        //数据存储到datas,供批量处理,或后续自己业务逻辑处理。
        datas.add(user);
        //达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if(datas.size() >= BATCH_COUNT){
            saveData();
            // 存储完成清理datas
            datas.clear();
        }
    }

    private void saveData() {
        for(User user : datas){
            userDao.addUser(user);
        }
    }

    public List> getDatas() {
        return datas;
    }

    public void setDatas(List> datas) {
        this.datas = datas;
    }

    /**
     * 所有数据解析完成了 都会来调用
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        saveData();//确保所有数据都能入库
    }
}

二、测试

刚开始的数据库表:
技术图片

准备一个“用户名单.xls”表,以便待会测试导入功能:
技术图片

1、 启动项目,使用postman测试“导入”功能:

技术图片
技术图片

点击send,然后查看数据表:

技术图片

上图数据一致,说明导入成功!!!

2、再用postman测试导出功能:

技术图片

没有参数,直接send,然后可以看到:

技术图片
技术图片
将其下载下来查看(本来这里的文件名应该是代码中命名的“用户名单.xls”,但我尝试了很久总是没有变。。。)

技术图片

与数据库表数据一致,说明导出成功!

 

特别说明:

技术图片

 

 

这里的excel名字的命名必须是这个,而且里面的主键可以不写,因为可能会遇到主键冲突的问题

技术图片

 

Springboot整合easyExcel导入导出Excel

标签:lazy   -o   入库   测试   ons   ota   func   cep   val   

原文地址:https://www.cnblogs.com/cxy2020/p/13965633.html

上一篇:javaScript Event loop

下一篇:java


评论


亲,登录后才可以留言!