前言
昨天在测试应用的时候,因为要查看数据库表里面的数据,但是又懒得去看数据库里面查找那张表,反而直接代码查看更方便。于是做了一个打印List的工具类,可以将List里面的数据进行打印成一个表格展示,List里面的元素的字段作为表头打印,元素数据作为表体打印。
目前不支持中文对齐,内容为中文会出现对不齐的现象!
代码
package org.example.common;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* author:keaizp
*/
public class PrintUtil {
private static final String SPACE = " ";
private static final String SPLIT_LINE = "-";
/**
* 打印表头
* @param list
* @param fieldWidthList
*/
private static void printHead(List list,List<Integer> fieldWidthList) {
int length = getTableWidth(fieldWidthList);
Object obj = list.get(0);
Field[] fields = obj.getClass().getDeclaredFields();
StringBuilder builder = new StringBuilder();
builder.append("|");
for (int i = 0; i < fields.length; i++) {
int fieldLength = fieldWidthList.get(i);
String fieldName = fields[i].getName();
if(fieldLength<fieldName.length()+1){
fieldName = fieldName.substring(0,fieldLength-1);
}
builder.append(fieldName);
builder.append(SPACE.repeat( fieldWidthList.get(i)- fieldName.length() - 1));
builder.append("|");
}
printSplitLine(length);
System.out.println(builder);
printSplitLine(length);
}
/**
* 打印表体
* @param list
* @param fieldWidthList
*/
private static void printBody(List list,List<Integer> fieldWidthList) {
Object obj = list.get(0);
Field[] fields = obj.getClass().getDeclaredFields();
StringBuilder builder = new StringBuilder();
for (Object o : list) {
builder.setLength(0);
builder.append("|");
for (int i = 0; i < fields.length; i++) {
fields[i].setAccessible(true);
try {
Object fieldValue = fields[i].get(o);
int fieldLength = fieldWidthList.get(i);
builderAppendField(builder, fieldValue, fieldLength);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
System.out.println(builder);
printSplitLine(getTableWidth(fieldWidthList));
}
}
private static void builderAppendField(StringBuilder builder, Object fieldValue, int fieldLength) {
int spaceLength = fieldValue == null ? fieldLength - 4 - 1 : fieldLength - fieldValue.toString().length() - 1;
if (spaceLength >= 0) {
builder.append(fieldValue);
builder.append(" ".repeat(spaceLength));
} else {
builder.append(fieldValue.toString(), 0, fieldLength - 1);
}
builder.append("|");
}
/**
* 通过每个字段的宽度取得表的长度
* @param fieldWidthList
* @return
*/
private static int getTableWidth(List<Integer> fieldWidthList) {
return fieldWidthList.stream().mapToInt(Integer::intValue).sum() + 1;
}
private static void printSplitLine(int size) {
System.out.println(SPLIT_LINE.repeat(size));
}
/**
* 通过List返回每个字段自适应的宽度,取字段名长度和该字段上对象长度的最大值
* @param list
* @return
*/
private static List<Integer> getFieldWidthList(List list) {
Object obj = list.get(0);
Field[] fields = obj.getClass().getDeclaredFields();
return Arrays.stream(fields).map(field -> {
int realLength = field.getName().length();
field.setAccessible(true);
for (Object o : list) {
try {
Object fieldValue = field.get(o);
realLength = Math.max(realLength, fieldValue == null ? 4 : fieldValue.toString().length());
} catch (IllegalAccessException e) {
// Log the error and continue
System.err.println("Error accessing field value: " + e.getMessage());
}
}
int fieldLength = realLength + 1;
fieldLength += (4 - fieldLength % 4);
return fieldLength;
}).collect(Collectors.toList());
}
/**
*
* @param list
* @param width
* @return
*/
private static List<Integer> getFieldWidthList(List list,int width) {
Object obj = list.get(0);
Field[] fields = obj.getClass().getDeclaredFields();
return Arrays.stream(fields).map(o -> width).collect(Collectors.toList());
}
/**
* 打印自适应宽度的List
* @param list
*/
public static void printTable(List list) {
if (list == null || list.size() == 0) {
return;
}
List<Integer> fieldWidthList = getFieldWidthList(list);
//打印表头
printHead(list,fieldWidthList);
//打印表内容
printBody(list,fieldWidthList);
}
/**
* 打印固定宽度的List
* @param list
* @param width
*/
public static void printTableFixed(List list, int width) {
if (list == null || list.size() == 0) {
return;
}
List<Integer> fieldWidthList = getFieldWidthList(list,width);
//打印表头
printHead(list, fieldWidthList);
//打印表内容
printBody(list, fieldWidthList);
}
}
二、使用步骤
这个类提供了两个public方法:
printTable
方法:可以通过List里面的内容自适应,改变每个列的宽度,List里面元素字段长,则列的宽度也会相应增大。printTableFixed
方法:可以设置表格的宽度,如果里面内容大于表格的宽度,内容将会被截取。