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

io.github.zouzhiy.excel.handler.CellHandlerRegistry Maven / Gradle / Ivy

The newest version!
/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.github.zouzhiy.excel.handler;

import io.github.zouzhiy.excel.enums.ExcelType;
import io.github.zouzhiy.excel.exceptions.ExcelException;
import io.github.zouzhiy.excel.handler.bigdecimal.BigDecimalBooleanHandler;
import io.github.zouzhiy.excel.handler.bigdecimal.BigDecimalNumberHandler;
import io.github.zouzhiy.excel.handler.bigdecimal.BigDecimalStringHandler;
import io.github.zouzhiy.excel.handler.biginteger.BigIntegerBooleanHandler;
import io.github.zouzhiy.excel.handler.biginteger.BigIntegerNumberHandler;
import io.github.zouzhiy.excel.handler.biginteger.BigIntegerStringHandler;
import io.github.zouzhiy.excel.handler.booleans.BooleanBooleanHandler;
import io.github.zouzhiy.excel.handler.booleans.BooleanNumberHandler;
import io.github.zouzhiy.excel.handler.booleans.BooleanStringHandler;
import io.github.zouzhiy.excel.handler.bytes.*;
import io.github.zouzhiy.excel.handler.calendar.CalendarDateHandler;
import io.github.zouzhiy.excel.handler.calendar.CalendarNumberHandler;
import io.github.zouzhiy.excel.handler.calendar.CalendarStringHandler;
import io.github.zouzhiy.excel.handler.date.DateDateHandler;
import io.github.zouzhiy.excel.handler.date.DateNumberHandler;
import io.github.zouzhiy.excel.handler.date.DateStringHandler;
import io.github.zouzhiy.excel.handler.doubles.DoubleBooleanHandler;
import io.github.zouzhiy.excel.handler.doubles.DoubleDateHandler;
import io.github.zouzhiy.excel.handler.doubles.DoubleNumberHandler;
import io.github.zouzhiy.excel.handler.doubles.DoubleStringHandler;
import io.github.zouzhiy.excel.handler.floats.FloatBooleanHandler;
import io.github.zouzhiy.excel.handler.floats.FloatNumberHandler;
import io.github.zouzhiy.excel.handler.floats.FloatStringHandler;
import io.github.zouzhiy.excel.handler.head.HeadStringHandler;
import io.github.zouzhiy.excel.handler.image.ImageByteCellHandler;
import io.github.zouzhiy.excel.handler.image.ImageFileCellHandler;
import io.github.zouzhiy.excel.handler.image.ImageUrlCellHandler;
import io.github.zouzhiy.excel.handler.ints.IntegerBooleanHandler;
import io.github.zouzhiy.excel.handler.ints.IntegerNumberHandler;
import io.github.zouzhiy.excel.handler.ints.IntegerStringHandler;
import io.github.zouzhiy.excel.handler.list.ListStringStringJoinHandler;
import io.github.zouzhiy.excel.handler.list.ListStringStringSplitHandler;
import io.github.zouzhiy.excel.handler.localdate.LocalDateDateHandler;
import io.github.zouzhiy.excel.handler.localdate.LocalDateNumberHandler;
import io.github.zouzhiy.excel.handler.localdate.LocalDateStringHandler;
import io.github.zouzhiy.excel.handler.localdatetime.LocalDateTimeDateHandler;
import io.github.zouzhiy.excel.handler.localdatetime.LocalDateTimeNumberHandler;
import io.github.zouzhiy.excel.handler.localdatetime.LocalDateTimeStringHandler;
import io.github.zouzhiy.excel.handler.localtime.LocalTimeDateHandler;
import io.github.zouzhiy.excel.handler.localtime.LocalTimeNumberHandler;
import io.github.zouzhiy.excel.handler.localtime.LocalTimeStringHandler;
import io.github.zouzhiy.excel.handler.longs.LongBooleanHandler;
import io.github.zouzhiy.excel.handler.longs.LongNumberHandler;
import io.github.zouzhiy.excel.handler.longs.LongStringHandler;
import io.github.zouzhiy.excel.handler.shorts.ShortBooleanHandler;
import io.github.zouzhiy.excel.handler.shorts.ShortNumberHandler;
import io.github.zouzhiy.excel.handler.shorts.ShortStringHandler;
import io.github.zouzhiy.excel.handler.string.StringBooleanHandler;
import io.github.zouzhiy.excel.handler.string.StringDateHandler;
import io.github.zouzhiy.excel.handler.string.StringNumberHandler;
import io.github.zouzhiy.excel.handler.string.StringStringHandler;
import io.github.zouzhiy.excel.handler.timestamp.TimestampDateHandler;
import io.github.zouzhiy.excel.handler.timestamp.TimestampNumberHandler;
import io.github.zouzhiy.excel.handler.timestamp.TimestampStringHandler;
import io.github.zouzhiy.excel.metadata.Configuration;
import lombok.Getter;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URL;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author zouzhiy
 * @since 2022/7/2
 */
