It's so beautiful. Output nice tables. Use this Python library

Posted by Hagaroo on Fri, 28 Jan 2022 07:35:02 +0100

  1. preface

Recently, I was writing a small tool in Python, which is mainly used to manage the information of various resources, such as Alibaba cloud ECS. Because the computer I work on uses LINUX, I wanted to write a command-line management tool in Python. The basic function is to synchronize the information of Alibaba cloud resources to the database, and then use the command-line query.

Because the information is displayed on the command line, it is well known that the complex text displayed on the command line looks really tiring, so I want to display it like a table, which looks much more comfortable.

prettytable library is such a tool. prettytable can print beautiful forms and supports Chinese very well (if you try to print forms yourself, you should know how troublesome it is to deal with Chinese)

  1. install

Prettytable is not a built-in Library of python. You can install prettytable through PIP install.

  1. Examples

    Let's take a look at an example:
    
    #!/usr/bin/python
    #**coding:utf-8**
    import sys
    from prettytable import PrettyTable
    reload(sys)
    sys.setdefaultencoding('utf8')
     
    table = PrettyTable(['number','Cloud number','name','IP address'])
    table.add_row(['1','server01','Server 01','172.16.0.1'])
    table.add_row(['2','server02','Server 02','172.16.0.2'])
    table.add_row(['3','server03','Server 03','172.16.0.3'])
    table.add_row(['4','server04','Server 04','172.16.0.4'])
    table.add_row(['5','server05','Server 05','172.16.0.5'])
    table.add_row(['6','server06','Server 06','172.16.0.6'])
    table.add_row(['7','server07','Server 07','172.16.0.7'])
    table.add_row(['8','server08','Server 08','172.16.0.8'])
    table.add_row(['9','server09','Server 09','172.16.0.9'])
    print(table)

The operation results of the above example are as follows:

linuxops@deepin:~$ python p.py
+------+----------+----------+------------+
| number |  Cloud number  |   name   |   IP address   |
+------+----------+----------+------------+
|  1   | server01 | Server 01 | 172.16.0.1 |
|  2   | server02 | Server 02 | 172.16.0.2 |
|  3   | server03 | Server 03 | 172.16.0.3 |
|  4   | server04 | Server 04 | 172.16.0.4 |
|  5   | server05 | Server 05 | 172.16.0.5 |
|  6   | server06 | Server 06 | 172.16.0.6 |
|  7   | server07 | Server 07 | 172.16.0.7 |
|  8   | server08 | Server 08 | 172.16.0.8 |
|  9   | server09 | Server 09 | 172.16.0.9 |
+------+----------+----------+------------+

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

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

Therefore, in order to more intuitively see the meaning of each column, you still need to add a header.

  1. Add data

prettytable provides a variety of ways to add data. The most common way is to add data by row and column.
Add data table by row add_ row

In the simple example above, we add data by row.

The added data must be in the form of a list, and the list length of the data must be the same as that 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 table by column add_ column()

Look at the following example:

#!/usr/bin/python
#**coding:utf-8**
import sys
from prettytable import PrettyTable
reload(sys)
sys.setdefaultencoding('utf8')
 
table = PrettyTable()
table.add_column('project', ['number','Cloud number','name','IP address'])
table.add_column('value', ['1','server01','Server 01','172.16.0.1'])
print(table)

The operation results are as follows:

+-------+--------+------------+
| index | project |    value     |
+-------+--------+------------+
|   1   |  number  |     1      |
|   2   | Cloud number |  server01  |
|   3   |  name  |  Server 01   |
|   4   | IP address | 172.16.0.1 |
+-------+--------+------------+

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

table.add_column('item', 'number', 'cloud number', 'name', 'IP address']) as an example, the item specifies that the header name of this column is "item", [' number ',' cloud number ',' name ',' IP address'] is the value of the column, which is also a list.
Add data from csv file

PrettyTable not only provides manual adding 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 the cvs file data, you must first import from_csv, otherwise it cannot run. The running results of the above example are as follows:

PS: csv files cannot be directly renamed by xls, and an error will be reported. If it is an xls file, use save as csv to get the 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. If mysql is used, it is the same. 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 operation results are as follows:

+------+----------+----------+------------+
| number |  Cloud number  |   name   |   IP address   |
+------+----------+----------+------------+
|  1   | server01 | Server 01 | 172.16.0.1 |
|  2   | server02 | Server 02 | 172.16.0.2 |
|  3   | server03 | Server 03 | 172.16.0.3 |
|  4   | server04 | Server 04 | 172.16.0.4 |
|  5   | server05 | Server 05 | 172.16.0.5 |
|  6   | server06 | Server 06 | 172.16.0.6 |
|  7   | server07 | Server 07 | 172.16.0.7 |
|  8   | server08 | Server 08 | 172.16.0.8 |
|  9   | server09 | Server 09 | 172.16.0.9 |
+------+----------+----------+------------+

Import data from HTML

