[SpringBoot] 37. SpringBoot integrates EasyPoi custom dictionary to export Excel

Earlier we introduced the use of JeecgBoot's Autopoi to export Excel in SpringBoot . In fact, the bottom layer of Autopoi is also EasyPoi, which is very convenient for Excel import/export. Then EasyPoi is also based on POI. If you want to study this aspect in depth, you can take a look at the native POI import/export method first, you will come back to choose EasyPoi

1. Introduction

The function of EasyPoi is the same as the name easy. The main function is easy, so that a person who has never seen poi can easily write Excel export, Excel template export, Excel import, Word template export, through simple annotations and template language (familiar Expression syntax), complete the previous complicated writing

If you want to learn about JeecgBoot's Autopoi, you can refer to another blog of mine, using JeecgBoot's Autopoi to export Excel in SpringBoot

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

2. Introduce EasyPoi

EasyPoi is also well packaged in SpringBoot, allowing us to quickly use EasyPoi for development in SpringBoot

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

We only need to introduce this dependency, which is a good support for SpringBoot

Three, source code interpretation

1. @Excel source code interpretation

By consulting the source code, it is not difficult to find from the cn.afterturn.easypoi.excel.annotation.Excel annotation

/**
 * Copyright 2013-2015 JueYue ([email protected])
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
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;

/**
 * Excel 导出基本注释
 * @author JueYue
 *  2014年6月20日 下午10:25:12
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Excel {
    
    

    /**
     * 导出时,对应数据库的字段 主要是用户区分每个字段, 不能有annocation重名的 导出时的列名
     * 导出排序跟定义了annotation的字段的顺序有关 可以使用a_id,b_id来确实是否使用
     */
    public String name();

    /**
     * 展示到第几个可以使用a_id,b_id来确定不同排序
     */
    public String orderNum() default "0";

    /**
     * 值得替换  导出是{a_id,b_id} 导入反过来,所以只用写一个
     */
    public String[] replace() default {
    
    };
    /**
     *  字典名称
     */
    public String dict() default  "";
}

The above is the code snippet of the @Excel annotation, we can see that the annotation supports two dictionary replacement methods

  • 1. Replace. This method supports directly writing into the annotation parameters, such as:
@Excel(name = "性别", width = 15, replace = "男_1,女_2")
@TableField("sex")
private Integer sex;

We use 1 for male and 2 for female, so that when we export, we can automatically replace the magic value in the data, but this way we often have to write too much code in the annotation parameters, and our dictionary is often Dynamically changing, such limitations are too great

  • 2. dict, dictionary mode, passed in the dictionary parameters, such as:
@Excel(name = "性别", width = 15, dict = "sex")
@TableField("sex")
private Integer sex;

Here we only pass in the key of the dictionary, so that when we query the data and write to the Excel file, we can dynamically replace the magic value in the data and increase the readability of the data.

2. Interpretation of IExcelDictHandler source code

In the previous step, we already know that the custom dictionary query export is supported in EasyPoi, so how do we implement it? By reading the code in the cn.afterturn.easypoi.handler.inter.IExcelDictHandler interface, the code is as follows:

package cn.afterturn.easypoi.handler.inter;

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

/**
 * @author jueyue on 18-2-2.
 * @version 3.0.4
 */
public interface IExcelDictHandler {
    
    

    /**
     * 返回字典所有值
     * key: dictKey
     * value: dictValue
     * @param dict  字典Key
     * @return
     */
    default public List<Map> getList(String dict) {
    
    
        return null;
    }

    /**
     * 从值翻译到名称
     *
     * @param dict  字典Key
     * @param obj   对象
     * @param name  属性名称
     * @param value 属性值
     * @return
     */
    public String toName(String dict, Object obj, String name, Object value);

    /**
     * 从名称翻译到值
     *
     * @param dict  字典Key
     * @param obj   对象
     * @param name  属性名称
     * @param value 属性值
     * @return
     */
    public String toValue(String dict, Object obj, String name, Object value);
}

Three methods are provided in the interface:

  • 1. GetList, query all the dictionary data under the key through the dictionary key, for example: {"1": "男", "2": "女"} under sex
  • 2. toName, the translation function of the dictionary, from value to name, for example: sex: 1 --> "男", generally used when exporting
  • 3. toValue, contrary to toName, translates from name to value, for example: sex: "男" --> 1, generally used when importing

Now that we know that the dictionary translation interface is provided in EasyPoi, we only need to provide an implementation class and rewrite the methods in the interface. IExcelDictHandlerImpl.java implements the IExcelDictHandler interface. The code is as follows:

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;

/**
 * 支持字典参数设置
 * 举例: @Excel(name = "性别", width = 15, dicCode = "sex")
 * 1、导出的时候会根据字典配置,把值1,2翻译成:男、女;
 * 2、导入的时候,会把男、女翻译成1,2存进数据库;
 *
 * @Author lizhou
 */
@Slf4j
@Component
public class IExcelDictHandlerImpl implements IExcelDictHandler {
    
    

    @Autowired
    private SysDictDetailMapper testSysDictDetailMapper;
    private static SysDictDetailMapper sysDictDetailMapper;

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

    /**
     * 从值翻译到名称
     *
     * @param dict  字典Key
     * @param obj   对象
     * @param name  属性名称
     * @param value 属性值
     * @return
     */
    @Override
    public String toName(String dict, Object obj, String name, Object value) {
    
    
        return sysDictDetailMapper.getTextByDictAndValue(dict, String.valueOf(value));
    }

    /**
     * 从名称翻译到值
     *
     * @param dict  字典Key
     * @param obj   对象
     * @param name  属性名称
     * @param value 属性值
     * @return
     */
    @Override
    public String toValue(String dict, Object obj, String name, Object value) {
    
    
        return null;
    }
}
  • 1. Here we export, only use the toName (translation from value to name) method, so only one method is written
  • 2. We need to use the @Component annotation to load it into the Spring container
  • 3. @PostConstruct This annotation is used to decorate a non-static void() method. The method decorated by @PostConstruct will run when the server loads the Servlet, and will only be executed once by the server. PostConstruct is executed after the constructor, and before the init() method

Fourth, start exporting

1. Define the entity class

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;

/**
 * <p>
 * 用户信息表
 * </p>
 *
 * @author lizhou
 */
@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;
}

The @Excel annotation is explained as follows:

  • name, header name
  • width, column width
  • dict, dictionary key

2. Export API interface

Controller layer provides export 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. Export tools

/**
* 导出excel
*
* @param list 数据集合
* @param pojoClass 数据类型
* @param fileName 文件名称
* @param title 表明
* @param response 响应对象
*/
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());, we passed in a custom dictionary query rule

Five, test export

We call the API interface for exporting data to export the file. The export effect is as follows:

Export file

Export results

Six, summary

It can be seen that the custom dictionary query and export method is actually the same as the Autopoi method of JeecgBoot. Later, it was found that the Autopoi of JeecgBoot and the hutool read file ExcelReader conflicted, and the Autopoi of JeecgBoot was abandoned. EasyPoi is indeed a powerful Excel operation product! ! !

If you find deficiencies in reading, please leave a message! ! !

Guess you like

Origin blog.csdn.net/qq_40065776/article/details/109537996