• 像MySql一样在控制台输出打印漂亮的表格


    还记得大学期间第一次学习MySql数据,对于初学者而言,MySql没有漂亮的UI界面,只有那种黑乎乎的控制台界面,所有数据的展示都在控制台上输出和打印。
    那个时候还是觉得MySql有一点Low,相比较之前学习的Sqlserver,Sqlserver好歹还有一个可以让初学者点击操作的UI界面。
    但是伴随着在计算机领域的不断深入,编程知识的积累,反而却觉得MySql的控制台界面更加地优雅简洁,尤其记得MySql输出打印表格数据的时候,控制台界面上那个标准整齐的字符表格。
    今天我就用一些空余时间,自己实现了一个类似表格输出打印程序。

    实现效果

    在这里,先贴一张实现的最终效果图。
    效果图

    控制台打印表格的难点

    对于控制台而言,打印表格的难点有这些。

    • 难点一,因为输出字符的多样性,不同的字符占位不同,有的字符占1个位置,有的字符占2个位置,而这些字符又组成不同的字符串,复杂难度加大。
    • 难点二,控制台并没有集成的UI框架,表格是无法自适应宽度的,所以需要我们自己计算表格的宽度。
    • 难点三,表格同一列内的数据长度不同,需要对字符串长度不够的表格进行空白文本填充,以保证表格边框的整齐。

    难点解决

    难点一

    因为输出字符的多样性,不同的字符占位长度不同,有的字符占1个位置,有的字符占2个位置,而这些字符又组成不同的字符串,复杂难度加大。
    关于这个问题,我们可以通过Unicode编码来进行区分,对于Unicode值在0-127为英文字符,占1个位置,其余字符占2个位置。

    难点二

    控制台并没有集成的UI框架,表格是无法自适应宽度的,所以需要我们自己计算表格的宽度。
    表格每一列的宽度应该以表格这一列数据中长度最长的数据为标准,这样表格的宽度才能够展示所有内容。
    所以这个问题可以通过计算每一列的字符串的最大的占位数来作为表格的宽度。

    难点三

    表格同一列内的数据长度不同,需要对字符串长度不够的表格进行空白文本填充,以保证表格边框的整齐。
    这个问题在于填充空白文本补齐长度不够的字符串,只需要使用表格列最大占位长度-文本占位长度即可计算出需要填充的空白文本。

    代码实现

    NODE = '+'
    EDGE = '-'
    HIGH = '|'
    SPACE = ' '
    EMPTY = ''
    
    # 获取字符串的占位长度
    def get_string_width(string):
        width = 0
        for char in string:
            width += 1 if ord(char) < 128 and ord(char) >= 0 else 2
        return width
    
    # 打印边框
    def print_edge(widths):
        col_num = len(widths)
        for col in range(col_num):
            width = widths[col]
            # 获取宽度
            print(NODE + EDGE * (width + 2), end=NODE + '\n' if col == col_num - 1 else EMPTY)
    
    # 打印数据
    def pritn_data(widths, data):
        col_num = len(widths)
        for col in range(col_num):
            width = widths[col]
            col_data = data[col] if len(data) > col else None
            if type(col_data) == int:
                content = SPACE * (width - get_string_width(str(col_data)) + 1) + str(col_data) + SPACE
            else:
                content = SPACE + str(col_data) + SPACE * (width - get_string_width(str(col_data)) + 1)
            print(HIGH + content, end=HIGH + '\n' if col == col_num - 1 else EMPTY)
    
    
    # 获取数据的最大占位长度
    def get_max_widths(data):
        max_widths = [0 for _ in range(len(data[0]))] if data else []
        for row_data in data:
            for col_index in range(len(row_data)):
                width = get_string_width(str(row_data[col_index]))
                max_widths[col_index] = max(width, max_widths[col_index])
        return max_widths
    
    
    # 打印表格通用方法
    def print_table(data):
        row_num = len(data)
        max_widths = get_max_widths(data)
        for row in range(row_num):
            if row <= 1:
                print_edge(max_widths)
            pritn_data(max_widths, data[row])
            if row == row_num - 1:
                print_edge(max_widths)
    
    
    data = []
    data.append(['序号', '昵称', '性别(1:男0:女)', '手机号码', '地址'])
    data.append([1, '归零者', 1, '17854265423', 'xx省xx市xx区xx东路x号'])
    data.append([2, '歌者', 1, '17854521114', 'xx省xx市xx区xx路xxx-x号'])
    data.append([3, '叶文洁', 0, '18945411454', 'xx省xx市xx区xx东路xx号'])
    data.append([4, '罗辑', 1, '18945414154', 'xx省xx市xx区xx路xxx号xx花园x栋x单元xxx室'])
    
    print_table(data)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    表格优化

    除了具体的表格输出打印逻辑之外,这份代码实现里面还有一部分表格展示的优化逻辑,比如在输出的文本内容前后空格,使得文本展示效果更加美观,比如字符串居左,数字居右显示等等,尽最大可能还原了MySql的表格输出逻辑。

  • 相关阅读:
    分析入门 Python 股票量化交易的原因
    阿里、腾讯、京东、拼多多智慧农业斗法
    CLIP(Contrastive Language-Image Pretraining)
    React设计思路
    Vue源码学习(十二):列队处理(防抖优化,多次调用,只处理一次)
    Paxos 算法详解
    事件相关电位ERP的皮层溯源分析
    std::initializer_list详解
    软件设计师笔记-----系统安全分析与设计
    SpringMVC之JSR303和拦截器
  • 原文地址:https://blog.csdn.net/qq_45193304/article/details/126854872