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

com.moon.poi.excel.TableFactory Maven / Gradle / Ivy

package com.moon.poi.excel;

import com.moon.core.lang.ArrayUtil;
import com.moon.core.util.IteratorUtil;
import com.moon.poi.excel.annotation.TableColumn;
import com.moon.poi.excel.annotation.TableColumnGroup;
import com.moon.poi.excel.annotation.TableRecord;
import org.apache.poi.ss.usermodel.Sheet;

import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;

/**
 * 针对注解的渲染工厂
 *
 * @author moonsky
 * @see TableColumn 标记一个字段
 * @see TableColumnGroup 标记一个实体字段
 * @see TableRecord 标记一个实体
 * * @see TableListable 标记一个列表字段,一个实体里最多只能有一列可迭代
 // * @see TableIndexer 标记一列索引
 */
public class TableFactory extends BaseFactory {

    private final PartRenderer HEAD_RENDERER

        = renderer -> renderer.renderHead(end());

    private final static PartRenderer EMPTY = r -> {};

    /**
     * 当前正在操作的 sheet 表
     */
    private Sheet sheet;
    /**
     * 标题
     */
    private TableTitle title;
    /**
     * 是否渲染表头
     */
    private boolean renderHead = true;
    /**
     * 是否渲染数据
     */
    private boolean renderBody = true;
    /**
     * 禁用缓存
     */
    private boolean cacheDisabled = false;

    public TableFactory(WorkbookProxy proxy, SheetFactory parent) { super(proxy, parent); }

    void setSheet(Sheet sheet) { this.sheet = sheet; }

    @Override
    protected Sheet get() { return getSheet(); }

    public Sheet getSheet() { return sheet; }

    private boolean isCacheDisabled() { return cacheDisabled; }

    /**
     * 设置标题,标题为 null 表示不设置
     *
     * @param title 标题内容
     *
     * @return TableFactory
     */
    public TableFactory title(String title) {
        return titleOf(title == null ? null : TableTitle.of(title));
    }

    /**
     * 设置标题,标题为 null 表示不设置
     *
     * @param title     标题内容
     * @param classname 标题样式
     *
     * @return TableFactory
     */
    public TableFactory title(String title, String classname) {
        return titleOf(title == null ? null : TableTitle.of(title, classname));
    }

    /**
     * 设置标题,标题为 null 表示不设置
     *
     * @param title 标题
     *
     * @return TableFactory
     */
    public TableFactory titleOf(TableTitle title) {
        this.title = title;
        return this;
    }

    /**
     * 设置渲染是否渲染表头和数据内容
     *
     * @param renderHead 是否渲染表头
     * @param renderBody 是否渲染数据内容
     *
     * @return TableFactory
     */
    public TableFactory config(boolean renderHead, boolean renderBody) {
        this.renderHead = renderHead;
        this.renderBody = renderBody;
        return this;
    }

    private PartRenderer getHeaderRenderer() {
        return renderHead ? HEAD_RENDERER : EMPTY;
    }

    private TableTitle getTitle() { return title; }

    private boolean isRenderBody() { return renderBody; }

    /**
     * 是否禁用解析缓存,生产环境下适当缓存可避免频繁解析,提高效率
     * 开发测试环境下可随时修改一些注解配置等
     *
     * @param disabled 是否禁用
     *
     * @return this
     */
    public TableFactory cacheDisabled(boolean disabled) {
        this.cacheDisabled = disabled;
        return this;
    }

    /*
     * -----------------------------------------------------------------------------------
     * 渲染表头和数据
     * -----------------------------------------------------------------------------------
     */

    /**
     * 渲染列表数据,默认解析第一项的类上的配置
     *
     * @param iterator 列表
     * @param       数据类型
     *
     * @return this
     */
    public  TableFactory render(Iterator iterator) { return render(iterator, null); }

    /**
     * 渲染列表数据,如果{@code targetClass}不为{@code null},则解析{@code targetClass}
     * 否则默认解析第一项的类上的配置
     *
     * @param iterator    列表
     * @param targetClass 自定义配置类
     * @param          数据类型
     *
     * @return this
     */
    public  TableFactory render(Iterator iterator, Class targetClass) {
        return doRenderData(iterator, targetClass, getHeaderRenderer());
    }

