SpringBoot集成EasyExcel实现文件导入导出

 一、什么是EasyExcel

EasyExcel 是一款基于Java的开源Excel操作工具,它提供了简单且强大的 API,使开发人员可以轻松地读写、操作和生成Excel文件。

二、常用注解

  1. @ExcelProperty:用于标识实体类中的字段与 Excel 表格中的列的对应关系。

  2. @ExcelIgnore:用于标识在读写 Excel 时忽略某个字段。

  3. @ExcelIgnoreUnannotated:用于标识在读取 Excel 时忽略未标注 @ExcelProperty 注解的字段。

  4. @ExcelTable:用于标识表格的属性,如表头所在行数等。

三、SpringBoot整合

1.添加依赖

主要依赖:

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.1.3</version>
        </dependency>

项目完整依赖:

<dependencies>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.1.3</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>28.2-jre</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.31</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.9</version>
        </dependency>
        <!-- mybatis-plus配置不同数据源 需要引入的包 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.16</version>
        </dependency>
    </dependencies>

2.实体类

@Data
public class Stu implements Serializable {
 
    private static final long serialVersionUID = 1L;
 
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
 
    @ExcelProperty("姓名")
    private String name;
 
    @ExcelProperty("年龄")
    private Integer age;
 
    @ExcelProperty("班级")
    private String calss;
 
    @ExcelProperty("学校")
    private String school;
 
    @ExcelProperty(value = "性别")
    private Integer sex;
}

3.自定义监听器

/**
 * 自定义监听器,对下载的excel中的数据进行校验
 * */
public class StuListener extends AnalysisEventListener {
 
    List<String> names = new ArrayList<>();
 
    /**
     * 每解析一行,回调该方法
     *
     * @param data
     * @param context
     */
    @Override
    public void invoke(Object data, AnalysisContext context) {
        //校验名称
        String name = ((Stu) data).getName();
        if (StrUtil.isBlank(name)) {
            throw new RuntimeException(String.format("第%s行名称为空,请核实", context.readRowHolder().getRowIndex() + 1));
        }
        if (names.contains(name)) {
            throw new RuntimeException(String.format("第%s行名称已重复,请核实", context.readRowHolder().getRowIndex() + 1));
        } else {
            names.add(name);
        }
    }
 
    /**
     * 出现异常回调
     *
     * @param exception
     * @param context
     * @throws Exception
     */
    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        if (exception instanceof ExcelDataConvertException) {
            /**从0开始计算*/
            Integer columnIndex = ((ExcelDataConvertException) exception).getColumnIndex() + 1;
            Integer rowIndex = ((ExcelDataConvertException) exception).getRowIndex() + 1;
            String message = "第" + rowIndex + "行,第" + columnIndex + "列" + "数据格式有误,请核实";
            throw new RuntimeException(message);
        } else if (exception instanceof RuntimeException) {
            throw exception;
        } else {
            super.onException(exception, context);
        }
    }
 
    /**
     * 解析完,全部回调
     *
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        //解析完,全部回调逻辑实现
        names.clear();
    }
}

4.导入

准备一个导入数据的文件,下方是我的文件:

Controller层代码

    @PostMapping(value = "/importData")
    public void importData(MultipartFile file) {
        try {
            //获取文件的输入流
            InputStream inputStream = file.getInputStream();
            List<Stu> lst = EasyExcel.read(inputStream) //调用read方法
                    //注册自定义监听器,字段校验可以在监听器内实现
                    .registerReadListener(new StuListener())
                    .head(Stu.class) //对应导入的实体类
                    .sheet(0) //导入数据的sheet页编号,0代表第一个sheet页,如果不填,则会导入所有sheet页的数据
                    .headRowNumber(1) //列表头行数,1代表列表头有1行,第二行开始为数据行
                    .doReadSync(); //开始读Excel,返回一个List<T>集合,继续后续入库操作

            System.out.println(lst);
            // TODO 导入后的处理逻辑

        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }
    }

导入成功

5.导出

Controller代码


    /**
     * 导出数据
     * */
    @GetMapping("/export/user")
    public void exportUserExcel(HttpServletResponse response) throws IOException {
        OutputStream outputStream=response.getOutputStream();
        try {
            String filePath = "userlist.xlsx"; // 保存到当前项目下的文件名
            File file = new File(filePath);
            this.setExcelResponseProp(response, "用户列表");
            // 模拟根据条件在数据库查询数据
//            List<Stu> stus = stuMapper.selectList(null);
            List<Stu> stus = new ArrayList<>();

            for (int i = 0; i < 5; i++) {
                Stu stu = new Stu();
                stu.setId(i);
                stu.setName("老" + i);
                if (i % 2 == 0) {
                    stu.setSex(1);
                } else {
                    stu.setSex(0);
                }
                stu.setCalss(i + "班");
                stu.setSchool("第一中学");
                stus.add(stu);
            }

            // 创建本地文件输出流
            outputStream = new FileOutputStream(file);
            //这个实现方式非常简单直接,使用EasyExcel的write方法将查询到的数据进行处理,以流的形式写出即可
            EasyExcel.write(outputStream,Stu.class)//对应的导出实体类
                    .excelType(ExcelTypeEnum.XLSX)//excel文件类型,包括CSV、XLS、XLSX
                    .sheet("Stu列表")//导出sheet页名称
                    .doWrite(stus); //查询获取的数据集合List<T>,转成excel
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            outputStream.flush();
            outputStream.close();
        }
    }

    /**
     * 设置响应结果
     *
     * @param response    响应结果对象
     * @param rawFileName 文件名
     * @throws UnsupportedEncodingException 不支持编码异常
     */
    private void setExcelResponseProp(HttpServletResponse response, String rawFileName) throws UnsupportedEncodingException {

        //设置内容类型
        response.setContentType("application/vnd.vnd.ms-excel");
        //设置编码格式
        response.setCharacterEncoding("utf-8");
        //设置导出文件名称(避免乱码)
        String fileName = URLEncoder.encode(rawFileName.concat(".xlsx"), "UTF-8");
        // 设置响应头
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName);
    }

导出成功

以上一个简单的demo就编写完成了。

  • 30
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值