EasyPoi(excel导入导出)

一,依赖包:

复制代码
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-spring-boot-starter</artifactId>
            <version>4.1.3</version>
        </dependency>

二,官网文档

1. 前言 - Powered by MinDoc

三,基础注解

###注解介绍

easypoi起因就是Excel的导入导出,最初的模板是实体和Excel的对应,model--row,filed--col 这样利用注解我们可以和容易做到excel到导入导出

经过一段时间发展,现在注解有5个类分别是

  • @Excel 作用到filed上面,是对Excel一列的一个描述
  • @ExcelCollection 表示一个集合,主要针对一对多的导出,比如一个老师对应多个科目,科目就可以用集合表示
  • @ExcelEntity 表示一个继续深入导出的实体,但他没有太多的实际意义,只是告诉系统这个对象里面同样有导出的字段
  • @ExcelIgnore 和名字一样表示这个字段被忽略跳过这个导导出
  • @ExcelTarget 这个是作用于最外层的对象,描述这个对象的id,以便支持一个对象可以针对不同导出做出不同处理

注解中的ID的用法

这个ID算是一个比较独特的例子,比如

复制代码
@ExcelTarget("teacherEntity")
public class TeacherEntity implements java.io.Serializable {
    /** name */
    @Excel(name = "主讲老师_teacherEntity,代课老师_absent", orderNum = "1", mergeVertical = true,needMerge=true,isImportField = "true_major,true_absent")
    private String name;

这里的@ExcelTarget 表示使用teacherEntity这个对象是可以针对不同字段做不同处理

同样的ExcelEntity 和ExcelCollection 都支持这种方式

当导出这对象时,name这一列对应的是主讲老师,而不是代课老师还有很多字段都支持这种做法

###@Excel

这个是必须使用的注解,如果需求简单只使用这一个注解也是可以的,涵盖了常用的Excel需求,需要大家熟悉这个功能,主要分为基础,图片处理,时间处理,合并处理几块,name_id是上面讲的id用法,这里就不累言了

|----------------|------------|------------------|-----------------------------------------------------------------------------------------------------|
| 属性 | 类型 | 默认值 | 功能 |
| name | String | null | 列名,支持name_id |
| needMerge | boolean | fasle | 是否需要纵向合并单元格(用于含有list中,单个的单元格,合并list创建的多个row) |
| orderNum | String | "0" | 列的排序,支持name_id |
| replace | String[] | {} | 值得替换 导出是{a_id,b_id} 导入反过来 |
| savePath | String | "upload" | 导入文件保存路径,如果是图片可以填写,默认是upload/className/ IconEntity这个类对应的就是upload/Icon/ |
| type | int | 1 | 导出类型 1 是文本 2 是图片,3 是函数,10 是数字 默认是文本 |
| width | double | 10 | 列宽 |
| height | double | 10 | 列高,后期打算统一使用 @ExcelTarget 的height,这个会被废弃,注意 |
| isStatistics | boolean | fasle | 自动统计数据,在追加一行统计,把所有数据都和输出[这个处理会吞没异常,请注意这一点] |
| isHyperlink | boolean | false | 超链接,如果是需要实现接口返回对象 |
| isImportField | boolean | true | 校验字段,看看这个字段是不是导入的Excel中有,如果没有说明是错误的Excel,读取失败,支持name_id |
| exportFormat | String | "" | 导出的时间格式,以这个是否为空来判断是否需要格式化日期 |
| importFormat | String | "" | 导入的时间格式,以这个是否为空来判断是否需要格式化日期 |
| format | String | "" | 时间格式,相当于同时设置了exportFormat 和 importFormat |
| databaseFormat | String | "yyyyMMddHHmmss" | 导出时间设置,如果字段是Date类型则不需要设置 数据库如果是string 类型,这个需要设置这个数据库格式,用以转换时间格式输出 |
| numFormat | String | "" | 数字格式化,参数是Pattern,使用的对象是DecimalFormat |
| imageType | int | 1 | 导出类型 1 从file读取 2 是从数据库中读取 默认是文件 同样导入也是一样的 |
| suffix | String | "" | 文字后缀,如% 90 变成90% |
| isWrap | boolean | true | 是否换行 即支持\n |
| mergeRely | int[] | {} | 合并单元格依赖关系,比如第二列合并是基于第一列 则{0}就可以了 |
| mergeVertical | boolean | fasle | 纵向合并内容相同的单元格 |
| fixedIndex | int | -1 | 对应excel的列,忽略名字 |
| isColumnHidden | boolean | false | 导出隐藏列 |

###@ExcelCollection

一对多的集合注解,用以标记集合是否被数据以及集合的整体排序

|----------|------------|-----------------|------------------|
| 属性 | 类型 | 默认值 | 功能 |
| id | String | null | 定义ID |
| name | String | null | 定义集合列名,支持nanm_id |
| orderNum | int | 0 | 排序,支持name_id |
| type | Class<?> | ArrayList.class | 导入时创建对象使用 |

###@ExcelEntity

标记是不是导出excel 标记为实体类,一遍是一个内部属性类,标记是否继续穿透,可以自定义内部id

|----|--------|------|------|
| 属性 | 类型 | 默认值 | 功能 |
| id | String | null | 定义ID |

###@ExcelIgnore

忽略这个属性,多使用需循环引用中,无需多解释吧^^

###@ExcelTarget

限定一个到处实体的注解,以及一些通用设置,作用于最外面的实体

属性 | 类型 | 默认值 | 功能

---------|--------|--------|-------

value | String | null | 定义ID

height | double | 10 | 设置行高

fontSize | short | 11 | 设置文字大小

四,代码的实现

导出数据

实体类:

复制代码
package com.example.yebsever.domain.dto.easyPoi;

import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.annotation.ExcelIgnore;
import cn.afterturn.easypoi.excel.annotation.ExcelTarget;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;

@Data
@ExcelTarget("easyPoi")
public class EasyPoi {

