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


    最近在学习使用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
  • 相关阅读:
    Activiti服务类-4 HistoryService服务类
    Activiti服务类-3 FormService服务类
    知识碎片
    web 框架
    pymysql 模块
    Bootstrap-按钮
    Bootstrap-下拉菜单
    前端之jQuery03 插件
    Python打印进度条
    JavaScript碎片
  • 原文地址:https://www.cnblogs.com/hebaibai/p/10710491.html
Copyright © 2020-2023  润新知