It's so beautiful, use this Python library to output beautiful tables

1 Introduction

Recently, I am writing a small tool in Python. This tool is mainly used to manage the information of various resources, such as Alibaba Cloud's ECS and other information. Because the computer I work on uses LINUX, I want to write a command line in python. The basic function of the management tool is to synchronize the information of Alibaba Cloud resources to the database, and then you can use the command line to query.

Because the information is displayed on the command line, it is well known that the command line is very tiring to display complex text, so I thought that it could be displayed like a table, which would seem more comfortable.

The prettytable library is such a tool, prettytable can print beautiful tables, and supports Chinese quite well (if you try to print tables by yourself, you should know how troublesome it is to deal with Chinese)
2. Installation

prettytable is not a built-in library of python, it can be installed by pip install prettytable.
3. Example

Let's look at an example first:

#!/usr/bin/python
#**coding:utf-8**
import sys
from prettytable import PrettyTable
reload(sys)
sys.setdefaultencoding('utf8')

table = PrettyTable(['编号','云编号','名称','IP地址'])
table.add_row(['1','server01','服务器01','172.16.0.1'])
table.add_row(['2','server02','服务器02','172.16.0.2'])
table.add_row(['3','server03','服务器03','172.16.0.3'])
table.add_row(['4','server04','服务器04','172.16.0.4'])
table.add_row(['5','server05','服务器05','172.16.0.5'])
table.add_row(['6','server06','服务器06','172.16.0.6'])
table.add_row(['7','server07','服务器07','172.16.0.7'])
table.add_row(['8','server08','服务器08','172.16.0.8'])
table.add_row(['9','server09','服务器09','172.16.0.9'])
print(table)

    

The result of running the above example is as follows:

linuxops@deepin:~$ python p.py
+------+----------+----------+------------+
| 编号 |  云编号  |   名称   |   IP地址   |
+------+----------+----------+------------+
|  1   | server01 | 服务器01 | 172.16.0.1 |
|  2   | server02 | 服务器02 | 172.16.0.2 |
|  3   | server03 | 服务器03 | 172.16.0.3 |
|  4   | server04 | 服务器04 | 172.16.0.4 |
|  5   | server05 | 服务器05 | 172.16.0.5 |
|  6   | server06 | 服务器06 | 172.16.0.6 |
|  7   | server07 | 服务器07 | 172.16.0.7 |
|  8   | server08 | 服务器08 | 172.16.0.8 |
|  9   | server09 | 服务器09 | 172.16.0.9 |
+------+----------+----------+------------+

  

In the above example, we imported the form library through form. table instantiates a table library, and adds ['number','cloud number','name','IP address'] as the header. If no header is added, it will be displayed with the default Field+number, for example :

+---------+----------+----------+------------+
| Field 1 | Field 2  | Field 3  |  Field 4   |
+---------+----------+----------+------------+

 

Therefore, in order to see the meaning of each column more intuitively, it is necessary to add a header.
4. Add data

prettytable provides a variety of ways to add data, the most commonly used should be to add data by row and column.
Add data by row table.add_row

In the simple example above, we are adding data by row.

The added data must be in the form of a list, and the length of the list of data must be the same as the length of the header. In actual use, we should pay attention to whether the added data corresponds to the header, which is very important.
Add data by column table.add_column()

See the example below:

#!/usr/bin/python
#**coding:utf-8**
import sys
from prettytable import PrettyTable
reload(sys)
sys.setdefaultencoding('utf8')

table = PrettyTable()
table.add_column('项目', ['编号','云编号','名称','IP地址'])
table.add_column('值', ['1','server01','服务器01','172.16.0.1'])
print(table)

  

The results are as follows:

+-------+--------+------------+
| index | 项目 |    值     |
+-------+--------+------------+
|   1   |  编号  |     1      |
|   2   | 云编号 |  server01  |
|   3   |  名称  |  服务器01   |
|   4   | IP地址 | 172.16.0.1 |
+-------+--------+------------+

 

In the above example, we use add_column to add data by column. Adding data by column does not require a header when instantiating the table. Its header is specified when adding a column.

table.add_column('project', ['number','cloud number','name','IP address']) This line of code is an example, the project specifies that the header of this column is named "project", [' ID', 'cloud ID', 'name', 'IP address'] are the column values, which are also lists.
Add data from csv file

PrettyTable not only provides manual addition of data by row and column, but also supports reading data directly from csv files.

#!/usr/bin/python
#**coding:utf-8**
import sys
from prettytable import PrettyTable
from prettytable import from_csv
reload(sys)
sys.setdefaultencoding('utf8')

