动态模板导入实体

动态模板导入实体

涉及关键类

类名描述
AdapterReturnMessage字段校验返回结果类
AttributeName字段对应列名注解
ExcelVoAdapter字段校验超类
ReadExcel对excel做校验的工具类(关键类)
StringUtils对字符串做校验的工具类
TemplatePo模板Vo,vo需要继承的类
User实列PO
UserVo实列Vo
UserVoAdapter实列校验类

UserVoAdapter校验类,方法命名规则为:实列Vo属性名+Adapter,注意查看实列;

实现思路

在这里插入图片描述

涉及依赖

 <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml-schemas -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>4.1.2</version>
        </dependency>

具体实现

1.AttributeName

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 AttributeName {
    public String value() default "";
}

2.AdapterReturnMessage

import java.io.Serializable;

/**
 * @ClassName AdapterReturnMessage
 * @Description TODO
 * @Version 1.0
 */

public class AdapterReturnMessage implements Serializable {
    private static final long serialVersionUID = -3582477728984396465L;

    /**
     * 返回状态
     */
    private int status;
    /**
     * 返回数据或者消息
     */
    private Object message;
    public int getStatus() {
        return status;
    }
    public void setStatus(int status) {
        this.status = status;
    }
    public Object getMessage() {
        return message;
    }
    public void setMessage(Object message) {
        this.message = message;
    }
}

3.ExcelVoAdapter

public class ExcelVoAdapter {
    AdapterReturnMessage adapterReturnMessage;
}

4.StringUtils


import java.io.Serializable;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ClassName StringUtils
 * @Description 字符串工具类
 * @Version 1.0
 */

public class StringUtils implements Serializable {
    private static final long serialVersionUID = -8222775877681330255L;
    private static Pattern pattern = Pattern.compile("-?[0-9]+(\\\\.[0-9]+)?");

    /**
     * 通过正则表达式判断字符串是否为数字
     * @param str
     * @return
     */
    public static boolean isNumber(String str) {
        // 通过Matcher进行字符串匹配
        Matcher m = pattern.matcher(str);
        // 如果正则匹配通过 m.matches() 方法返回 true ,反之 false
        return m.matches();
    }

    /**
     * 判断字符串是否是空
     * @param str
     * @return
     */
    public static boolean isNull(String str) {
        return !(Objects.nonNull(str) && str.trim().length() > 0);
    }

}

5.TemplatePo

import java.io.Serializable;

/**
 * @ClassName TemplatePo
 * @Description TODO
 * @Version 1.0
 */

public abstract class TemplatePo<T> implements Serializable {
    private static final long serialVersionUID = 4396383350565943517L;
    private AdapterReturnMessage adapterReturnMessage;
    public  T po;

    public abstract T nwePo();
    public T getPo(){
        return po;
    }


    public abstract void setPo(T t);

    public AdapterReturnMessage getAdapterReturnMessage() {
        return adapterReturnMessage;
    }

    public void setAdapterReturnMessage(AdapterReturnMessage adapterReturnMessage) {
        this.adapterReturnMessage = adapterReturnMessage;
    }
}

6.User

package com.excellent.importExcel;

import java.io.Serializable;

/**
 * @ClassName User
 * @Description TODO
 * @Version 1.0
 */

public class User implements Serializable {
    private static final long serialVersionUID = -5735964634195165696L;
    private String name;
    private String code;
    private String loginName;
    private Integer sort;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getLoginName() {
        return loginName;
    }

    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }

    public Integer getSort() {
        return sort;
    }

    public void setSort(Integer sort) {
        this.sort = sort;
    }
}

7.UserVo

package com.excellent.importExcel;

import java.io.Serializable;

/**
 * @ClassName UserVo
 * @Description TODO
 * @Version 1.0
 */

public class UserVo extends TemplatePo<User> implements Serializable {
    private static final long serialVersionUID = -5856364608311260336L;
    @AttributeName("姓名")
    private String name;
    @AttributeName("人员编号")
    private String code;
    @AttributeName("登录名")
    private String loginName;
    @AttributeName("人员排序号")
    private Integer sort;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getLoginName() {
        return loginName;
    }

    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }

    public Integer getSort() {
        return sort;
    }

    public void setSort(Integer sort) {
        this.sort = sort;
    }

    @Override
    public User nwePo() {
        return new User();
    }

    @Override
    public void setPo(User user) {
       super.po = user;
    }

}

8.UserVoAdapter

import java.util.Objects;

/**
 * @ClassName UserVoAdapter
 * @Description 对UserVo的所有属性做数据校验的实现类
 * adapterReturnMessage status为0时认为校验成功,并且message 返回类型为传入po需要类型
 * @Version 1.0
 */

public class UserVoAdapter extends ExcelVoAdapter{

    {
        if (Objects.isNull(this.adapterReturnMessage)) {
            this.adapterReturnMessage = new AdapterReturnMessage();
        }
    }

