最近在学习使用java来编写cli应用,但是在信息展示上碰到了难题。原因是没有很好工具来展示一个由字符串组成的表格。在git上搜到阿里巴巴有一个叫做 text-ui 的开源项目可以用,但是这个工具在制作表格的时候如果表格内容是中英文混合的,表格就会乱掉。于是就自己写了一个工具类来打印一个字符串组成的表格。

这个工具满足一下使用要求:

  • 可以设置标题
  • 可以设置表格中数据的左右边距
  • 可以设置表格由什么符号组成
  • 可以设置表格数据最大长度

代码如下:

package com.hebaibai.ascmd.text;

import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern; public class TextForm { /**
* 左边距
*/
protected int paddingL = 1; /**
* 右边距
*/
protected int paddingR = 1; /**
* 标题
*/
protected List<String> title = new ArrayList<>(); /**
* 数据
*/
protected List<List<String>> datas = new ArrayList<>(); /**
* 最大列数
*/
protected int maxCol = 0; /**
* 每个单元格最大字符数
*/
protected int colMaxLength = 8; /**
* 表格组成符号
*/
protected char separator = '.'; private TextForm() {
} public static TextFormBulider bulider() {
return new TextFormBulider(new TextForm());
} /**
* 格式化输出表格
*/
public void printFormat() {
List<List<String>> formData = new ArrayList<>();
formData.add(title);
formData.addAll(datas);
Map<Integer, Integer> colMaxLengthMap = colMaxLength(formData);
for (int i = 0; i < formData.size(); i++) {
List<String> row = formData.get(i);
for (int j = 0; j < row.size(); j++) {
Formatter formatter = new Formatter();
String str = row.get(j);
if (str.length() > colMaxLength) {
str = str.substring(0, colMaxLength);
}
int chineseNum = getChineseNum(str);
Integer maxLength = colMaxLengthMap.get(j);
String val = formatter.format("%-" + (maxLength - chineseNum) + "s", str).toString();
row.set(j, val);
}
}
Map<Integer, Integer> colMinBlankLengthMap = colMinBlankLength(formData);
for (int i = 0; i < formData.size(); i++) {
List<String> row = formData.get(i);
for (int j = 0; j < row.size(); j++) {
String val = row.get(j);
Integer minBlankLength = colMinBlankLengthMap.get(j);
val = val.substring(0, val.length() - minBlankLength);
row.set(j, val);
}
}
String line = "";
List<String> rows = new ArrayList<>();
for (List<String> strings : formData) {
String pL = StringUtils.repeat(" ", paddingL);
String pR = StringUtils.repeat(" ", paddingR);
String row = separator + pL + String.join(pL + separator + pR, strings) + pR + separator;
if (line.length() < row.length()) {
line = StringUtils.repeat(separator, row.length());
}
rows.add(row);
}
System.out.println(line);
for (String row : rows) {
System.out.println(row);
System.out.println(line);
}
} /**
* 找到每一列最大的长度
*
* @param formData
* @return
*/
private Map<Integer, Integer> colMaxLength(List<List<String>> formData) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < formData.size(); i++) {
int col = 0;
List<String> strings = formData.get(i);
while (strings.size() > col) {
String val = strings.get(col);
if (val.length() > colMaxLength) {
val = val.substring(0, colMaxLength);
strings.set(col, val);
}
int length = val.getBytes().length;
Integer integer = map.get(col);
if (integer == null) {
map.put(col, length);
} else {
if (integer < length) {
map.put(col, length);
}
}
col++;
}
}
return map;
} /**
* 找到每一列从右开始最小的空格长度
*
* @param formData
* @return
*/
private Map<Integer, Integer> colMinBlankLength(List<List<String>> formData) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < formData.size(); i++) {
int col = 0;
List<String> strings = formData.get(i);
while (strings.size() > col) {
String val = strings.get(col);
int length = 0;
for (int i1 = val.length() - 1; i1 >= 0; i1--) {
if (val.charAt(i1) == ' ') {
length++;
} else {
break;
}
}
Integer integer = map.get(col);
if (integer == null) {
map.put(col, length);
} else {
if (integer > length) {
map.put(col, length);
}
}
col++;
}
}
return map;
} /**
* 获取中文数量
*
* @param val
* @return
*/
private int getChineseNum(String val) {
if (val == null) {
val = "null";
}
String regex = "[\u4e00-\u9fa5|。|,]";
ArrayList<String> list = new ArrayList<String>();
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(val);
while (matcher.find()) {
list.add(matcher.group());
}
int size = list.size();
return size;
}
}

  

