简介
PrettyTable 是python中的一个第三方库,可用来生成美观的ASCII格式的表格,十分实用。
安装
pip install prettytable
示例
从已有文件创建
CSV
from prettytable import from_csv fp = open("mytable.csv", "r") pt = from_csv(fp) fp.close()
HTML
from prettytable import from_html pts = from_html(html_string)
SQL
from prettytable import from_db_cursor db_cur.execute("SELECT * FROM mytable") pt = from_db_cursor(db_cur)
按行添加数据
##按行添加数据 tb = pt.PrettyTable() tb.field_names = ["City name", "Area", "Population"] # 字段名 tb.add_row(["A1",125, 1158259]) # 增加行 tb.add_row(["B1",595, 1857594]) tb.add_row(["C1", 12, 120900]) tb.add_row(["D1", 135, 205556]) print(tb)
结果
+-----------+------+------------+ | City name | Area | Population | +-----------+------+------------+ | A1 | 125 | 1158259 | | B1 | 595 | 1857594 | | C1 | 12 | 120900 | | D1 | 135 | 205556 | +-----------+------+------------+
按列添加数据
## 按列添加数据 tb.add_column('index',[1,2,3,4]) print(tb)
输出结果
+-----------+------+------------+-------+ | City name | Area | Population | index | +-----------+------+------------+-------+ | A1 | 125 | 1158259 | 1 | | B1 | 595 | 1857594 | 2 | | C1 | 12 | 120900 | 3 | | D1 | 135 | 205556 | 4 | +-----------+------+------------+-------+
使用不同的输出风格
## 使用不同的输出风格 tb.set_style(pt.MSWORD_FRIENDLY) print('--- style:MSWORD_FRIENDLY -----') print(tb) tb.set_style(pt.PLAIN_COLUMNS) print('--- style:PLAIN_COLUMNS -----') print(tb) ## 随机风格,每次不同 tb.set_style(pt.RANDOM) print('--- style:RANDOM-----') print(tb) tb.set_style(pt.DEFAULT) print('--- style:DEFAULT -----') print(tb)
输出结果
--- style:MSWORD_FRIENDLY ----- | City name | Area | Population | | A1 | 125 | 1158259 | | B1 | 595 | 1857594 | | C1 | 12 | 120900 | | D1 | 135 | 205556 | --- style:PLAIN_COLUMNS ----- City name Area Population A1 125 1158259 B1 595 1857594 C1 12 120900 D1 135 205556 --- style:RANDOM----- City name Area Population A1 125 1158259 B1 595 1857594 C1 12 120900 D1 135 205556 --- style:DEFAULT ----- +-----------+------+------------+ | City name | Area | Population | +-----------+------+------------+ | A1 | 125 | 1158259 | | B1 | 595 | 1857594 | | C1 | 12 | 120900 | | D1 | 135 | 205556 | +-----------+------+------------+
# 不打印,获取表格字符串 s = tb.get_string() print(s) # 写入到文件 with open('1.txt', 'a+') as f: f.write(tb.get_string()) # 可以只获取指定列或行 s = tb.get_string(fields=["City name", "Population"],start=1,end=4) print(s)
输出结果
+-----------+------+------------+ | City name | Area | Population | +-----------+------+------------+ | A1 | 125 | 1158259 | | B1 | 595 | 1857594 | | C1 | 12 | 120900 | | D1 | 135 | 205556 | +-----------+------+------------+ +-----------+------------+ | City name | Population | +-----------+------------+ | B1 | 1857594 | | C1 | 120900 | | D1 | 205556 | +-----------+------------+
自定义表格输出样式
## 自定义表格输出样式 ### 设定左对齐 tb.align = 'l' ### 设定数字输出格式 tb.float_format = "2.2" ### 设定边框连接符为'*" tb.junction_char = "*" ### 设定排序列 tb.sortby = "Population" ### 设定排序方式 tb.reversesort=True ### 设定左侧不填充空白字符 tb.left_padding_width = 0 print(tb)
输出结果
*----------*-----*-----------* |City name |Area |Population | *----------*-----*-----------* |B1 |595 |1857594 | |C1 |12 |120900 | |A1 |125 |115825.90 | |D1 |135 |20555.60 | *----------*-----*-----------*
## 不显示边框 tb.border = 0 print(tb) ## 修改边框分隔符 tb.set_style(pt.DEFAULT) tb.horizontal_char = '+' print(tb)
输出结果
City name Area Population B1 595 1857594 C1 12 120900 A1 125 115825.90 D1 135 20555.60 +++++++++++++++++++++++++++++++++ | City name | Area | Population | +++++++++++++++++++++++++++++++++ | B1 | 595 | 1857594 | | C1 | 12 | 120900 | | A1 | 125 | 115825.90 | | D1 | 135 | 20555.60 | +++++++++++++++++++++++++++++++++
#prettytable也支持输出HTML代码
s = tb.get_html_string() print(s)
输出结果
<table> <tr> <th>City name</th> <th>Area</th> <th>Population</th> </tr> <tr> <td>B1</td> <td>595</td> <td>1857594</td> </tr> <tr> <td>C1</td> <td>12</td> <td>120900</td> </tr> <tr> <td>A1</td> <td>125</td> <td>115825.90</td> </tr> <tr> <td>D1</td> <td>135</td> <td>20555.60</td> </tr> </table>
手动控制样式
可调整选项
- border - 布尔类型参数(必须是True或False)。控制表格边框是否显示。
- header - 布尔类型参数(必须是True或False)。控制表格第一行是否作为表头显示。
- header-style - 控制表头信息的大小写。允许的参数值:“cap”(每个单词首字母大写),“title”(除了介词助词首字母大写),“lower”(全部小写)或者None(不改变原内容格式)。默认参数为None。
- hrules - 设置表格内部水平边线。允许的参数值:FRAME,ALL,NONE。注意这些是在prettytable模块内部定义的变量,在使用之前导入或用类似prettytable.FRAME的方法调用。
- vrules - 设置表格内部竖直边线。允许的参数值:FRAME,ALL,NONE。
- align - 水平对齐方式(None,“l”(左对齐),“c”(居中),“r”右对齐)
- valign - 垂直对齐方式(None,“t”(顶部对齐),“m”(居中),“b”底部对齐)
- int_format - 控制整型数据的格式。
- float_format - 控制浮点型数据的格式。
- padding_width - 列数据左右的空格数量。(当左右padding未设置时生效)
- left_padding_width - 列数据左侧的空格数量。
- right_padding_width - 列数据右侧的空格数量。
- vertical_char - 绘制竖直边线的字符,默认为“|”
- horizontal_char - 绘制水平边线的字符,默认为“-”
- junction_char - 绘制水平竖直交汇点的字符,默认为“+”
用法
# 1 x = PrettyTable() x.border = False x.header = False x.padding_width = 5 # 2 x = PrettyTable(border=False, header=False, padding_width=5) # 1 print(x.get_string(align="l")) # 2 x.align["City name"] = "l" x.align["Population"] = "c" x.align["Area"] = "r" # 3 x.align="l"
案例:从数据库提取数据
Oracle_utils.py
# 用于以清晰、可读的形式输出 Python 数据结构 from sys import modules import sys import os import cx_Oracle from DBUtils.PooledDB import PooledDB BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) # 加入环境变量 from utils import settings from utils import my_logset from utils.Time_utils import run_time """ 通过PooledDB连接Oracle,并完成常用一些操作 """ class Ora_util(object): __pool = None # 连接池对象 _db_info = { 'user': settings.DB_USER, 'pwd': settings.DB_PASSWORD, 'dsn': settings.DB_SID } def __init__(self, db_info=_db_info, arraysize=500): # 日志 self.db_log = my_logset.get_mylogger("oradb_access") self.db_info = db_info self.conn = Ora_util.__getConn(db_info) self.cursor = self.conn.cursor() # 每次从数据库向Python的缓存返回arraysize=100条记录 self.cursor.arraysize = arraysize @staticmethod def __getConn(db_info): # 静态方法,从连接池中取出连接 if Ora_util.__pool is None: __pool = PooledDB(cx_Oracle, user=db_info['user'], password=db_info['pwd'], dsn=db_info['dsn'], mincached=20, maxcached=50) return __pool.connection() # 执行sql @run_time def execute(self, sql, args={}): try: self.db_log.debug('execute sql: {}'.format(sql)) return self.cursor.execute(sql, args) except Exception as e: self.close() raise e # oracle的参数名必须使用:代替,如 userid = :userid def insertOne(self, table, column_dict): column_dict = self.create_params(table, column_dict) keys = ','.join(column_dict.keys()) values = column_dict.values() placeholder = ','.join([':%s' % (v) for v in column_dict.keys()]) ins_sql = 'INSERT INTO %(table)s (%(keys)s) VALUES (%(placeholder)s)' # print(ins_sql % locals()) self.execute(ins_sql % locals(), column_dict) # 获取序列的下一个值,传入sequence的名称 def nextval(self, seq): self.cursor.execute("SELECT %(seq)s.nextval from dual " % locals()) result = self.cursor.fetchall() return result[0][0] # 批量插入数据库,参数一:表名,参数二:['字段1','字段2',...],参数二:[('值1','值2',...),('值1','值2',...)] def insertMany(self, table, columns=[], values=[]): keys = ','.join(columns) placeholder = ','.join([':%s' % (v) for v in columns]) ins_sql = 'INSERT INTO %(table)s (%(keys)s) VALUES(%(placeholder)s)' self.executemany(ins_sql % locals(), values) return self._get_rows_num()
test.py
import os import sys from sys import modules from prettytable import PrettyTable BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) # 加入环境变量 from utils.Oracle_utils import Ora_util if __name__ == '__main__': ora = Ora_util() ora.execute("DROP TABLE python_modules PURGE") create_table = """ CREATE TABLE python_modules ( module_name VARCHAR2(50) NOT NULL, file_path VARCHAR2(300) NOT NULL, t_id INT NOT NULL ) """ # 执行创建表 create_flag = ora.execute(create_table) # 得到表所有列 print(ora.get_columns('python_modules')) # 添加模块信息 M = [] count = 1 for m_name, m_info in modules.items(): try: M.append((m_name, m_info.__file__, count)) count += 1 except AttributeError: pass print(len(M)) print(ora.insertMany('python_modules',['module_name', 'file_path','t_id'],M)) ora.commit() from prettytable import from_db_cursor tb = from_db_cursor(ora.execute('select * from python_modules')) ### 设定左对齐 tb.align = 'l' ### 设定T_ID右对齐 tb.align["T_ID"]="r" ### 设定数字输出格式 tb.float_format = "2.2" ### 设定边框连接符为'*" tb.junction_char = "*" ### 设定排序列 tb.sortby = "T_ID" ### 设定排序方式 tb.reversesort = True ### 设定左侧不填充空白字符 tb.left_padding_width = 0 print(tb)
输出结果
[2018-05-31 12:02:07 - DEBUG - oradb_access - Oracle_utils.py - execute- 99 ] execute sql: DROP TABLE python_modules PURGE [2018-05-31 12:02:07 - DEBUG - runtime - Time_utils.py - decor- 51 ] func execute run 0.1400 s [2018-05-31 12:02:07 - DEBUG - oradb_access - Oracle_utils.py - execute- 99 ] execute sql: CREATE TABLE python_modules ( module_name VARCHAR2(50) NOT NULL, file_path VARCHAR2(300) NOT NULL, t_id INT NOT NULL ) [2018-05-31 12:02:08 - DEBUG - runtime - Time_utils.py - decor- 51 ] func execute run 0.0620 s [2018-05-31 12:02:08 - DEBUG - oradb_access - Oracle_utils.py - execute- 99 ] execute sql: select lower(column_name) column_name from user_tab_columns where table_name=upper('python_modules') [2018-05-31 12:02:08 - DEBUG - runtime - Time_utils.py - decor- 51 ] func execute run 0.0030 s [2018-05-31 12:02:08 - DEBUG - oradb_access - Oracle_utils.py - executemany- 139 ] executemany sql:INSERT INTO python_modules (module_name,file_path,t_id) VALUES(:module_name,:file_path,:t_id) ['module_name', 'file_path', 't_id'] [2018-05-31 12:02:08 - DEBUG - runtime - Time_utils.py - decor- 51 ] func executemany run 0.0650 s [2018-05-31 12:02:08 - DEBUG - oradb_access - Oracle_utils.py - execute- 99 ] execute sql: select * from python_modules [2018-05-31 12:02:08 - DEBUG - runtime - Time_utils.py - decor- 51 ] func execute run 0.0090 s *------------------------------*-------------------------------------------------------------------------*-----* |MODULE_NAME |FILE_PATH |T_ID | *------------------------------*-------------------------------------------------------------------------*-----* |utils.Time_utils |C:UserschinaPycharmProjectspython_utilsutilsTime_utils.py | 87 | |queue |C:Program FilesPython36libqueue.py | 86 | |_compat_pickle |C:Program FilesPython36lib\_compat_pickle.py | 85 | |struct |C:Program FilesPython36libstruct.py | 84 | |pickle |C:Program FilesPython36libpickle.py | 83 | |select |C:Program FilesPython36DLLsselect.pyd | 82 | |selectors |C:Program FilesPython36libselectors.py | 81 | |_socket |C:Program FilesPython36DLLs\_socket.pyd | 80 | |socket |C:Program FilesPython36libsocket.py | 79 | |logging.handlers |C:Program FilesPython36liblogginghandlers.py | 78 | |string |C:Program FilesPython36libstring.py | 77 | |logging |C:Program FilesPython36liblogging\__init__.py | 76 | |utils.my_logset |C:UserschinaPycharmProjectspython_utilsutilsmy_logset.py | 75 | |utils.settings |C:UserschinaPycharmProjectspython_utilsutilssettings.py | 74 | |DBUtils.SteadyDB |C:Program FilesPython36libsite-packagesDBUtilsSteadyDB.py | 73 | |token |C:Program FilesPython36lib oken.py | 72 | |tokenize |C:Program FilesPython36lib okenize.py | 71 | |linecache |C:Program FilesPython36liblinecache.py | 70 | |traceback |C:Program FilesPython36lib raceback.py | 69 | |threading |C:Program FilesPython36lib hreading.py | 68 | |DBUtils.PooledDB |C:Program FilesPython36libsite-packagesDBUtilsPooledDB.py | 67 | |DBUtils |C:Program FilesPython36libsite-packagesDBUtils\__init__.py | 66 | |cx_Oracle |C:Program FilesPython36libsite-packagescx_Oracle.cp36-win_amd64.pyd | 65 | |_decimal |C:Program FilesPython36DLLs\_decimal.pyd | 64 | |numbers |C:Program FilesPython36lib umbers.py | 63 | |decimal |C:Program FilesPython36libdecimal.py | 62 | |datetime |C:Program FilesPython36libdatetime.py | 61 | |utils.Oracle_utils |C:UserschinaPycharmProjectspython_utilsutilsOracle_utils.py | 60 | |_markupbase |C:Program FilesPython36lib\_markupbase.py | 59 | |html.parser |C:Program FilesPython36libhtmlparser.py | 58 | |html.entities |C:Program FilesPython36libhtmlentities.py | 57 | |html |C:Program FilesPython36libhtml\__init__.py | 56 | |unicodedata |C:Program FilesPython36DLLsunicodedata.pyd | 55 | |textwrap |C:Program FilesPython36lib extwrap.py | 54 | |bisect |C:Program FilesPython36libisect.py | 53 | |_hashlib |C:Program FilesPython36DLLs\_hashlib.pyd | 52 | |hashlib |C:Program FilesPython36libhashlib.py | 51 | |random |C:Program FilesPython36lib andom.py | 50 | |sre_constants |C:Program FilesPython36libsre_constants.py | 49 | |sre_parse |C:Program FilesPython36libsre_parse.py | 48 | |sre_compile |C:Program FilesPython36libsre_compile.py | 47 | |enum |C:Program FilesPython36libenum.py | 46 | |re |C:Program FilesPython36lib e.py | 45 | |csv |C:Program FilesPython36libcsv.py | 44 | |copyreg |C:Program FilesPython36libcopyreg.py | 43 | |copy |C:Program FilesPython36libcopy.py | 42 | |prettytable |C:Program FilesPython36libsite-packagesprettytable.py | 41 | |encodings.cp437 |C:Program FilesPython36libencodingscp437.py | 40 | |contextlib |C:Program FilesPython36libcontextlib.py | 39 | |importlib.machinery |C:Program FilesPython36libimportlibmachinery.py | 38 | |importlib.abc |C:Program FilesPython36libimportlibabc.py | 37 |