    /**
     * 姓名校验
     * @param name
     * @return
     */
    private AdapterReturnMessage nameAdapter(String name) {
        if (StringUtils.isNull(name)) {
            this.adapterReturnMessage.setStatus(1);
            this.adapterReturnMessage.setMessage("姓名不能为空");
        }else {
            this.adapterReturnMessage.setStatus(0);
            this.adapterReturnMessage.setMessage(name);
        }
        return this.adapterReturnMessage;
    }

    /**
     * 姓名校验
     * @param code
     * @return
     */
    private AdapterReturnMessage codeAdapter(String code) {
        if (StringUtils.isNull(code)) {
            this.adapterReturnMessage.setStatus(1);
            this.adapterReturnMessage.setMessage("人员编号不能为空");
        }else {
            this.adapterReturnMessage.setStatus(0);
            this.adapterReturnMessage.setMessage(code);
        }
        return this.adapterReturnMessage;
    }

    /**
     * 登录名
     * @param loginName
     * @return
     */
    private AdapterReturnMessage loginNameAdapter(String loginName) {
        if (StringUtils.isNull(loginName)) {
            this.adapterReturnMessage.setStatus(1);
            this.adapterReturnMessage.setMessage("登录名");
        }else {
            this.adapterReturnMessage.setStatus(0);
            this.adapterReturnMessage.setMessage(loginName);
        }
        return this.adapterReturnMessage;
    }

    /**
     * 人员排序号
     * @param sort
     * @return
     */
    private AdapterReturnMessage sortAdapter(String sort) {
        if (StringUtils.isNull(sort)) {
            this.adapterReturnMessage.setStatus(1);
            this.adapterReturnMessage.setMessage("排序号不能为空");
        }else {
            if (StringUtils.isNumber(sort)) {
                int i = Integer.parseInt(sort);
                this.adapterReturnMessage.setStatus(0);
                this.adapterReturnMessage.setMessage(i);
            }else {
                this.adapterReturnMessage.setStatus(1);
                this.adapterReturnMessage.setMessage("sort不是数字");
            }
        }
        return this.adapterReturnMessage;
    }
}

9.ReadExcel

import org.apache.poi.ss.usermodel.*;
import org.springframework.util.SerializationUtils;


import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Objects;

/**
 * @ClassName ReadExcel
 * @Description TODO
 * @Version 1.0
 */

public class ReadExcel {