public class CellHandlerRegistry {

    private final ConcurrentHashMap, ExcelType> standardMapping = new ConcurrentHashMap<>(32);

    {
        standardMapping.put(BigDecimal.class, ExcelType.NUMERIC);
        standardMapping.put(BigInteger.class, ExcelType.NUMERIC);
        standardMapping.put(boolean.class, ExcelType.BOOLEAN);
        standardMapping.put(Boolean.class, ExcelType.BOOLEAN);
        standardMapping.put(byte.class, ExcelType.NUMERIC);
        standardMapping.put(Byte.class, ExcelType.NUMERIC);
        standardMapping.put(byte[].class, ExcelType.STRING);
        standardMapping.put(Byte[].class, ExcelType.STRING);
        standardMapping.put(Calendar.class, ExcelType.DATE);
        standardMapping.put(java.sql.Date.class, ExcelType.DATE);
        standardMapping.put(Date.class, ExcelType.DATE);
        standardMapping.put(double.class, ExcelType.NUMERIC);
        standardMapping.put(Double.class, ExcelType.NUMERIC);
        standardMapping.put(float.class, ExcelType.NUMERIC);
        standardMapping.put(Float.class, ExcelType.NUMERIC);
        standardMapping.put(int.class, ExcelType.NUMERIC);
        standardMapping.put(Integer.class, ExcelType.NUMERIC);
        standardMapping.put(LocalDate.class, ExcelType.DATE);
        standardMapping.put(LocalDateTime.class, ExcelType.DATE);
        standardMapping.put(LocalTime.class, ExcelType.DATE);
        standardMapping.put(long.class, ExcelType.NUMERIC);
        standardMapping.put(Long.class, ExcelType.NUMERIC);
        standardMapping.put(OffsetDateTime.class, ExcelType.DATE);
        standardMapping.put(OffsetTime.class, ExcelType.DATE);
        standardMapping.put(Short.class, ExcelType.NUMERIC);
        standardMapping.put(String.class, ExcelType.STRING);
        standardMapping.put(Time.class, ExcelType.DATE);
        standardMapping.put(Timestamp.class, ExcelType.DATE);
        standardMapping.put(URL.class, ExcelType.STRING);
        standardMapping.put(List.class, ExcelType.STRING);
    }

    private final Map, CellHandler> allCellHandlerMap = new ConcurrentHashMap<>();

    private final Map, List>> cellHandlerListMap = new ConcurrentHashMap<>();

    @Getter
    private final Configuration configuration;

    public CellHandlerRegistry(Configuration configuration) {
        this.configuration = configuration;

        register(new BigDecimalBooleanHandler());
        register(new BigDecimalNumberHandler());
        register(new BigDecimalStringHandler());

        register(new BigIntegerBooleanHandler());
        register(new BigIntegerNumberHandler());
        register(new BigIntegerStringHandler());

        register(new BooleanBooleanHandler());
        register(new BooleanNumberHandler());
        register(new BooleanStringHandler());

        register(new ByteArrayBoxStringHandler());
        register(new ByteArrayStringHandler());

        register(new ByteBooleanHandler());
        register(new ByteNumberHandler());
        register(new ByteStringHandler());

        register(new CalendarDateHandler());
        register(new CalendarNumberHandler());
        register(new CalendarStringHandler());

        register(new DateDateHandler());
        register(new DateNumberHandler());
        register(new DateStringHandler());

        register(new DoubleBooleanHandler());
        register(new DoubleDateHandler());
        register(new DoubleNumberHandler());
        register(new DoubleStringHandler());

        register(new FloatBooleanHandler());
        register(new FloatNumberHandler());
        register(new FloatStringHandler());

        register(new IntegerBooleanHandler());
        register(new IntegerNumberHandler());
        register(new IntegerStringHandler());

        register(new ListStringStringJoinHandler());
        register(new ListStringStringSplitHandler());

        register(new LocalDateDateHandler());
        register(new LocalDateNumberHandler());
        register(new LocalDateStringHandler());

        register(new LocalDateTimeDateHandler());
        register(new LocalDateTimeNumberHandler());
        register(new LocalDateTimeStringHandler());

        register(new LocalTimeDateHandler());
        register(new LocalTimeNumberHandler());
        register(new LocalTimeStringHandler());

        register(new LongBooleanHandler());
        register(new LongNumberHandler());
        register(new LongStringHandler());

        register(new ShortBooleanHandler());
        register(new ShortNumberHandler());
        register(new ShortStringHandler());

        register(new StringBooleanHandler());
        register(new StringDateHandler());
        register(new StringNumberHandler());
        register(new StringStringHandler());

        register(new TimestampDateHandler());
        register(new TimestampNumberHandler());
        register(new TimestampStringHandler());

        register(new HeadStringHandler());

        register(new ImageByteCellHandler());
        register(new ImageUrlCellHandler());
        register(new ImageFileCellHandler());
    }