package com.hebaibai.ascmd.text;

import java.util.ArrayList;
import java.util.List; public class TextFormBulider {
private TextForm textForm; protected TextFormBulider(TextForm textForm) {
this.textForm = textForm;
} public TextFormBulider title(String... titles) {
if (textForm.maxCol < titles.length) {
textForm.maxCol = titles.length;
}
for (String title : titles) {
if (title == null) {
title = "null";
}
textForm.title.add(title);
}
return this;
} public TextFormBulider paddingL(int paddingL) {
textForm.paddingL = paddingL;
return this;
} public TextFormBulider paddingR(int paddingR) {
textForm.paddingR = paddingR;
return this;
} public TextFormBulider separator(char separator) {
textForm.separator = separator;
return this;
} public TextFormBulider colMaxLength(int colMaxLength) {
textForm.colMaxLength = colMaxLength;
return this;
} public TextFormBulider addRow(String... cols) {
if (textForm.maxCol < cols.length) {
textForm.maxCol = cols.length;
}
List<String> list = new ArrayList<>(cols.length);
for (String col : cols) {
if (col == null) {
col = "null";
}
list.add(col);
}
textForm.datas.add(list);
return this;
} public TextForm finish() {
int titleSize = textForm.title.size();
if (titleSize < textForm.maxCol) {
for (int i = 0; i < textForm.maxCol - titleSize; i++) {
textForm.title.add(null);
}
}
for (List<String> data : textForm.datas) {
int dataSize = data.size();
if (dataSize < textForm.maxCol) {
for (int i = 0; i < textForm.maxCol - dataSize; i++) {
data.add(null);
}
}
}
return textForm;
}
}

  

使用例子:

 @Test
public void printFormat() {
TextForm.bulider()
.title("name", "age", "sex")//设置标题
.addRow("王麻345子", "21", "男2")//添加行
.addRow("wzeefgrerhei", "21", "男")//添加行
.colMaxLength(5)//设置单元格最大数据长度
.separator('*')//设置表格由什么符号构成
.paddingR(2)//右边距
.paddingL(2)//左边距
.finish()//完成
.printFormat();//打印
}

  

输出结果:

*****************************
* name * age * sex *
*****************************
* 王麻345 * 21 * 男2 *
*****************************
* wzeef * 21 * 男 *
***************************** 原文地址:https://www.cnblogs.com/hebaibai/p/10710491.html
个人站地址:https://www.hebaibai.com/?p=371

