【SpringBoot】三十七、SpringBoot整合EasyPoi自定义字典导出Excel

   日期:2020-11-09     浏览:585    评论:0    
核心提示:前面我们介绍了 SpringBoot 中使用 JeecgBoot 的 Autopoi 导出 Excel,其实 Autopoi 的底层也是 EasyPoi,对于 Excel 的导入/导出也是非常方便的。那 EasyPoi 也是基于 POI 的,如果对这方面想要深究的,可以先看看原生 POI 的导入/导出方式,你会回来选择 EasyPoi 的一、简介EasyPoi 功能如同名字 easy,主打的功能就是容易,让一个没见接触过poi的人员就可以方便的写出 Excel 导出,Excel 模板导出,Excel 导

前面我们介绍了 SpringBoot 中使用 JeecgBoot 的 Autopoi 导出 Excel,其实 Autopoi 的底层也是 EasyPoi,对于 Excel 的导入/导出也是非常方便的。那 EasyPoi 也是基于 POI 的,如果对这方面想要深究的,可以先看看原生 POI 的导入/导出方式,你会回来选择 EasyPoi 的

一、简介

EasyPoi 功能如同名字 easy,主打的功能就是容易,让一个没见接触过poi的人员就可以方便的写出 Excel 导出,Excel 模板导出,Excel 导入,Word 模板导出,通过简单的注解和模板语言(熟悉的表达式语法),完成以前复杂的写法

如果想了解 JeecgBoot 的 Autopoi,可以参考我的另一篇博客,SpringBoot 中使用 JeecgBoot 的 Autopoi 导出 Excel

https://blog.csdn.net/qq_40065776/article/details/107824221

二、引入 EasyPoi

EasyPoi 在 SpringBoot 中也是做了很好的封装,让我们能够在 SpringBoot 快速地使用 EasyPoi 进行开发

<!-- easypoi -->
<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-spring-boot-starter</artifactId>
    <version>4.2.0</version>
</dependency>

我们只需要引入这一个依赖即可,这是对 SpringBoot 做了很好的支持

三、源码解读

1、@Excel 源码解读

通过查阅源码,我们不难从 cn.afterturn.easypoi.excel.annotation.Excel 注解中发现


package cn.afterturn.easypoi.excel.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Excel { 

    
    public String name();

    
    public String orderNum() default "0";

    
    public String[] replace() default { };
    
    public String dict() default  "";
}

以上是 @Excel 注解的代码片段,我们可以看出该注解中支持两种字典替换方式

  • 1、replace,该方式支持直接写入注解参数中,如:
@Excel(name = "性别", width = 15, replace = "男_1,女_2")
@TableField("sex")
private Integer sex;

我们用 1 表示 男性,2 表示 女性,这样我们在导出的时候,就能够自动替换掉数据中的魔法值,但是这样我们往往要在注解参数中写入过多的代码,而且我们的字典往往是动态变化的,这样的局限性太大

  • 2、dict,字典方式,传入字典参数中,如:
@Excel(name = "性别", width = 15, dict = "sex")
@TableField("sex")
private Integer sex;

这里我们只传入的字典的 key,这样我们在查询出数据的时候,写入 Excel 文件时,在进行动态替换,即可替换掉数据中的魔法值,增加数据的可读性

2、IExcelDictHandler 源码解读

上一步,我们已经知道了在 EasyPoi 中是支持自定义字典查询导出的,那么我们该如何实现它呢?通过阅读 cn.afterturn.easypoi.handler.inter.IExcelDictHandler 接口中的代码,代码如下:

package cn.afterturn.easypoi.handler.inter;

import java.util.List;
import java.util.Map;


public interface IExcelDictHandler { 

    
    default public List<Map> getList(String dict) { 
        return null;
    }

    
    public String toName(String dict, Object obj, String name, Object value);

    
    public String toValue(String dict, Object obj, String name, Object value);
}

接口中提供了三个方法:

  • 1、getList,通过字典 key 查询该 key 下的所有字典数据,例如:sex 下的 {“1”:“男”, “2”:“女”}
  • 2、toName,字典的翻译功能,从值翻译到名称,例如:sex: 1 --> “男”,一般导出的时候使用
  • 3、toValue,与 toName 相反,从名称翻译到值,例如:sex: “男” --> 1,一般导入的时候使用

既然我们知道在 EasyPoi 中提供了字典翻译的接口,那我们只需要提供一个实现类,重写接口中的方法即可,IExcelDictHandlerImpl.java 实现 IExcelDictHandler 接口,代码如下:

package com.zyxx.common.excel;

import cn.afterturn.easypoi.handler.inter.IExcelDictHandler;
import com.zyxx.sys.service.SysDictDetailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;


@Slf4j
@Component
public class IExcelDictHandlerImpl implements IExcelDictHandler { 

    @Autowired
    private SysDictDetailMapper testSysDictDetailMapper;
    private static SysDictDetailMapper sysDictDetailMapper;

    @PostConstruct
    public void init() { 
        sysDictDetailMapper = this.testSysDictDetailMapper;
    }

    
    @Override
    public String toName(String dict, Object obj, String name, Object value) { 
        return sysDictDetailMapper.getTextByDictAndValue(dict, String.valueOf(value));
    }

    
    @Override
    public String toValue(String dict, Object obj, String name, Object value) { 
        return null;
    }
}
  • 1、这里我们导出,只使用了 toName(从值翻译到名称)这个方法,所以,只写了一个方法
  • 2、我们需要使用 @Component 注解将它加载到 Spring 容器中
  • 3、@PostConstruct 该注解被用来修饰一个非静态的 void() 方法。被 @PostConstruct 修饰的方法会在服务器加载 Servlet 的时候运行,并且只会被服务器执行一次。PostConstruct 在构造函数之后执行,init() 方法之前执行

四、开始导出

1、定义实体类

package com.zyxx.sys.entity;

import cn.afterturn.easypoi.excel.annotation.Excel;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.zyxx.common.annotation.Dict;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.util.Date;


@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("sys_user_info")
@ApiModel(value = "SysUserInfo对象", description = "用户信息表")
public class SysUserInfo extends Model<SysUserInfo> { 


    @ApiModelProperty(value = "ID")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    @Excel(name = "姓名", width = 15)
    @ApiModelProperty(value = "姓名")
    @TableField("name")
    private String name;

    @Excel(name = "电话", width = 15)
    @ApiModelProperty(value = "电话")
    @TableField("phone")
    private String phone;

    @Excel(name = "性别", width = 15, dict = "sex")
    @TableField("sex")
    @Dict(dictCode = "user_sex")
    private Integer sex;

    @Excel(name = "状态", width = 15, dict = "status")
    @TableField("status")
    private Integer status;
}

@Excel 注解解释如下:

  • name,表头名称
  • width,列宽
  • dict,字典 key

2、导出 API 接口

controller 层提供导出 API

@ApiOperation(value = "导出用户信息", notes = "导出用户信息")
@GetMapping(value = "/export")
public void exportXls(HttpServletResponse response) { 
	// 查询数据
    List<SysUserInfo> list = sysUserInfoService.list(1, Integer.MAX_VALUE);
    // 导出数据,数据,数据类型,文件名称,表名,响应对象
    ExportExcelUtil.exportExcel(list, SysUserInfo.class, "用户信息表", "用户信息统计", response);
}

3、导出工具类


public static void exportExcel(List<?> list, Class<?> pojoClass, String fileName, String title, HttpServletResponse response) { 
   ExportParams exportParams = new ExportParams(title, null);
   // 自定义字典查询规则
   exportParams.setDictHandler(new IExcelDictHandlerImpl());
   Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
   if (workbook != null) { 
       try { 
           response.setCharacterEncoding("UTF-8");
           response.setHeader("content-Type", "application/vnd.ms-excel");
           response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xls");
           workbook.write(response.getOutputStream());
       } catch (IOException e) { 
           e.printStackTrace();
       }
   }
}

exportParams.setDictHandler(new IExcelDictHandlerImpl());,我们传入了自定义的字典查询规则

五、测试导出

我们调取导出数据的 API 接口,即可导出文件,导出效果如下:

六、总结

可以看出,自定义字典查询导出方式,其实和 JeecgBoot 的 Autopoi 方式都大同小异,后面是发现了 JeecgBoot 的 Autopoi 和 hutool 的读取文件 ExcelReader 有冲突,放弃了 JeecgBoot 的 Autopoi,EasyPoi 确实是一款强大的 Excel 操作产品!!!

如您在阅读中发现不足,欢迎留言!!!

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服