table = PrettyTable()
fp = open("res.csv", "r")
table = from_csv(fp)
print(table)
fp.close()

 

If you want to read cvs file data, you must import from_csv first, otherwise it will not work. The result of running the above example is as follows:

PS: The csv file cannot be directly renamed through xls, and an error will be reported. If it is xls file, please use save as csv to get csv file
add from sql query value

The data queried from the database can be directly imported into the table for printing. The following example uses sqlite3. The same is true if mysql is used. As long as the data can be queried, it can be imported into the table.

#!/usr/bin/python
#**coding:utf-8**
import sys
from prettytable import PrettyTable
from prettytable import from_db_cursor
import sqlite3
reload(sys)
sys.setdefaultencoding('utf8')

conn = sqlite3.connect("/tmp/aliyun.db")
cur = conn.cursor()
cur.execute("SELECT * FROM res")
table = from_db_cursor(cur)
print(table)

    

The results are as follows:

+------+----------+----------+------------+
| 编号 |  云编号  |   名称   |   IP地址   |
+------+----------+----------+------------+
|  1   | server01 | 服务器01 | 172.16.0.1 |
|  2   | server02 | 服务器02 | 172.16.0.2 |
|  3   | server03 | 服务器03 | 172.16.0.3 |
|  4   | server04 | 服务器04 | 172.16.0.4 |
|  5   | server05 | 服务器05 | 172.16.0.5 |
|  6   | server06 | 服务器06 | 172.16.0.6 |
|  7   | server07 | 服务器07 | 172.16.0.7 |
|  8   | server08 | 服务器08 | 172.16.0.8 |
|  9   | server09 | 服务器09 | 172.16.0.9 |
+------+----------+----------+------------+

    

Import data from HTML

Supports importing from html tables, see the following example:

#!/usr/bin/python
#**coding:utf-8**
import sys
from prettytable import PrettyTable
from prettytable import from_html
reload(sys)
sys.setdefaultencoding('utf8')

html_string='''<table>
<tr>
<th>编号</th>
<th>云编号</th>
<th>名称</th>
<th>IP地址</th>
</tr>
<tr>
<td>1</td>
<td>server01</td>
<td>服务器01</td>
<td>172.16.0.1</td>
</tr>
<tr>
<td>2</td>
<td>server02</td>
<td>服务器02</td>
<td>172.16.0.2</td>
</tr>
</table>'''

table = from_html(html_string)

print(table[0])

   

The results are as follows:

+------+----------+----------+------------+
| 编号 |  云编号  |   名称   |   IP地址   |
+------+----------+----------+------------+
|  1   | server01 | 服务器01 | 172.16.0.1 |
|  2   | server02 | 服务器02 | 172.16.0.2 |
+------+----------+----------+------------+

In the above example, we can import html tables, but the difference is the print statement. When using html tables to import data, the print must be the first element in the list, otherwise it may report [<prettytable.PrettyTable object at 0x7fa87feba590>] such an error.

This is because table is not a PrettyTable object, but a list containing a single PrettyTable object, which is obtained by parsing html, so it cannot print table directly, but needs to print table[0]
5. Table output format

Just as it supports multiple inputs, the output of the table also supports multiple formats. In the above example, we have used the print method to output, which is a common output method.
print

Print out the form directly through print. Forms printed this way will have borders.
Output table in HTML format

print(table.get_html_string()) can print out the table of html tags.

In the above example, using print(table.get_html_string()) will print the following result:

<table>
    <tr>
        <th>编号</th>
        <th>云编号</th>
        <th>名称</th>
        <th>IP地址</th>
    </tr>
    <tr>
        <td>1</td>
        <td>server01</td>
        <td>服务器01</td>
        <td>172.16.0.1</td>
    </tr>
    <tr>
        <td>2</td>
        <td>server02</td>
        <td>服务器02</td>
        <td>172.16.0.2</td>
    </tr>
</table>

  

6. Selective output

Prettytable After creating the table, you can still selectively output some specific rows.
Output the specified columns

print table.get_string(fields=["number", "IP address"]) can output the specified column and
output the first two lines

Through print(table.get_string(start = 0, end = 2)), the specified column can be printed out. Of course, the start and end parameters allow me to freely control the display interval. Of course, the interval contains start but not end. Are you familiar with this usage?

    According to the function of outputting specified rows and columns, we can specify both rows and columns for output, which will not be explained here.

Slice the table

From the above output interval, we make a bold assumption. Since the interval contains start and does not contain end, the rule is the same as that of slicing. We can generate a new table by slicing and then print it.

In fact it is possible.

new_table = table[0:2]
print(new_table)

 

In the above code snippet, we can print out a table with 2 lines from 0 to 1. Python's slicing function is very powerful. With slicing, we can freely input any line.
output sorting

Sometimes we need to sort the output table, use print table.get_string(sortby="number", reversesort=True) to sort the table, where reversesort specifies whether to sort in reverse order, the default is False, that is, the default positive sequence sort.

sortby specifies the sort field.
7. Table styles
Built-in styles

You can set the table style through set_style(). Prettytable has a variety of built-in styles. Personally, I think MSWORD_FRIENDLY, PLAIN_COLUMNS, and DEFAULT look relatively refreshing. Displaying the table in the terminal looks very tiring. Things look even more tired.

In addition to the three recommended styles above, there is another style that has to be said, that is RANDOM, which is a random style. Every time you print, one of the built-in styles will be randomly selected, which is more fun.

There are several built-in styles, please refer to the official website and try the output for yourself.

#!/usr/bin/python
#**coding:utf-8**
import sys
from prettytable import PrettyTable
from prettytable import MSWORD_FRIENDLY
from prettytable import PLAIN_COLUMNS
from prettytable import RANDOM
from prettytable import DEFAULT

reload(sys)
sys.setdefaultencoding('utf8')

table = PrettyTable(['编号','云编号','名称','IP地址'])
table.add_row(['1','server01','服务器01','172.16.0.1'])
table.add_row(['3','server03','服务器03','172.16.0.3'])
table.add_row(['2','server02','服务器02','172.16.0.2'])
table.add_row(['9','server09','服务器09','172.16.0.9'])
table.add_row(['4','server04','服务器04','172.16.0.4'])
table.add_row(['5','server05','服务器05','172.16.0.5'])
table.add_row(['6','server06','服务器06','172.16.0.6'])
table.add_row(['8','server08','服务器08','172.16.0.8'])
table.add_row(['7','server07','服务器07','172.16.0.7'])
table.set_style(DEFAULT)

print(table)

  

custom style

In addition to the built-in styles, PrettyTable also provides user customization, such as alignment, numeric output format, border connectors, etc.
Set the alignment

align provides a way for users to set alignment. The values ​​are l, r, and c to represent left alignment, right alignment and centering. If not set, the default is center alignment.
Control border style

In PrettyTable, the border consists of three parts, the horizontal border, the vertical border, and the border connector (the horizontal and vertical cross link symbols)

The following example:

#!/usr/bin/python
#**coding:utf-8**
import sys
from prettytable import PrettyTable

reload(sys)
sys.setdefaultencoding('utf8')

table = PrettyTable(['编号','云编号','名称','IP地址'])
table.add_row(['1','server01','服务器01','172.16.0.1'])
table.add_row(['3','server03','服务器03','172.16.0.3'])
table.add_row(['2','server02','服务器02','172.16.0.2'])
table.add_row(['9','server09','服务器09','172.16.0.9'])
table.add_row(['4','server04','服务器04','172.16.0.4'])
table.add_row(['5','server05','服务器05','172.16.0.5'])
table.add_row(['6','server06','服务器06','172.16.0.6'])
table.add_row(['8','server08','服务器08','172.16.0.8'])
table.add_row(['7','server07','服务器07','172.16.0.7'])
table.align[1] = 'l'

table.border = True
table.junction_char='$'
table.horizontal_char = '+'
table.vertical_char = '%'

print(table)
table.border`控制是否显示边框,默认是`True

table.junction_char controls the border connector

table.horizontal_char controls the horizontal border symbol

table.vertical_char controls the vertical border symbol

The above example runs as follows:

$++++++$++++++++++$++++++++++$++++++++++++$
% 编号 %  云编号  %   名称   %   IP地址   %
$++++++$++++++++++$++++++++++$++++++++++++$
%  1   % server01 % 服务器01 % 172.16.0.1 %
%  3   % server03 % 服务器03 % 172.16.0.3 %
%  2   % server02 % 服务器02 % 172.16.0.2 %
%  9   % server09 % 服务器09 % 172.16.0.9 %
%  4   % server04 % 服务器04 % 172.16.0.4 %
%  5   % server05 % 服务器05 % 172.16.0.5 %
%  6   % server06 % 服务器06 % 172.16.0.6 %
%  8   % server08 % 服务器08 % 172.16.0.8 %
%  7   % server07 % 服务器07 % 172.16.0.7 %
$++++++$++++++++++$++++++++++$++++++++++++$


 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324650165&siteId=291194637