前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >使用Java打印字符串表格(中英文内容不乱)

使用Java打印字符串表格(中英文内容不乱)

作者头像
何白白
发布于 2019-06-28 08:21:34
发布于 2019-06-28 08:21:34
2.8K00
代码可运行
举报
运行总次数:0
代码可运行

使用Java打印字符串表格(中英文内容不乱)

需求

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

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

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

代码

TextForm
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;
    }
}
TextFormBulider
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;
    }

}

例子

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 @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();//打印
 }
结果
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
*****************************
*  name     *  age  *  sex  *
*****************************
*  王麻345  *  21   *2  *
*****************************
*  wzeef    *  21   **
*****************************
图片
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Java实用工具类四:StringUtils工具类
此文仅对自己工作中用到的类进行总结,方便以后的使用。 package com.cn.hnust.util; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRe
芈亓
2022/06/17
7200
LeetCode 付费题目(一)
【题目】Given a binary tree where all the right nodes are either leaf nodes with a sibling (a left node that shares the same parent node) or empty, flip it upside down and turn it into a tree where the original right nodes turned into left leaf nodes. Return the new root.
四火
2022/07/19
2.5K0
Java工具集-字符串(StringUtils)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
cwl_java
2019/10/28
1.6K0
数据结构与算法思想
分治法是基于多项分支递归的一种很重要的算法范式。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。
知一
2021/12/07
4310
数据结构与算法思想
剑指offer(61-67)题解
例如,我们可以把一个只有根节点为1的二叉树序列化为"1,",然后通过自己的函数来解析回这个二叉树
萌萌哒的瓤瓤
2020/08/26
2990
剑指offer(61-67)题解
java实现excel表格导入数据库表「建议收藏」
导入excel就是一个上传excel文件,然后获取excel文件数据,然后处理数据并插入到数据库的过程
全栈程序员站长
2022/09/14
3.1K0
java实现excel表格导入数据库表「建议收藏」
LeetCode 题目解答——155~226 题
[Updated on 9/22/2017] 如今回头看来,里面很多做法都不是最佳的,有的从复杂度上根本就不是最优解,有的写的太啰嗦,有的则用了一些过于 tricky 的方法。我没有为了这个再更新,就让它们去吧。
四火
2022/07/19
7040
LeetCode 题目解答——155~226 题
数据算法之反转排序 | 寻找相邻单词的数量
想处理的问题是:统计一个单词相邻前后两位的数量,如有w1,w2,w3,w4,w5,w6,则:
王知无-import_bigdata
2020/02/10
4740
Java版本的基于计算机视觉的跃动小子保卫主公自动通关计划之执行计划生成篇
微信小程序跃动小子保卫主公自动通关之执行计划,包含了移动1步,2步,3步,4步消除3个元素,4个元素,5个元素,6个元素,7个元素的所有执行计划,共计20036个
九转成圣
2024/11/24
1070
java实现文件对比
web项目需要实现文件内容对比功能,开发语言是java,也就是通过java实现类似于svn的文件对比功能
六月的雨在Tencent
2024/03/29
2330
java实现文件对比
玩转字符串篇--替换的鬼斧神工
本文说明 1.1.问题 今天遇到一个问题,就是如何指定批量代换某些字符串。 场景:比如下面一段markdown,写文章时遇到很多固定的链接时,总是很长一段。 特别是表格里,感觉要崩溃啊,而且万一哪天要换个网址,一个个改还不改疯掉。 不行,得想个办法,再怎么说咱也是会敲些Hello World代码的人,逼格不能输。 Padding是一个可以产生内边距的控件 详情可见:![Padding](https://juejin.im/user/5b42c0656fb9a04fe727eb37/collect
张风捷特烈
2020/04/30
5390
玩转字符串篇--替换的鬼斧神工
LeetCode通关:连刷十四题,回溯算法完全攻略
例如我们在查找二叉树所有路径的时候,查找完一个路径之后,还需要回退,接着找下一个路径。
三分恶
2021/09/23
9820
LeetCode通关:连刷十四题,回溯算法完全攻略
【算法题解】 Day2 字符串
从题目中可知,当矩阵中的某个元素为0时,那么它所在的行与列都将清零,因此,可以先记录下原始矩阵中0的坐标,这里的话,自然而然的就想到了标记数组,伪代码如下:
sidiot
2023/08/31
1460
【算法题解】 Day2 字符串
Kotlin与Java的异同(一)
Kotlin是一种针对Java 平台的新编程语言。Kotlin简洁、安全、务实,并且专注于与Java代码的互操作性。它几乎可以用在现在Java使用的任何地方:服务端开发、Android应用等等。Kotlin 可以很好地和所有现存的Java库和框架一起工作,而且性能和Java旗鼓相当。
全栈程序员站长
2022/09/08
1.9K0
LeetCode 题目解答——Medium 部分(下)
[Updated on 9/22/2017] 如今回头看来,里面很多做法都不是最佳的,有的从复杂度上根本就不是最优解,有的写的太啰嗦,有的则用了一些过于 tricky 的方法。我没有为了这个再更新,就让它们去吧。
四火
2022/07/19
4040
LeetCode 题目解答——Medium 部分(下)
《剑指offer》全部题目-含Java实现
陆续刷了好久,算是刷完了《剑指offer》,以下全部AC代码,不一定性能最优,如有错误或更好解答,请留言区指出,大家共同交流,谢谢~ 1.二维数组中的查找 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 public class Solution { public boolean Find(int target, int [][] array) { if(arra
10JQKA
2018/05/09
3.1K0
《剑指offer》全部题目-含Java实现
java 创建一个JDBC表格模型
创建一个JDBC表格模型 创建一个JDBC表格模型 import javax.swing.*; import javax.swing.table.*; import java.sql.*; import java.util.*; /** an immutable table model built from getting metadata about a table in a jdbc database */ public cla
艳艳代码杂货店
2021/10/29
4200
# Java 一步一步实现高逼格的字符串替换工具(二)
Java 一步一步实现高逼格的字符串替换工具(二) 上一篇实现了一个用于字符串替换的方法,主要是利用 正则 + jdk的字符串替换,本篇则会再之前的基础上走一个扩展 1. 之前的方法存在的问题
一灰灰blog
2018/02/06
1.1K0
# Java  一步一步实现高逼格的字符串替换工具(二)
Java-集合
哈喽!大家好,我是小简。今天开始学习《Java-集合》,此系列是我做的一个 “Java 从 0 到 1 ” 实验,给自己一年左右时间,按照我自己总结的 Java-学习路线,从 0 开始学 Java 知识,并不定期更新所学笔记,期待一年后的蜕变吧!<有同样想法的小伙伴,可以联系我一起交流学习哦!>
小简
2023/01/04
1.2K0
Java-集合
常用的Java开发自定义工具类UtilsTools
日常开发中经常会遇到一些常用频繁的数据类型转换、日期格式转换、非空校验、避免重复造轮子写代码一般我们一般会封装一个常用的Utils开放工具类;
ZhangXianSheng
2019/07/02
2.2K0
常用的Java开发自定义工具类UtilsTools
相关推荐
Java实用工具类四:StringUtils工具类
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验