Import from html tables is supported. Please 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>number</th>
<th>Cloud number</th>
<th>name</th>
<th>IP address</th>
</tr>
<tr>
<td>1</td>
<td>server01</td>
<td>Server 01</td>
<td>172.16.0.1</td>
</tr>
<tr>
<td>2</td>
<td>server02</td>
<td>Server 02</td>
<td>172.16.0.2</td>
</tr>
</table>'''
 
table = from_html(html_string)
 
print(table[0])

The operation results are as follows:

+------+----------+----------+------------+
| number |  Cloud number  |   name   |   IP address   |
+------+----------+----------+------------+
|  1   | server01 | Server 01 | 172.16.0.1 |
|  2   | server02 | Server 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 an error like [< prettytable. Prettytable object at 0x7fa87feba590 >] may be reported.

This is because table is not a PrettyTable object, but a list containing a single PrettyTable object. It comes from parsing html, so it cannot print table directly, but needs to print table[0]

  1. Table output format

Just like supporting multiple inputs, table output also supports multiple formats. In the above example, we have used print output, which is a common output method.
print

Print the form directly through print. The form printed in this way will have a border.
Output tables in HTML format

print(table.get_html_string()) can print the table with HTML tag.

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

<table>
    <tr>
        <th>number</th>
        <th>Cloud number</th>
        <th>name</th>
        <th>IP address</th>
    </tr>
    <tr>
        <td>1</td>
        <td>server01</td>
        <td>Server 01</td>
        <td>172.16.0.1</td>
    </tr>
    <tr>
        <td>2</td>
        <td>server02</td>
        <td>Server 02</td>
        <td>172.16.0.2</td>
    </tr>
</table>
  1. Selective output

prettytable after creating a table, you can still selectively output certain rows
Outputs the specified column

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

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

According to the function of specifying rows and columns for output, we can specify rows and columns for output at the same time, which will not be explained here.

Slice 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. Can we generate a new table through slicing and then print it.

In fact, it can.

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

In the above code segment, we can print out a table with 2 lines in total 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 tables and use print table get_ String (sortby = "number", reveresort = true) can sort the table. Reveresort specifies whether to sort in reverse order. The default is False, that is, the default is positive sequence sorting.

sortby specifies the fields to sort.

  1. Table style
    Built in style

By set_style() can set table styles. prettytable has built-in multiple styles. Personally, I think MSWORD_FRIENDLY,PLAIN_ The three styles of columns and DEFAULT look refreshing. Displaying tables under the terminal looks very tired, and it looks even more tired with fancy things.

In addition to the three styles recommended above, there is another style, RANDOM, which is a RANDOM style. Each printing will randomly select one of the built-in styles, which is more fun.

There are several built-in styles. Please refer to the official website and try to output it 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(['number','Cloud number','name','IP address'])
table.add_row(['1','server01','Server 01','172.16.0.1'])
table.add_row(['3','server03','Server 03','172.16.0.3'])
table.add_row(['2','server02','Server 02','172.16.0.2'])
table.add_row(['9','server09','Server 09','172.16.0.9'])
table.add_row(['4','server04','Server 04','172.16.0.4'])
table.add_row(['5','server05','Server 05','172.16.0.5'])
table.add_row(['6','server06','Server 06','172.16.0.6'])
table.add_row(['8','server08','Server 08','172.16.0.8'])
table.add_row(['7','server07','Server 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, digital output format, border connector, and so on
Set alignment

align provides the user to set the alignment method. The values are l, r and c, which conveniently represent left alignment, right alignment and center. If it is not set, the center alignment is the default.
Control border style

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

Examples are as follows:

#!/usr/bin/python
#**coding:utf-8**
import sys
from prettytable import PrettyTable
 
reload(sys)
sys.setdefaultencoding('utf8')
 
table = PrettyTable(['number','Cloud number','name','IP address'])
table.add_row(['1','server01','Server 01','172.16.0.1'])
table.add_row(['3','server03','Server 03','172.16.0.3'])
table.add_row(['2','server02','Server 02','172.16.0.2'])
table.add_row(['9','server09','Server 09','172.16.0.9'])
table.add_row(['4','server04','Server 04','172.16.0.4'])
table.add_row(['5','server05','Server 05','172.16.0.5'])
table.add_row(['6','server06','Server 06','172.16.0.6'])
table.add_row(['8','server08','Server 08','172.16.0.8'])
table.add_row(['7','server07','Server 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 controls whether the border is displayed. The default is True
table.junction_char control border connector

table.horizontal_char control border symbol

table.vertical_char controls the vertical border symbol

The above example runs as follows:

$++++++$++++++++++$++++++++++$++++++++++++$
% number %  Cloud number  %   name   %   IP address   %
$++++++$++++++++++$++++++++++$++++++++++++$
%  1   % server01 % Server 01 % 172.16.0.1 %
%  3   % server03 % Server 03 % 172.16.0.3 %
%  2   % server02 % Server 02 % 172.16.0.2 %
%  9   % server09 % Server 09 % 172.16.0.9 %
%  4   % server04 % Server 04 % 172.16.0.4 %
%  5   % server05 % Server 05 % 172.16.0.5 %
%  6   % server06 % Server 06 % 172.16.0.6 %
%  8   % server08 % Server 08 % 172.16.0.8 %
%  7   % server07 % Server 07 % 172.16.0.7 %
$++++++$++++++++++$++++++++++$++++++++++++$

Topics: Python