TableHeadHelper.java 4.47 KB
package com.yanzuoguang.util.table;

import com.yanzuoguang.util.helper.StringHelper;

import java.util.*;

/**
 * 表头计算
 *
 * @author 颜佐光
 */
public class TableHeadHelper {

    public static final String SPLIT = ":";

    /**
     * 获取父节点路径
     *
     * @param from 子节点
     * @return 父节点路径
     */
    public static String getParentPath(String from) {
        if (from.lastIndexOf(SPLIT) >= 0) {
            return from.substring(0, from.lastIndexOf(":"));
        } else {
            return StringHelper.EMPTY;
        }
    }

    /**
     * 对列头进行排序
     *
     * @param columns 对列头进行排序
     */
    public static void sort(String[] columns) {
        // 列头排序,同级元素排序
        Arrays.sort(columns, new Comparator<String>() {
            @Override
            public int compare(String from, String to) {
                String fromParent = getParentPath(from);
                String toParent = getParentPath(to);
                if (fromParent.length() == 0 || toParent.length() == 0) {
                    return 0;
                }
                return fromParent.compareTo(toParent);
            }
        });
    }

    /**
     * 列头函数
     *
     * @param columns 计算列头
     * @return 返回计算结果
     */
    public static TableHead getTableHead(String... columns) {
        TableHead head = new TableHead();
        head.setTotalColumn(columns.length);
        // 节点关系映射
        Map<String, TableHeadItem> headMap = new LinkedHashMap<>();
        // 当前节点的子节点元素
        Map<String, List<TableHeadItem>> headSubs = new LinkedHashMap<>();

        // 计算每个单元格的大小和占用的行、列
        for (int columnPos = 0; columnPos < columns.length; columnPos++) {
            String column = columns[columnPos];
            int totalRow = setHead(head, headMap, headSubs, column, columnPos);
            head.setTotalRow(Math.max(totalRow, head.getTotalRow()));
        }

        //  计算最后一行的合并数量
        for (Map.Entry<String, TableHeadItem> item : headMap.entrySet()) {
            TableHeadItem headItem = item.getValue();
            if (headItem.isDataColumn()) {
                headItem.setRowCell(head.getTotalRow() - headItem.getRow());
            }
        }

        return head;
    }

    /**
     * 设置列头相关信息
     *
     * @param head      列头对象集合
     * @param headMap   列头对象路径映射
     * @param headSubs  列头对象路径映射
     * @param fullPath  来源路径
     * @param columnPos 列位置
     * @return 当前列包含行数
     */
    private static int setHead(TableHead head,
                               Map<String, TableHeadItem> headMap, Map<String, List<TableHeadItem>> headSubs,
                               String fullPath, int columnPos) {
        String[] heads = fullPath.split(":");
        StringBuilder path = new StringBuilder();

        for (int rowIndex = 0; rowIndex < heads.length; rowIndex++) {
            // 列名称
            String column = heads[rowIndex].trim();
            // 父路径与当前节点路径
            String parentPath = path.toString().trim();
            if (rowIndex > 0) {
                path.append(":");
            }
            path.append(column);

            String nowPath = path.toString();
            // 设置当前单元格属性
            if (!headMap.containsKey(nowPath)) {
                TableHeadItem headItem = new TableHeadItem();
                headItem.setRow(rowIndex);
                headItem.setRowCell(1);
                headItem.setColumn(columnPos);
                headItem.setColumnCell(1);
                headItem.setName(column);
                headItem.setPath(nowPath);
                headItem.setDataColumn(fullPath.equals(nowPath));

                // 添加到父元素的子节点
                if (!headSubs.containsKey(parentPath)) {
                    headSubs.put(parentPath, new ArrayList<TableHeadItem>());
                }

                // 添加到当前元素对应缓存
                head.getColumns().add(headItem);
                headMap.put(nowPath, headItem);
                headSubs.get(parentPath).add(headItem);

            } else {
                // 当前单元格合并列增加1
                TableHeadItem headItem = headMap.get(nowPath);
                headItem.setColumnCell(headItem.getColumnCell() + 1);
            }
        }
        return heads.length;
    }
}