使用Java打印字符串表格(中英文内容不乱)的更多相关文章

  1. 描述了say_hello函数的具体内容,调用zend_printf系统函数在php中打印字符串

    下载一个php的源代码包,这里使用的是php 4.0.5版,解压后会看到php的根目录下会有README.EXT_SKEL这样一个文件,打开详细阅读了一下,发现了一个非常好用的工具,这个工具可以帮你构 ...

  2. python 打印 str 字符串的实际内容 repr(str)

    python 打印 str 字符串的实际内容 repr(str) s = 'aa' print(repr(s))

  3. java判断字符串内容

    java判断字符串是否全为数字 String str = "032";boolean isNum = str.matches("[0-9]+"); java判断 ...

  4. Java打印

    Java打印 import java.awt.Color; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Gra ...

  5. Java之字符串String,StringBuffer,StringBuilder

    String类: String类即字符串类型,并不是Java的基本数据类型,但可以像基本数据类型一样使用,用双引号括起来进行声明.在Java中用String类的构造方法来创建字符串变量. 声明字符串: ...

  6. Java 打印程序设计实例

    3.1 打印文本 3.1.1 应用场景 假设我们需要打印一个窗体的某个文本编辑域(可能只有几行,也可能包含多页)的内容,并且每页最多打印 54 行,如何实现呢? 3.1.2 解决方法 基本思路如下:首 ...

  7. Java基础-字符串(String)常用方法

    Java基础-字符串(String)常用方法 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.java的API概念 Java的API(API:Application(应用) Pr ...

  8. 《Java程序设计》课堂实践内容总结

    <Java程序设计>课堂实践内容总结 实践一 要求 修改教材P98 Score2.java, 让执行结果数组填充是自己的学号: 提交在IDEA或命令行中运行结查截图,加上学号水印,没学号的 ...

  9. 20145209 2016-2017-2 《Java程序设计》课堂实践内容

    20145209 2016-2017-2 <Java程序设计>课堂实践内容 一.递归 题目详情: public class TestArgs{ public static void mai ...

随机推荐

  1. Git使用方法(精心整理,绝对够用)转载

    Git使用方法(精心整理,绝对够用)   一.git客户端(本地仓库)的一些操作 1.设置账户(需要和github账户设置一致) git config --global user.name xxx g ...

  2. jsp和html的区别

    html是超文本标记语言,只要有浏览器,就可以显示出来了. jsp是java server page就是在java服务器端的页面,需要通过jdk的编译才可以显示在客户端的浏览器上. 不仅如此,jsp还 ...

  3. 如何将他人的SOPC工程转换为自己可以使用的工程

    上篇文章的程序源码在:http://download.csdn.net/detail/noticeable/9921952 源码错误现象: 在下载源码文件解压后,打开系统工程,可以看到quartus ...

  4. zabbix教程

    zabbix官方文档:https://www.zabbix.com/documentation/current/zh/manual zabbix视频教程:https://www.bilibili.co ...

  5. less的功能和介绍

    在全新的css中,经过程序员们的开发和努力.又打造了全新的less样式表的全新界面,只需引入外部样式表即刻套用,加上了函数定义和取值.大大的降低了代码的书写量.也更加方便程序员的调用和修改!

  6. Learning WCF:Life Cycle of Service instance

    示例代码下载地址:WCFDemo1Day 概述 客户端向WCF服务发出请求后,服务端会实例化一个Service对象(实现了契约接口的对象)用来处理请求,实例化Service对象以及维护其生命周期的方式 ...

  7. word文档的python解析

    主要两块,第一个是文件类型的转换,第二个是用docx包去对word文档中的table进行parse 1. 文件格式装换 因为很多各种各样的原因,至今还有一些word文档是doc的格式存的,对于这种,如 ...

  8. css font-family属性设置中文字体乱码

    一般设置字体,个人都喜欢用中文,比如:font-family:"微软雅黑":但是偶尔会出现设置以后字体显示乱码的问题 解决方法[1]: 看看你的CSS文件的第一行有没有:@char ...

  9. Python+Excel+Unittest+HTMLTestRunner实现数据驱动接口自动化测试(二)

    因为小白,这2天研究了好久才算是搞好.先附上一个测试完成后邮件的截图: 上一篇有提到: unittest中实际运行了一个接口的很多条用例,而报告中只会有一条记录.这是因为unittest test c ...

  10. js学习笔记----JavaScript中DOM扩展的那些事

    什么都不说,先上总结的图~   Selectors API(选择符API) querySelector()方法 接收一个css选择符,返回与该模式匹配的第一个元素,如果没有找到匹配的元素,返回null ...