反射机制实现Excel导入动态字段的处理

851 阅读1分钟

需求

需要Excel导出一个对象的某些字段,修改后再Excel导入进行更新。 当然有几个核心字段是必须导出的,比如主键或代码。

难点在于导出的字段不确定是哪些,如何映射到对象。

通过反射进行映射

List<String> headList = datas.get(0);
Map<String, Integer> map = new HashMap<>(256);
for (String s : headList) {
    map.put(s, map.size());
}
List<ExcelYbxxwh> excelYbxxwhs = new ArrayList<>();
Field[] fields = ExcelYbxxwh.class.getDeclaredFields();
for (List<String> list : datas) {
    ExcelYbxxwh excelYbxxwh = new ExcelYbxxwh();
    for (Field field : fields) {
        field.setAccessible(true);
        ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
        if (excelProperty == null){
            continue;
        }
        String[] values = excelProperty.value();
        if (ArrayUtils.isEmpty(values) || values.length !=1){
            continue;
        }
        Integer index = map.get(values[0]);
        if (index == null){
            continue;
        }
        try {
            if(index >= list.size()){
                field.set(excelYbxxwh,"");
            } else {
                field.set(excelYbxxwh,list.get(index));
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    excelYbxxwhs.add(excelYbxxwh);
}


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

    /**
     * The name of the sheet header.
     *
     * <p>
     * write: It automatically merges when you have more than one head
     * <p>
     * read: When you have multiple heads, take the first one
     *
     * @return The name of the sheet header
     */
    String[] value() default {""};

    /**
     * Index of column
     *
     * Read or write it on the index of column,If it's equal to -1, it's sorted by Java class
     *
     * @return Index of column
     */
    int index() default -1;

    /**
     * Force the current field to use this converter.
     *
     * @return Converter
     */
    Class<? extends Converter> converter() default AutoConverter.class;

    /**
     *
     * default @see com.alibaba.excel.util.TypeUtil if default is not meet you can set format
     *
     * @return Format string
     * @deprecated please use {@link com.alibaba.excel.annotation.format.DateTimeFormat}
     */
    @Deprecated
    String format() default "";
}


public class ExcelYbxxwh extends BaseRowModel {
    @ExcelProperty(value = "姓名")
    private String xm;
    @ExcelProperty(value = "身份证件号")
    private String sfzjh;
}