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

com.ecfront.easybi.excelconverter.inner.tojava.FastJavaConvertStrategy Maven / Gradle / Ivy

package com.ecfront.easybi.excelconverter.inner.tojava;

import com.ecfront.easybi.excelconverter.exchange.annotation.Map2J;
import com.ecfront.easybi.excelconverter.inner.util.ExcelHelper;
import com.ecfront.easybi.excelconverter.inner.util.MappingHelper;

import java.lang.reflect.Field;
import java.text.ParseException;
import java.util.*;


public class FastJavaConvertStrategy extends AbsJavaConvertStrategy {


    private Map> MAPPING = new HashMap<>();

    @Override
    public Object doConvert() throws Exception {
        assembleMapping(beanClass, null);
        return assembleBean(beanClass, 0);
    }

    //组装MAPPING,获取所有field和其对应的单元格
    private  void assembleMapping(Class beanClass, List parentArea) {
        String area;
        Class subClass;
        for (Field field : beanClass.getDeclaredFields()) {
            if (!field.isAnnotationPresent(Map2J.class)) {
                continue;
            }
            area = field.getAnnotation(Map2J.class).value();
            if (null == area || "".equals(area)) {
                continue;
            }
            //保存字段与区域
            MAPPING.put(beanClass.getName() + "." + field.getName(), assembleArea(area, parentArea));
            subClass = MappingHelper.getSubClass(field);
            if (null != subClass) {
                //递归bean
                assembleMapping(subClass, MAPPING.get(beanClass.getName() + "." + field.getName()));
            }
        }
    }

    //组装区域
    private List assembleArea(String area, List parentArea) {
        List resultAreas = new ArrayList<>();
        if (!area.contains(":") && !area.contains(",")) {
            int[] idx = MappingHelper.getCellIdx(area, sheet);
            if (-1 == idx[0] || -1 == idx[1]) {
                //把类似"A"这样的区域改为"A:A",因为它本身就是一个区域
                area = area + ":" + area;
            }
        }
        if (area.contains(":")) {
            //单元格区域处理
            //获取首末单元格,对没有指定相应行/列的(多在子对象中)按父区域的边界组装
            int[] startIdx = MappingHelper.getCellIdx(area.split(":")[0], sheet);
            int[] endIdx = MappingHelper.getCellIdx(area.split(":")[1], sheet);
            if (-1 == startIdx[0]) {
                startIdx[0] = getRowNum(parentArea, false);
            }
            if (-1 == startIdx[1]) {
                startIdx[1] = getColNum(parentArea, startIdx[0], false);
            }
            if (-1 == endIdx[0]) {
                endIdx[0] = getRowNum(parentArea, true);
            }
            if (-1 == endIdx[1]) {
                endIdx[1] = getColNum(parentArea, endIdx[0], true);
            }
            for (int i = startIdx[0]; i <= endIdx[0]; i++) {
                for (int j = startIdx[1]; j <= endIdx[1]; j++) {
                    addArea(new int[]{i, j}, parentArea, resultAreas);
                }
            }
        } else if (area.contains(",")) {
            //多个单元格处理
            String[] areas = area.split(",");
            for (String a : areas) {
                addArea(a, parentArea, resultAreas);
            }
        } else {
            //单一单元格处理
            addArea(area, parentArea, resultAreas);
        }
        return resultAreas;
    }

    //根据父区域或工作表可用区域获取行首/末
    private int getRowNum(List parentArea, boolean isLast) {
        if (null == parentArea || parentArea.size() == 0) {
            if (isLast) {
                return sheet.getLastRowNum();
            } else {
                return sheet.getFirstRowNum();
            }
        } else {
            if (isLast) {
                return parentArea.get(parentArea.size() - 1)[0];
            } else {
                return parentArea.get(0)[0];
            }
        }
    }

    //根据父区域或工作表可用区域获取列首/末,父区域不可用时列末需要指定行号
    private int getColNum(List parentArea, int rowIdx, boolean isLast) {
        if (null == parentArea || parentArea.size() == 0) {
            if (isLast) {
                return sheet.getRow(rowIdx).getLastCellNum();
            } else {
                return sheet.getRow(rowIdx).getFirstCellNum();
            }
        } else {
            if (isLast) {
                return parentArea.get(parentArea.size() - 1)[1];
            } else {
                return parentArea.get(0)[1];
            }
        }
    }

    private void addArea(String area, List parentArea, List resultAreas) {
        int[] idx = MappingHelper.getCellIdx(area, sheet);
        addArea(idx, parentArea, resultAreas);
    }

    private void addArea(int[] idx, List parentArea, List resultAreas) {
        idx = ExcelHelper.getMergedValueCell(idx, mergedCells);
        if (isAddAreaAble(idx, parentArea)) {
            resultAreas.add(idx);
        }
    }

    //是否可以添加,要求指定的单元格在父区域内
    private boolean isAddAreaAble(int[] idx, List parentArea) {
        if (null == idx || idx[0] < 0 || idx[1] < 0) {
            return false;
        }
        if (null == parentArea || parentArea.size() == 0) {
            return true;
        }
        int len = parentArea.size();
        for (int[] aParentArea : parentArea) {
            if (idx[0] == aParentArea[0] && idx[1] == aParentArea[1]) {
                return true;
            }
        }
        return false;
    }

    //组装Bean,mapIdx主要用于容器成员变量,每次循环加1
    private  O assembleBean(Class beanClass, int mapIdx) throws IllegalAccessException, InstantiationException, ParseException {
        O obj = beanClass.newInstance();
        Class subClass;
        Object result;
        for (Field field : beanClass.getDeclaredFields()) {
            if (!field.isAnnotationPresent(Map2J.class)) {
                continue;
            }
            field.setAccessible(true);
            subClass = MappingHelper.getSubClass(field);
            if (null != subClass) {
                if (Collection.class.isAssignableFrom(field.getType())) {
                    //容器组装,窗口的size由 MAPPING 确定
                    Collection collection = (Collection) field.get(obj);
                    //获取对应字段的区域列表
                    List m = MAPPING.get(beanClass.getName() + "." + field.getName());
                    if (null != m && m.size() > 0) {
                        //根据区域中首末单元格行号的差计算size
                        int len = m.get(m.size() - 1)[0] - m.get(0)[0] + 1;
                        for (int i = 0; i < len; i++) {
                            collection.add(assembleBean(subClass, i));
                        }
                    }
                } else {
                    field.set(obj, assembleBean(subClass, mapIdx));
                }
            } else {
                result = getFieldValue(beanClass.getName() + "." + field.getName(), field, mapIdx);
                if (null != result) {
                    field.set(obj, result);
                }
            }
        }
        return obj;
    }

    //获取结果值
    private Object getFieldValue(String key, Field field, int mapIdx) throws ParseException {
        int[] area = MAPPING.get(key).get(mapIdx);
        return getFinalValue(field, area[0], area[1]);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy