springboot项目利用easypoi导入导出(包括一对多导出的动态列选择,以及普通导入)

springboot项目利用easypoi导入导出(包括一对多导出的动态列选择,以及有错误数据导入返回错误信息)

因为项目只涉及到一对多的导出,以及普通的导入,所以,本文只会涉及这方面的使用

导入的时候,有校验,如果有错误数据,就会返回错误数据的所在行,以及错误信息(如果需要返回错误信息的所在的那几行数据以及错误信息的excel文件的话,可以看看第三个参考文章,这个项目最开始是做的返回excel文件,最后又取消了)

参考了一下文章(排名不分先后):

  1. easypoi的官方文档
  2. 使用easypoi根据表头信息动态导出
  3. 微服务中EasyPoi上传Excel文件带校验并返回错误信息
  4. easyPOI基本用法
  5. Springboot 导入导出Excel ,一对多关系,复合表格、合并单元格数据
  6. SpringBoot实现Excel导入导出,好用到爆,POI可以扔掉了!

一. 前置准备

1. 在pom.xml中导入依赖

<dependency>
			<groupId>cn.afterturn</groupId>
			<artifactId>easypoi-base</artifactId>
			<version>4.1.0</version>
		</dependency>
		<dependency>
			<groupId>cn.afterturn</groupId>
			<artifactId>easypoi-web</artifactId>
			<version>4.1.0</version>
		</dependency>
		<dependency>
			<groupId>cn.afterturn</groupId>
			<artifactId>easypoi-annotation</artifactId>
			<version>4.1.0</version>
		</dependency>

		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-validator</artifactId>
			<version>5.2.4.Final</version>
		</dependency>

2. application.yml配置环境

# mybatis yml文件配置
mybatis:
  mapper-locations: classpath:mapper/*.xml
  configuration:
    #    映射数据库中的下划线命名到 java 中的驼峰命名
    map-underscore-to-camel-case: true

3. 工具包

MyExcelUtils.java
package com.xxx.template.utils.recruitmentManagement;

import java.lang.reflect.*;

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

import com.byd.template.log.Log;

import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.annotation.ExcelCollection;
import cn.afterturn.easypoi.excel.annotation.ExcelEntity;
import lombok.extern.slf4j.Slf4j;


@Slf4j
public class MyExcelUtils {
   
    /**
     * 修改fields上@Excel注解的name属性,不需要下载的列,name修改增加_ignore.
     * 保存原来的@Excel注解name属性值,本次生成后用来恢复
     * @Params
     *     headers:用户勾选,由前端传来的列名,列名的key必须和 Model字段对应
     *     clazz:model实体类
     *     excelMap:用来记录原值的map,因为用到了递归,这里返回值作为参数传入
     * @return Map<String, String> 原实体类字段名和 @Excel注解 name属性值的映射关系<字段名,@Excel注解 name 属性值>
     */
    public static Map<String, String> dynamicChangeAndSaveSourceAnnotation(List<String> headers, Class clazz, Map<String, String> excelMap) {
   
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
   
            // @Excel注解
            if (field.isAnnotationPresent(Excel.class)) {
   
                boolean flag = true;
                if(headers == null || headers.size()==0){
   
                    flag =true;
                }else{
   
                    for (int i = 0; i < headers.size(); i++) {
   
                        String header = headers.get(i);
                        if (field.getName().equals(header)) {
   
                            flag = false;
                            break;
                        }
                    }
                }
                // 下载列不包括该字段,进行隐藏,并记录原始值
                if (flag) {
   
                    Excel annotation = field.getAnnotation(Excel.class);
                    // 保存注解
                    excelMap.put(field.getName(), annotation.name());
                    InvocationHandler handler = Proxy.getInvocationHandler(annotation);
                    String value = annotation.name().toString();
                    changeAnnotationValue(handler, field.getName() + "_ignore");
                }
                // @ExcelCollection注解
            } else if (field.isAnnotationPresent(ExcelCollection.class) && field.getType().isAssignableFrom(List.class)) {
   
                Type type = field.getGenericType();
                if (type instanceof ParameterizedType) {
   
                    ParameterizedType pt = (ParameterizedType) type;
                    Class collectionClazz = (Class) pt.getActualTypeArguments()[0];
                    // 解决@ExcelCollection如果没有需要下载列的异常,java.lang.IllegalArgumentException: The 'to' col (15) must not be less than the 'from' col (16)
                    // 如果没有需要下载列,将@ExcelCollection忽略
                    Field[] collectionFields = collectionClazz.getDeclaredFields();
                    boolean flag = false;
                    out:
                    for (Field temp : collectionFields) {
   
                        if (!temp.isAnnotationPresent(Excel.class)) {
   
                            continue;
                        }
                        for (int i = 0; i < headers.size(); i++) {
   
                            String header = headers.get(i);
                            if (temp.getName().equals(header)) {
   
                                flag = true;
                                break out;
                            }
                        }
                    }
                    if (flag) {
   
                        dynamicChangeAndSaveSourceAnnotation(headers, collectionClazz, excelMap);
                    } else {
   
                        ExcelCollection annotation = field.getAnnotation(ExcelCollection.class);
                        excelMap.put(field.getName(), annotation.name());
                        InvocationHandler handler = Proxy.getInvocationHandler(annotation);
                        changeAnnotationValue(handler, field.getName() + "_ignore");
                    }
                }
                // @ExcelEntity注解
            } else if (field.isAnnotationPresent(ExcelEntity.class)) {
   
                Class entityClazz = field.getType();
                dynamicChangeAndSaveSourceAnnotation(headers, entityClazz, excelMap);
            }
        }
        return excelMap;
    }
    public static Map<String, String> dynamicChangeAndSaveSourceAnnotation(List<String> headers, List<String> otherHeaders,Class clazz, Map<String, String> excelMap) {
   

        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
   
            // @Excel注解
            if ( field.isAnnotationPresent(Excel.class)) {
   
                boolean flag = true;
                if(headers == null || headers.size()==0){
   
                    flag =true;
                }else{
   
                    for (int i = 0; i < headers.size(); i++) {
   
            
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值