    @ExcelIgnore
    @TableId(type = IdType.AUTO)
    private Integer id;

    /**
     * 学生名称
     */
    @Excel(name = "学生名称")
    private String studentName;

    /**
     * 0-男 1-女
     */
    private Integer studentSex;

    @Excel(name = "性别")
    private String studentSexName;

    /**
     * 图片
     */
    @Excel(name = "头像",type =2 ,savePath="upload/Icon/")
    private String img;
}

注意:type:2 表示导出是图片 savePath:默认为upload/className/就行,图片就可以导出了

控制层:

复制代码
/***
     *导出数据
     * produces:以流的形式导出
     * 导出是响应出去
     */
    @ApiOperation(value = "导出数据")
    @GetMapping(value = "exportData",produces = "application/octet-stream")
    public void exportData(HttpServletResponse response){
        //1.查询导出信息
        List<EasyPoi> easyPoisList=testService.exportData();
        easyPoisList.stream().forEach(s->{
            if (s.getStudentSex().equals(1)){
                s.setStudentSexName("女");
            }else {
                s.setStudentSexName("男");
            }

        });
        log.info("数据:{}",easyPoisList);
        //2.导出
        ExportParams params = new ExportParams("学生信息表","学生信息表", ExcelType.XSSF);
        Workbook sheets = ExcelExportUtil.exportExcel(params, EasyPoi.class, easyPoisList);
        log.info("sheets结果:{}",sheets);
        ServletOutputStream outputStream =null;
        try {
            //头部信息
            response.setHeader("content-disposition", "attachment;filename="+
                    URLEncoder.encode("学生信息表.xlsx", "UTF-8"));
            response.setHeader("content-type", "application/octet-stream");
            //输出字节流
            outputStream=response.getOutputStream();
           sheets.write(outputStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            if (null!=outputStream){
                try {
                    //关闭流
                    outputStream.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

导入数据

实体类:

复制代码
package com.example.yebsever.domain;

import cn.afterturn.easypoi.excel.annotation.Excel;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Data;

/**
 * 测试
 * @TableName test
 */
@TableName(value ="test")
@Data
public class Test implements Serializable {
    /**
     *
     */
    @TableId(type = IdType.AUTO)
    private Integer id;

    /**
     * 学生名称
     */
    @Excel(name = "学生名称")
    private String studentName;

    /**
     * 0-男 1-女
     */
    private Integer studentSex;
    @Excel(name = "性别")
    @TableField(exist = false)
    private String studentSexName;

    /**
     * 图片
     */
    @Excel(name = "头像",type =2 ,savePath="D:\\student")
    private String img;

    @TableField(exist = false)
    private static final long serialVersionUID = 1L;


}

注意:savePath:可以设为本地路径储存到本地

控制层

复制代码
/**
     * 导入数据
     */
    @PostMapping("importData")
    @ApiOperation(value = "导入数据")
    public void importData(MultipartFile file){
        //导入
        ImportParams params = new ImportParams();
        //去掉标题行
        params.setTitleRows(1);
        try {
            List<Test> easyPoisList= ExcelImportUtil.importExcel(file.getInputStream(), Test.class, params);
            /**
            *如果不想存在本地,就在这里自己添加方法
            **/
            log.info("数据结果:{}",easyPoisList);
            easyPoisList.stream().forEach(s->{
                if ("男".equals(s.getStudentName())){
                    s.setStudentSex(0);
                }else {
                    s.setStudentSex(1);
                }
            });
            testService.saveBatch(easyPoisList);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }


    }
相关推荐
极智-9963 分钟前
Excel如何合并单元格?【图文详解】Excel合并单元格技巧?单元格合并高阶操作?
excel·excel如何合并单元格·excel合并单元格技巧·单元格合并高阶操作·单元格合并·取消单元格合并·重复数据合并
hrrrrb4 分钟前
【Spring Security】Spring Security 密码编辑器
java·hive·spring
豐儀麟阁贵6 分钟前
2.3变量与常量
java·开发语言
兮动人1 小时前
Eureka注册中心通用写法和配置
java·云原生·eureka
爱编程的小白L3 小时前
基于springboot志愿服务管理系统设计与实现(附源码)
java·spring boot·后端
聪明的笨猪猪5 小时前
Java Redis “持久化”面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
聪明的笨猪猪6 小时前
Java Redis “核心基础”面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
奋斗的小monkey8 小时前
Spring Boot 3.x核心特性与性能优化实战
java·spring boot·微服务·性能优化·响应式编程