Python使用tabulate、PrettyTable打印带边框表格格式错乱求解
问题原因
- 原代码按固定字符步长硬切tabulate输出的完整字符串,没有按字符串自带的换行符拆分每行,换行符被当成普通字符切分到不同切片,原有行结构完全被破坏
- PrettyTable默认会自动计算单元格宽度、添加内边距、触发自动折行,硬切出来的字符串长度和单元格实际可用宽度不匹配,直接导致内容截断、错位、排版错乱
实现方案
方案1:单库实现(推荐,维护成本最低)
不需要同时用tabulate和PrettyTable两个库嵌套,tabulate本身内置了多套带外边框的表格样式,直接配置即可生成规整输出,完全不存在多库嵌套的兼容问题。
import tabulate apps_iter_data = [ {"hello1": "hello1_data","hello2": "hello1_data","hello3": "hello1_data","hello4": "hello1_data","hello5": "hello1_data","hello6": "hello1_data"}, {"hello1": "hello1_data","hello2": "hello1_data","hello3": "hello1_data","hello4": "hello1_data","hello5": "hello1_data","hello6": "hello1_data"}, {"hello1": "hello1_data","hello2": "hello1_data","hello3": "hello1_data","hello4": "hello1_data","hello5": "hello1_data","hello6": "hello1_data"}, {"hello1": "hello1_data","hello2": "hello1_data","hello3": "hello1_data","hello4": "hello1_data","hello5": "hello1_data","hello6": "hello1_data"}, {"hello1": "hello1_data","hello2": "hello1_data","hello3": "hello1_data","hello4": "hello1_data","hello5": "hello1_data","hello6": "hello1_data"}, {"hello1": "hello1_data","hello2": "hello1_data","hello3": "hello1_data","hello4": "hello1_data","hello5": "hello1_data","hello6": "hello1_data"}, {"hello1": "hello1_data","hello2": "hello1_data","hello3": "hello1_data","hello4": "hello1_data","hello5": "hello1_data","hello6": "hello1_data"} ] message_type = "INFO" header = apps_iter_data[0].keys() rows = [x.values() for x in apps_iter_data] # 直接选用带外边框的内置样式,可选值:grid、pretty、rst、simple_grid等 # 如果不需要额外加消息类型标题,直接执行下一行打印即可 # print(tabulate.tabulate(rows, header, tablefmt="grid")) # 需要加顶部INFO标题的实现 table_content = tabulate.tabulate(rows, header, tablefmt="grid") content_width = len(table_content.splitlines()[0]) title_sep = "+" + "-"*(content_width - 2) + "+" title_content = "|" + message_type.center(content_width - 2) + "|" final_output = "\n".join([title_sep, title_content, table_content]) print(final_output)
运行后输出为完全规整的带外边框表格,无错位截断问题。
方案2:保留双库嵌套的修正写法
如果业务要求必须用PrettyTable生成外层边框,放弃硬切字符串的逻辑,先把tabulate生成的内容按原有换行符拆分为独立行,逐行添加到PrettyTable中,同时关闭PrettyTable的自动折行、固定列宽匹配原有表格宽度。
import tabulate import prettytable as pt apps_iter_data = [ # 测试数据与上述一致 ] message_type = "info" header = apps_iter_data[0].keys() rows = [x.values() for x in apps_iter_data] message = tabulate.tabulate(rows, header) # 按原有换行拆分内容行,禁止硬切字符串 message_lines = message.splitlines() content_width = len(message_lines[0]) t = pt.PrettyTable() t.field_names = [message_type.upper()] # 固定列宽,关闭自动折行 t._max_width = {message_type.upper(): content_width} t.hrules = pt.ALL t.padding_width = 1 # 逐行添加原有表格内容 for line in message_lines: t.add_row([line]) print(t)
注意事项
- 处理已经格式化好的定宽文本时,必须按换行符拆分内容,禁止用固定字符步长硬切,避免破坏原有行结构
- 多表格库嵌套使用时,要关闭所有自动宽度调整、自动折行配置,保证宽度计算逻辑统一,避免排版错位
内容的提问来源于stack exchange,提问作者Akshay J
相关产品推荐
相关产品推荐