    /**
     * 渲染列表数据,默认解析第一项的类上的配置
     *
     * @param iterable 列表
     * @param       数据类型
     *
     * @return this
     */
    public  TableFactory render(Iterable iterable) { return render(iterable.iterator()); }

    /**
     * 渲染列表数据,如果{@code targetClass}不为{@code null},则解析{@code targetClass}
     * 否则默认解析第一项的类上的配置
     *
     * @param iterable    列表
     * @param targetClass 自定义配置类
     * @param          数据类型
     *
     * @return this
     */
    public  TableFactory render(Iterable iterable, Class targetClass) {
        return render(iterable.iterator(), targetClass);
    }

    /**
     * 渲染列表数据,默认解析第一项的类上的配置
     *
     * @param stream 列表
     * @param     数据类型
     *
     * @return this
     */
    public  TableFactory render(Stream stream) { return render(stream.iterator()); }

    /**
     * 渲染列表数据,如果{@code targetClass}不为{@code null},则解析{@code targetClass}
     * 否则默认解析第一项的类上的配置
     *
     * @param stream      列表
     * @param targetClass 自定义配置类
     * @param          数据类型
     *
     * @return this
     */
    public  TableFactory render(Stream stream, Class targetClass) {
        return render(stream.iterator(), targetClass);
    }

    /**
     * 渲染数组列表数组,默认解析第一项的类上的配置
     *
     * @param data 数据列表
     * @param   数据类型
     *
     * @return this
     */
    @SafeVarargs
    public final  TableFactory render(T... data) {
        if (data == null) {
            return this;
        }
        Class targetClass = data.getClass().getComponentType();
        return render(IteratorUtil.of(data), targetClass);
    }

    /**
     * 渲染数组列表数组,默认解析第一项的类上的配置
     *
     * @param targetClass 自定义配置类
     * @param data        数据列表
     * @param          数据类型
     *
     * @return this
     */
    @SafeVarargs
    public final  TableFactory render(Class targetClass, T... data) {
        return data == null ? this : render(IteratorUtil.of(data), targetClass);
    }

    /**
     * 渲染任意集合类型,用于预先未知集合数据类型的情况,这里会自动选择合适的类型进行渲染
     * 

* 不支持 Map * * @param collect 集合、数组等 * * @return TableFactory */ public TableFactory renderAll(Object collect) { return renderAll(collect, null); } /** * 渲染任意集合类型,用于预先未知集合数据类型的情况,这里会自动选择合适的类型进行渲染 *

* 不支持 Map * * @param collect 集合、数组等 * @param targetClass 数据项类 * * @return TableFactory */ public TableFactory renderAll(Object collect, Class targetClass) { if (collect == null) { return this; } if (collect instanceof Iterable) { return render((Iterable) collect, targetClass); } if (collect instanceof Object[]) { return render(targetClass, (Object[]) collect); } if (collect instanceof Iterator) { return render((Iterator) collect, targetClass); } if (collect instanceof Stream) { return render((Stream) collect, targetClass); } if (collect.getClass().isArray()) { return render(targetClass, ArrayUtil.toObjectArray(collect)); } throw new UnsupportedOperationException("不支持集合类型:" + collect.getClass()); } /* * ~~~~ actual executor ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ protected SheetFactory end() { return getParentFactory(); } private TableFactory doRenderData( Iterator iterator, Class targetClass, PartRenderer headRenderer ) { SheetFactory factory = end(); Renderer renderer = null; Object first = null; if (targetClass == null) { if (iterator.hasNext()) { T data = iterator.next(); renderer = parseRenderer(data.getClass()); renderer.title(factory, getTitle()); headRenderer.render(renderer); first = data; } } else { renderer = parseRenderer(targetClass); renderer.title(factory, getTitle()); headRenderer.render(renderer); } if (renderer != null && isRenderBody()) { renderer.renderBody(factory, iterator, first); } return this; } private final Map, Renderer> thisCached = new ConcurrentHashMap<>(); private Renderer parseRenderer(Class targetClass) { if (isCacheDisabled()) { return TableUtil.parse(targetClass, this, true); } else { Renderer renderer = thisCached.get(targetClass); if (renderer == null) { renderer = TableUtil.parse(targetClass, this, false); thisCached.put(targetClass, renderer); } return renderer; } } /** * 这实际上只是个代理 */ interface PartRenderer { /** * 渲染表头 * * @param renderer 实际执行的渲染器 */ void render(Renderer renderer); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy