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

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

作者头像
何白白
发布2019-06-28 16:21:34
2.7K0
发布2019-06-28 16:21:34
举报
文章被收录于专栏:何白白开发记录

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

需求

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

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

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

代码

TextForm
代码语言:javascript
复制
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
复制
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
复制
 @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
复制
*****************************
*  name     *  age  *  sex  *
*****************************
*  王麻345  *  21   *  男2  *
*****************************
*  wzeef    *  21   *  男   *
*****************************
图片
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用Java打印字符串表格(中英文内容不乱)
    • 需求
      • 代码
        • 例子
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档