    public static <T> ArrayList<T> toList(Workbook workbook, String sheetName, int startNum, Class<T> clazz, ExcelVoAdapter excelVoAdapter) {

        ArrayList<T> ts = new ArrayList<T>();
        Sheet sheet = workbook.getSheet(sheetName);
        int lastRowNum = sheet.getLastRowNum()+1;
        if (lastRowNum <= startNum) {
            return ts;
        }
        //列名列
        Row row = sheet.getRow(startNum);
        HashMap<String, String> map = new HashMap<>();
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field field : declaredFields) {
            AttributeName annotation = field.getAnnotation(AttributeName.class);
            if (annotation != null) {
                map.put(annotation.value(),field.getName());
            }
        }
        ArrayList<String> rowHead = getRowHead(row, map);
        ts = getListBean(clazz,startNum,sheet,rowHead,excelVoAdapter);
        return ts;
    }

    /**
     * 返回封装后的对象
     * @param <T>
     * @param clazz
     * @param startNum
     * @param sheet
     * @param rowHead
     * @param excelVoAdapter
     * @return
     */
    private static <T> ArrayList<T> getListBean(Class<T> clazz, int startNum, Sheet sheet, ArrayList<String> rowHead, ExcelVoAdapter excelVoAdapter) {
        ArrayList<T> ts = new ArrayList<T>();
        int lastRowNum = sheet.getLastRowNum() + 1;
        if (lastRowNum <= startNum+1) {
            return ts;
        }
        for (int j = startNum+1; j < lastRowNum; j++) {
            Row row = sheet.getRow(j);
            short lastCellNum = row.getLastCellNum();
            T t = null;
            try {
                t = clazz.newInstance();
                Method getPo = clazz.getSuperclass().getDeclaredMethod("nwePo");
                getPo.setAccessible(true);
                Object invoke = getPo.invoke(t);
                Method setPo = clazz.getDeclaredMethod("setPo",invoke.getClass());
                setPo.setAccessible(true);
                for (int i = 0; i < rowHead.size(); i++) {
                    String cellValue;
                    if (lastCellNum < i) {
                        cellValue = "";
                    }else {
                        Cell cell = row.getCell(i);
                        cellValue = getCellValue(cell);
                    }
                    Field field = t.getClass().getDeclaredField(rowHead.get(i));
                    Field poField = invoke.getClass().getDeclaredField(rowHead.get(i));
                    poField.setAccessible(true);
                    field.setAccessible(true);
                    field.set(t, gettypeValue(cellValue,field));
                    String adapterFieldName = field.getName() + "Adapter";
                    Method adapterMethod = excelVoAdapter.getClass().getDeclaredMethod(adapterFieldName, String.class);
                    adapterMethod.setAccessible(true);
                    AdapterReturnMessage adapterReturnMessage = (AdapterReturnMessage) adapterMethod.invoke(excelVoAdapter, cellValue);
                    boolean b = setStatus(adapterReturnMessage, t, invoke, poField);
                    if (!b){
                        break;
                    }
                }
                setPo.setAccessible(true);
                setPo.invoke(t,invoke);
            } catch (Exception e) {
                e.printStackTrace();
            }
            ts.add(t);
        }
        return ts;
    }

    public static <T> boolean setStatus(AdapterReturnMessage adapterReturnMessage, T t, Object invoke, Field poField) {
        boolean b = false;
        try {
            Field adapterReturnMessageFile = t.getClass().getSuperclass().getDeclaredField("adapterReturnMessage");
            adapterReturnMessageFile.setAccessible(true);
            AdapterReturnMessage adapterReturnMessage2 = (AdapterReturnMessage) adapterReturnMessageFile.get(t);;
            int status = 0;
            boolean isClone = false;
            if (Objects.isNull(adapterReturnMessage2)) {
                adapterReturnMessage2 = objClone(adapterReturnMessage);
            }
            if (Objects.equals(status,adapterReturnMessage.getStatus())) {
                poField.set(invoke,adapterReturnMessage.getMessage());
                    adapterReturnMessage2.setMessage(null);
                b = true;
                adapterReturnMessageFile.set(t, adapterReturnMessage2);
            }else {
                adapterReturnMessageFile.set(t, objClone(adapterReturnMessage));
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return b;

    }

    /**
     * 根据字段类型返回val需要的类型
     * @param val
     * @param type
     * @param <T>
     * @return
     */
    public static  <T> T gettypeValue(String val, Class<T> type) {
        // 把val转换成type类型返回 比如说getVal("123",Integer.class) 返回一个123
        T value = null;
        try {
            Constructor<T> constructor = type.getConstructor(String.class);
            constructor.setAccessible(true);
            value = constructor.newInstance(val);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return value;

    }

    /**
     * 根据Filed类型返回val需要的类型
     *
     * @param val
     * @param field 属性field
     * @return
     */
    public static Object gettypeValue(String val, Field field) {
        Object value = null;
        try {
            Constructor<?> constructor = field.getType().getConstructor(String.class);
            constructor.setAccessible(true);
            value = constructor.newInstance(val);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return value;

    }

    /**
     * 根据表头和表头列名对应字段明map转换为字段名list
     * @param row
     * @param map
     * @return
     */
    private static ArrayList<String> getRowHead(Row row, HashMap<String,String> map) {
        ArrayList<String> attributeLists = new ArrayList<>(map.size());
        short lastCellNum = row.getLastCellNum();
        short firstCellNum = row.getFirstCellNum();
        for (short i = firstCellNum; i < lastCellNum;i++) {
            Cell cell = row.getCell(i);
            String cellValue = getCellValue(cell);
            String attributeName = map.get(cellValue);
            attributeLists.add(attributeName);
        }
        return attributeLists;
    }

    /**
     * 获取单个cell的值
     * @param cell
     * @return
     */
    private static String getCellValue(Cell cell) {
        String cellValue = "";
        DataFormatter formatter = new DataFormatter();
        if (cell != null) {
            switch (cell.getCellType()) {
                case NUMERIC:
                    if (DateUtil.isCellDateFormatted(cell)) {
                        cellValue = formatter.formatCellValue(cell);
                    } else {
                        double value = cell.getNumericCellValue();
                        int intValue = (int) value;
                        cellValue = value - intValue == 0 ? String.valueOf(intValue) : String.valueOf(value);
                    }
                    break;
                case STRING:
                    cellValue = cell.getStringCellValue();
                    break;
                case BOOLEAN:
                    cellValue = String.valueOf(cell.getBooleanCellValue());
                    break;
                case FORMULA:
                    cellValue = String.valueOf(cell.getCellFormula());
                    break;
                case BLANK:
                    cellValue = "";
                    break;
                case ERROR:
                    cellValue = "";
                    break;
                default:
                    cellValue = cell.toString().trim();
                    break;
            }
        }
        return cellValue.trim();
    }

    /**
     * 克隆对象方法
     * @param t
     * @param <T>
     * @return
     */
    public static <T> T objClone(T t) {
        byte[] serialize = SerializationUtils.serialize(t);
        return  (T)SerializationUtils.deserialize(serialize);
    }

}

测试调用

try {
            String sheetName = "人员列表";//工作博名称
            int startNum = 2; //列名列
            String path = "E:\\MemberList_86474400-1.xls";
            File file = new File(path);
            if (!file.exists() && !file.canRead()) {
                return;
            }
            Workbook sheets = WorkbookFactory.create(file);
            sheets.close();
            UserVoAdapter userVoAdapter = new UserVoAdapter();
            ArrayList<UserVo> userVos = ReadExcel.toList(sheets, sheetName, startNum, UserVo.class, userVoAdapter);
            System.out.println(userVos.size());
        } catch (IOException e) {
            e.printStackTrace();
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值