    public void register(CellHandler cellHandler) {
        ExcelStandardMapping excelStandardMapping = cellHandler.getClass().getAnnotation(ExcelStandardMapping.class);
        if (excelStandardMapping != null) {
            this.addStandardMapping(cellHandler.getJavaType(), cellHandler.getExcelType());
        }

        Class javaType = cellHandler.getJavaType();
        List> cellHandlerList = cellHandlerListMap.computeIfAbsent(javaType, k -> new ArrayList<>());

        if (!cellHandlerList.contains(cellHandler)) {
            cellHandlerList.add(cellHandler);
        }

        allCellHandlerMap.put(cellHandler.getClass(), cellHandler);
    }

    public  CellHandler getCellHandler(Class> cellHandlerClazz) {
        //noinspection unchecked
        return (CellHandler) this.getCellHandler(Collections.singletonList(cellHandlerClazz), ExcelType.BLANK);
    }

    public  CellHandler getCellHandler(Class>[] cellHandlerClazz, Class clazz, ExcelType excelType) {
        //noinspection unchecked
        return (CellHandler) this.getCellHandler(Arrays.asList(cellHandlerClazz), clazz, excelType);
    }

    public CellHandler getCellHandler(List>> cellHandlerClazzList, Class clazz, ExcelType excelType) {
        if (cellHandlerClazzList.isEmpty()) {
            return this.getCellHandler(clazz, excelType);
        } else {
            return this.getCellHandler(cellHandlerClazzList, excelType);
        }
    }

    public CellHandler getCellHandler(List>> cellHandlerClazzList, ExcelType excelType) {
        List> cellHandlerList = new ArrayList<>();
        for (Class> cellHandlerClazz : cellHandlerClazzList) {
            CellHandler cellHandler = allCellHandlerMap.get(cellHandlerClazz);
            if (cellHandler == null) {
                continue;
            }
            cellHandlerList.add(cellHandler);
        }
        return getWinnerCellHandler(cellHandlerList, null, excelType);
    }


    public  CellHandler getCellHandler(Class clazz, ExcelType excelType) {
        Class boxClazz = this.getBoxClazz(clazz);
        List> cellHandlerList = cellHandlerListMap.get(boxClazz);

        //noinspection unchecked
        return (CellHandler) getWinnerCellHandler(cellHandlerList, clazz, excelType);
    }

    public List> getAllHandler() {
        return new ArrayList<>(allCellHandlerMap.values());
    }

    /**
     * 根据条件,选出一个最佳匹配的 {@link io.github.zouzhiy.excel.handler.CellHandler}
     * 以不返回空为最大追求结果
     *
     * @param cellHandlerList 第一次筛选匹配的CellHandler列表
     * @param javaClazz       java类型
     * @param excelType       excle单元格格式
     * @return 最匹配的CellHandler
     */
    private CellHandler getWinnerCellHandler(List> cellHandlerList, Class javaClazz, ExcelType excelType) {
        if (cellHandlerList == null || cellHandlerList.isEmpty()) {
            throw new ExcelException("无对应的转换器。%s,%s", javaClazz, excelType);
        }

        if (javaClazz == null) {
            javaClazz = cellHandlerList.get(0).getJavaType();
        }
        // 只有一个,则此元素胜出
        if (cellHandlerList.size() == 1) {
            return cellHandlerList.get(0);
        }

        List> winnerList = new ArrayList<>();
        // excelType匹配的优先级最高
        for (CellHandler cellHandler : cellHandlerList) {
            if (excelType.equals(cellHandler.getExcelType())) {
                winnerList.add(cellHandler);
            }
        }
        if (winnerList.size() > 0) {
            return winnerList.get(0);
        }

        // excelType不匹配的情况下,取标准匹配
        excelType = standardMapping.getOrDefault(javaClazz, ExcelType.NONE);
        for (CellHandler cellHandler : cellHandlerList) {
            if (excelType.equals(cellHandler.getExcelType())) {
                winnerList.add(cellHandler);
            }
        }
        if (winnerList.size() > 0) {
            return winnerList.get(0);
        }

        // 实在匹配不上,就去第一个
        return cellHandlerList.get(0);
    }

    private Class getBoxClazz(Class clazz) {
        Class newClazz = null;
        if (!clazz.isPrimitive()) {
            newClazz = clazz;
        } else if (clazz.equals(boolean.class)) {
            newClazz = Boolean.class;
        } else if (clazz.equals(byte.class)) {
            newClazz = Byte.class;
        } else if (clazz.equals(short.class)) {
            newClazz = Short.class;
        } else if (clazz.equals(int.class)) {
            newClazz = Integer.class;
        } else if (clazz.equals(long.class)) {
            newClazz = Long.class;
        } else if (clazz.equals(float.class)) {
            newClazz = Float.class;
        } else if (clazz.equals(double.class)) {
            newClazz = Double.class;
        }
        return newClazz;
    }

    private void addStandardMapping(Class javaType, ExcelType excelType) {
        standardMapping.put(javaType, excelType);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy