最近在学习使用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. GET请求Referer限制绕过总结

    作者:Vulkey_Chen 原文来自:GET请求Referer限制绕过总结 前言 在做测试的时候会遇见这样几个漏洞场景: JSONP跨域劫持 反射XSS GET请求类型攻击 但是,在相对安全的情况下 ...

  2. Go语言常量

    常量是一个简单值的标识符,在程序运行时,不会被修改的量. 常量中的数据类型只能是布尔型.数字型(整数型.浮点型和复数)和字符串型. 常量的定义格式: //const 常量名 类型 值 const id ...

  3. Maven 的安装与配置

    最近公司需要新起一个项目,想使用maven+springmvc+spring+mybatis+mysql实现,以前我们的项目都是传统的老项目,没用过maven,Eclipse版本是GALILEO的,有 ...

  4. 用jQuery修改右键菜单

    概述 以前在网上找过屏蔽右键菜单的代码,也找过屏蔽F12的代码,今天无意之中看到别人的右键菜单很有意思,我也想来搞一个. 思路 建立一个菜单并且隐藏起来. 用window.oncontextmenu屏 ...

  5. Mybatis框架三:DAO层开发、Mapper动态代理开发

    这里是最基本的搭建:http://www.cnblogs.com/xuyiqing/p/8600888.html 接下来做到了简单的增删改查:http://www.cnblogs.com/xuyiqi ...

  6. 使用MultipartFile上传文件

    转载地址:https://www.cnblogs.com/lunaticcoder/p/9813483.html(具体的看这个这个大佬的博客) 依赖包: <!-- 上传文件依赖组件 --> ...

  7. Linux - 参考链接

    01 - Linux系统监控的Shell脚本 常用的主机监控Shell脚本 使用Shell脚本对Linux系统和进程资源进行监控 02 - Linux系统结构 Linux 系统结构详解 03 - Li ...

  8. [视频]K8飞刀 exploit管理功能 演示教程

    [视频]K8飞刀 exp管理功能 演示教程 链接: https://pan.baidu.com/s/1rYb3rh4od3j07TZAAq_smw 提取码: kksa

  9. kafka shutdown停止关闭很慢问题的解决方案

    kafka shutdown停止很慢问题 在数据量大的时候,consumer一次抓取数据的数据很多,进入到业务处理的数据可能有很多, 假设一次poll有1万条数据进入业务程序,而且业务程序是和poll ...

  10. LDA-线性判别分析(一)预备知识

    本来是要调研 Latent Dirichlet Allocation 的那个 LDA 的, 没想到查到很多关于 Linear Discriminant Analysis 这个 LDA 的资料.初步看了 ...