All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ludii.excel.parse.DefaultExcelImportParse Maven / Gradle / Ivy

There is a newer version: 1.1.0
Show newest version
package com.ludii.excel.parse;

import com.ludii.excel.exceptions.ExcelException;
import com.ludii.excel.utils.ExcelUtils;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.ludii.excel.parse.ExcelFieldConfigDefinedItem.GETTER_PREFIX;
import static com.ludii.excel.parse.ExcelFieldConfigDefinedItem.SETTER_PREFIX;

/**
 * @author 陆迪
 * @date 2022/3/24
 */
public class DefaultExcelImportParse implements ExcelImportParse, AutoCloseable {

    private final ExcelImportCellValueReader excelImportCellValueReader;

    private final ExcelFieldConfigParse excelFieldConfigParse;

    private final CellValueTransform cellValueTransform;

    private ExcelImportConfigDefined excelImportConfigDefined;

    private List headerValueList;

    private List> cellValueListList;

    public DefaultExcelImportParse(ExcelImportCellValueReader excelImportCellValueReader, ExcelFieldConfigParse excelFieldConfigParse, CellValueTransform cellValueTransform) {
        this.excelImportCellValueReader = excelImportCellValueReader;
        this.excelFieldConfigParse = excelFieldConfigParse;
        this.cellValueTransform = cellValueTransform;
    }

    @Override
    public List listData() throws InvocationTargetException, InstantiationException, IllegalAccessException {
        List sortDefinedItemList = getSortDefinedItemList();
        Constructor constructor = getConstructor();

        List dataList = new ArrayList<>();
        List> cellValueListList = getCellValueListList();
        for (List cellValueList : cellValueListList) {
            int cellValueSize = cellValueList.size();
            E item = constructor.newInstance();
            // 根据单元格数据给对象赋值
            for (int i = 0; i < sortDefinedItemList.size(); i++) {
                // 注解下标大于表格列数据下标,则意味着后面的数值都为null,故不需要处理
                if (i >= cellValueSize) {
                    continue;
                }
                Object cellValue = cellValueList.get(i);
                if (cellValue == null) {
                    continue;
                }
                ExcelFieldConfigDefinedItem annotationItem = sortDefinedItemList.get(i);
                if (annotationItem == null) {
                    continue;
                }
                ExcelFieldDefined excelField = annotationItem.getExcelField();
                Class valueTypeClazz = annotationItem.getValueType();

                // 字典表转换
                cellValue = cellValueTransform.transformReadValue(cellValue, annotationItem);

                // 如果注解设置了属性值,则使用属性值注入
                if (ExcelUtils.isNotBlank(excelField.attrName())) {
                    ExcelUtils.invokeSetter(item, excelField.attrName(), cellValue);
                } else {
                    if (annotationItem.getField() != null) {
                        ExcelUtils.invokeSetter(item, annotationItem.getField().getName(), cellValue);
                    } else if (annotationItem.getMethod() != null) {
                        //如果注解是在get方法上,则转换为set方法设置值
                        String methodName = annotationItem.getMethod().getName();
                        if (GETTER_PREFIX.equals(methodName.substring(0, 3))) {
                            methodName = SETTER_PREFIX + ExcelUtils.substringAfter(methodName, GETTER_PREFIX);
                        }
                        ExcelUtils.invokeMethod(item, methodName, new Class[]{valueTypeClazz}, new Object[]{cellValue});
                    }
                }
            }
            dataList.add(item);
        }

        return dataList;
    }

    private List getSortDefinedItemList() {
        ExcelImportConfigDefined excelImportConfigDefined = getExcelImportConfigDefined();
        ExcelFieldParseMode excelFieldParseMode = excelImportConfigDefined.getExcelFieldParseMode();

        List definedItemList = excelImportConfigDefined.listExcelFieldAnnotationItem();
        if (ExcelFieldParseMode.sort.equals(excelFieldParseMode)) {
            return definedItemList.stream().sorted((o1, o2) -> {
                // 若有空值,则排序号不变
                if (o1 == null || o2 == null) {
                    return 0;
                }
                return Integer.compare(o1.getExcelField().sort(), o2.getExcelField().sort());
            }).collect(Collectors.toList());
        } else {
            List headerValueList = getHeaderValueList();

            Map definedItemMap = excelImportConfigDefined
                    .listExcelFieldAnnotationItem()
                    .stream()
                    .collect(Collectors.toMap(excelFieldConfigDefinedItem -> excelFieldConfigDefinedItem.getExcelField().title(), item -> item));

            return headerValueList.stream()
                    .map(definedItemMap::get)
                    .collect(Collectors.toList());
        }
    }

    private ExcelImportConfigDefined getExcelImportConfigDefined() {
        if (excelImportConfigDefined == null) {
            excelImportConfigDefined = excelFieldConfigParse.getExcelImportConfigDefined();
        }
        return excelImportConfigDefined;
    }

    private List getHeaderValueList() {
        if (headerValueList == null) {
            headerValueList = excelImportCellValueReader.getHeaderValueList();
        }
        return headerValueList;
    }

    private List> getCellValueListList() {
        if (cellValueListList == null) {
            cellValueListList = excelImportCellValueReader.getCellValueListList();
        }
        return cellValueListList;
    }

    private Constructor getConstructor() {
        ExcelImportConfigDefined excelImportConfigDefined = this.getExcelImportConfigDefined();
        try {
            Class itemClazz = excelImportConfigDefined.getItemClazz();
            return itemClazz.getDeclaredConstructor();
        } catch (NoSuchMethodException e) {
            throw new ExcelException("列表元素对象必须包含一个空参数的构造参数");
        }
    }

    @Override
    public void close() throws Exception {
        if (excelImportCellValueReader != null) {
            excelImportCellValueReader.close();
        }
    }
}