package com.imyeyu.utils; import com.imyeyu.java.bean.CallbackArgReturn; import com.imyeyu.java.bean.timi.TimiCode; import com.imyeyu.java.bean.timi.TimiException; import com.imyeyu.java.ref.Ref; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author 夜雨 * @since 2024-12-18 10:10 */ public class AsciiTable { /** 制表符水平边框 */ private static final String BORDER_H = "─"; /** 制表符垂直边框 */ private static final String BORDER_V = "│"; /** 制表符左上边框 */ private static final String BORDER_TL = "┌"; /** 制表符上边框 */ private static final String BORDER_T = "┬"; /** 制表符右上边框 */ private static final String BORDER_TR = "┐"; /** 制表符左边框 */ private static final String BORDER_L = "├"; /** 制表符十字边框 */ private static final String BORDER_P = "┼"; /** 制表符右边框 */ private static final String BORDER_R = "┤"; /** 制表符左下边框 */ private static final String BORDER_BL = "└"; /** 制表符下边框 */ private static final String BORDER_B = "┴"; /** 制表符右下边框 */ private static final String BORDER_BR = "┘"; private final List> colMappingList = new ArrayList<>(); private final List rowList = new ArrayList<>(); public String render(List dataList) { try { { // 表头 Row header = new Row(); for (int i = 0; i < colMappingList.size(); i++) { Row.Col col = new Row.Col(); col.text = colMappingList.get(i).name; header.colList.add(col); } rowList.add(header); } { // 数据 for (int i = 0; i < dataList.size(); i++) { Row row = new Row(); for (int j = 0; j < colMappingList.size(); j++) { Row.Col col = new Row.Col(); Object objValue; ColMapping tColMapping = colMappingList.get(j); if (tColMapping.itemCallback == null) { objValue = Ref.getFieldValue(dataList.get(i), tColMapping.field, Object.class); } else { objValue = tColMapping.itemCallback.handler(dataList.get(i)); } if (tColMapping.valueCallback != null) { objValue = tColMapping.valueCallback.handler(objValue.toString()); } col.text = objValue.toString(); row.colList.add(col); } rowList.add(row); } } // 对齐渲染 Map colMaxSize = new HashMap<>(); for (int i = 0; i < rowList.size(); i++) { List colList = rowList.get(i).colList; for (int j = 0; j < colList.size(); j++) { String colText = colList.get(j).text; if (!colMaxSize.containsKey(j)) { colMaxSize.put(j, colText.length()); } colMaxSize.put(j, Math.max(colMaxSize.get(j), colText.length())); } } StringBuilder sb = new StringBuilder(); for (int i = 0; i < rowList.size(); i++) { List colList = rowList.get(i).colList; if (i == 0) { // 顶边 sb.append(BORDER_TL); for (int j = 0; j < colList.size(); j++) { sb.append(BORDER_H.repeat(colMaxSize.get(j))); if (j == colList.size() - 1) { sb.append(BORDER_TR); } else { sb.append(BORDER_T); } } sb.append('\n'); } // 数据 for (int j = 0; j < colList.size(); j++) { String text = colList.get(j).text; if (j == 0) { sb.append(BORDER_V); } sb.append(Text.paddedSpaceEnd(text, colMaxSize.get(j))).append(BORDER_V); } sb.append('\n'); if (i != rowList.size() - 1) { // 数据分割 for (int j = 0; j < colList.size(); j++) { if (j == 0) { sb.append(BORDER_L); } sb.append(BORDER_H.repeat(colMaxSize.get(j))); if (j == colList.size() - 1) { sb.append(BORDER_R); } else { sb.append(BORDER_P); } } sb.append('\n'); } else { // 底边 sb.append(BORDER_BL); for (int j = 0; j < colList.size(); j++) { sb.append(BORDER_H.repeat(colMaxSize.get(j))); if (j == colList.size() - 1) { sb.append(BORDER_BR); } else { sb.append(BORDER_B); } } } } return sb.toString(); } catch (IllegalAccessException e) { throw new TimiException(TimiCode.ERROR, e.getMessage(), e); } } public void addHeader(String field) { addHeader(field.substring(0, 1).toUpperCase() + field.substring(1), field); } public void addHeader(String name, String field) { TimiException.required(field, "not found field"); ColMapping colMapping = new ColMapping<>(); colMapping.name = name; colMapping.field = field; colMappingList.add(colMapping); } public void addHeader(ColMapping colMapping) { colMappingList.add(colMapping); } /** * * * @author 夜雨 * @since 2024-12-18 10:16 */ public static class ColMapping extends Row.Col { private String name; private String field; private CallbackArgReturn itemCallback; private CallbackArgReturn valueCallback; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getField() { return field; } public void setField(String field) { this.field = field; } public CallbackArgReturn getItemCallback() { return itemCallback; } public void setItemCallback(CallbackArgReturn itemCallback) { this.itemCallback = itemCallback; } public CallbackArgReturn getValueCallback() { return valueCallback; } public void setValueCallback(CallbackArgReturn valueCallback) { this.valueCallback = valueCallback; } } /** * * * @author 夜雨 * @since 2024-12-18 10:10 */ private static class Row { List colList = new ArrayList<>(); /** * * * @author 夜雨 * @since 2024-12-18 10:10 */ private static class Col { String text; } } }