Welcome to beautifultable’s documentation!¶
Introduction¶
This Package provides BeautifulTable class for easily printing tabular data in a visually appealing format to a terminal.
Features included but not limited to:
- Full customization of the look and feel of the table
- Build the Table as you wish, By adding rows, or by columns or even mixing both these approaches.
- Full support for colors using ANSI sequences or any library of your choice. It just works.
- Plenty of predefined styles for multiple use cases and option to create custom ones.
- Support for Unicode characters.
- Supports streaming table when data is slow to retrieve.
Contents¶
Installation¶
python3 -m pip install beautifultable
Quickstart¶
Building the Table¶
Building a table is very easy. BeautifulTable
provides two views
rows
and columns
. You can use them to modify their respective properties.
Let’s create our first table and add some rows.
>>> from beautifultable import BeautifulTable
>>> table = BeautifulTable()
>>> table.rows.append(["Jacob", 1, "boy"])
>>> table.rows.append(["Isabella", 1, "girl"])
>>> table.rows.append(["Ethan", 2, "boy"])
>>> table.rows.append(["Sophia", 2, "girl"])
>>> table.rows.append(["Michael", 3, "boy"])
>>> table.columns.header = ["name", "rank", "gender"]
>>> table.rows.header = ["S1", "S2", "S3", "S4", "S5"]
>>> print(table)
+----+----------+------+--------+
| | name | rank | gender |
+----+----------+------+--------+
| S1 | Jacob | 1 | boy |
+----+----------+------+--------+
| S2 | Isabella | 1 | girl |
+----+----------+------+--------+
| S3 | Ethan | 2 | boy |
+----+----------+------+--------+
| S4 | Sophia | 2 | girl |
+----+----------+------+--------+
| S5 | Michael | 3 | boy |
+----+----------+------+--------+
BeautifulTable initializes the shape lazily. Here when you appended the first row, the number of columns was set to 3. Further rows had to be of length 3. If you had set the columns and/or row headers beforehand as follows, the table shape would already be set to (5, 3). Hence you would just set the rows directly using their indices or keys.
>>> from beautifultable import BeautifulTable
>>> table = BeautifulTable()
>>> table.columns.header = ["name", "rank", "gender"]
>>> table.rows.header = ["S1", "S2", "S3", "S4", "S5"]
>>> table.rows[0] = ["Jacob", 1, "boy"]
>>> table.rows[1] = ["Isabella", 1, "girl"]
>>> table.rows[2] = ["Ethan", 2, "boy"]
>>> table.rows[3] = ["Sophia", 2, "girl"]
>>> table.rows[4] =["Michael", 3, "boy"]
>>> print(table)
+----+----------+------+--------+
| | name | rank | gender |
+----+----------+------+--------+
| S1 | Jacob | 1 | boy |
+----+----------+------+--------+
| S2 | Isabella | 1 | girl |
+----+----------+------+--------+
| S3 | Ethan | 2 | boy |
+----+----------+------+--------+
| S4 | Sophia | 2 | girl |
+----+----------+------+--------+
| S5 | Michael | 3 | boy |
+----+----------+------+--------+
So, We created our first table. Let’s add a new column.
>>> table.columns.append(["2010", "2012", "2008", "2010", "2011"], header="year")
>>> print(table)
+----+----------+------+--------+------+
| | name | rank | gender | year |
+----+----------+------+--------+------+
| S1 | Jacob | 1 | boy | 2010 |
+----+----------+------+--------+------+
| S2 | Isabella | 1 | girl | 2012 |
+----+----------+------+--------+------+
| S3 | Ethan | 2 | boy | 2008 |
+----+----------+------+--------+------+
| S4 | Sophia | 2 | girl | 2010 |
+----+----------+------+--------+------+
| S5 | Michael | 3 | boy | 2011 |
+----+----------+------+--------+------+
You can also build a BeautifulTable
using slicing. Slicing creates a
new table with it’s own copy of data. But it retains the properties
of the original object. You can slice both rows or columns.
>>> new_table = table.rows[:3]
>>> print(new_table)
+----+----------+------+--------+------+
| | name | rank | gender | year |
+----+----------+------+--------+------+
| S1 | Jacob | 1 | boy | 2010 |
+----+----------+------+--------+------+
| S2 | Isabella | 1 | girl | 2012 |
+----+----------+------+--------+------+
| S3 | Ethan | 2 | boy | 2008 |
+----+----------+------+--------+------+
>>> new_table = table.columns[:3]
>>> print(new_table)
+----+----------+------+--------+
| | name | rank | gender |
+----+----------+------+--------+
| S1 | Jacob | 1 | boy |
+----+----------+------+--------+
| S2 | Isabella | 1 | girl |
+----+----------+------+--------+
| S3 | Ethan | 2 | boy |
+----+----------+------+--------+
| S4 | Sophia | 2 | girl |
+----+----------+------+--------+
| S5 | Michael | 3 | boy |
+----+----------+------+--------+
As you can see how easy it is to create a Table with beautifultable. Now lets move on to see some common use cases. For details, please refer the API Documentation.
Accessing Rows¶
You can access a row using it’s index or it’s header. It returns a BTRowData object.
>>> print(list(table.rows[3]))
['Sophia', 2, 'girl', '2010']
To access a particular field of a row, you can again use the index, or the header of the required column.
>>> print(table.rows[3][2])
girl
>>> print(table.rows[3]['gender'])
girl
Accessing Columns¶
You can access a column using it’s index or it’s header. It returns a BTColumnData object.
>>> print(list(table.columns['name']))
['Jacob', 'Isabella', 'Ethan', 'Sophia', 'Michael']
To access a particular field of a column, you can again use the index, or the header of the required row.
>>> print(table.columns[2][3])
girl
>>> print(table.columns[2]['S4'])
girl
Counting Rows and Columns¶
You can get the number of columns or rows in the table by using the
len
function. You can also use the BeautifulTable.shape
attribute.
>>> print(len(table.columns))
3
>>> print(len(table.rows))
5
>>> print(table.shape)
(5,3)
Inserting Rows and Columns¶
BeautifulTable provides 2 methods, BTRowCollection.insert()
and
BTColumnCollection.insert()
for this purpose.
>>> table.rows.insert(3, ['Gary', 2, 'boy', 2009], header='S6')
>>> table.columns.insert(2, [78, 67, 82, 56, 86, 74], header='marks')
>>> print(table)
+----+----------+------+-------+--------+------+
| | name | rank | marks | gender | year |
+----+----------+------+-------+--------+------+
| S1 | Jacob | 1 | 78 | boy | 2010 |
+----+----------+------+-------+--------+------+
| S2 | Isabella | 1 | 67 | girl | 2012 |
+----+----------+------+-------+--------+------+
| S3 | Ethan | 2 | 82 | boy | 2008 |
+----+----------+------+-------+--------+------+
| S6 | Gary | 2 | 56 | boy | 2009 |
+----+----------+------+-------+--------+------+
| S4 | Sophia | 2 | 86 | girl | 2010 |
+----+----------+------+-------+--------+------+
| S5 | Michael | 3 | 74 | boy | 2011 |
+----+----------+------+-------+--------+------+
Removing Rows and Columns¶
Removing a row or column is very easy. Just delete it using del
statement.
>>> del table.rows[3]
>>> del table.columns['year']
>>> print(table)
+----+----------+------+-------+--------+
| | name | rank | marks | gender |
+----+----------+------+-------+--------+
| S1 | Jacob | 1 | 78 | boy |
+----+----------+------+-------+--------+
| S2 | Isabella | 1 | 67 | girl |
+----+----------+------+-------+--------+
| S3 | Ethan | 2 | 82 | boy |
+----+----------+------+-------+--------+
| S4 | Sophia | 2 | 86 | girl |
+----+----------+------+-------+--------+
| S5 | Michael | 3 | 74 | boy |
+----+----------+------+-------+--------+
You can also use the helper methods BTRowCollection.pop()
,
BTColumnCollection.pop()
to do the same thing. Both these
methods take the index or header of the row/column to be removed.
Therefore the following 2 snippets are equivalent.
>>> table.columns.pop('marks')
>>> table.columns.pop(2)
Updating data in the Table¶
Let’s change the name in the 4th row to 'Sophie'
.
>>> table.rows[3][0] = 'Sophie' # index of 4th row is 3
>>> print(list(table.rows[3]))
['Sophie', 2, 86, 'girl']
You could have done the same thing using the header.
>>> table.rows[3]['name'] = 'Sophie'
Or, you can also change the entire row, or even multiple rows using slicing.
>>> table.rows[3] = ['Sophie', 2, 56, 'girl']
You can also update existing columns as shown below.
>>> table.columns['marks'] = [75, 46, 89, 56, 82]
>>> print(table)
+----+----------+------+-------+--------+
| | name | rank | marks | gender |
+----+----------+------+-------+--------+
| S1 | Jacob | 1 | 75 | boy |
+----+----------+------+-------+--------+
| S2 | Isabella | 1 | 46 | girl |
+----+----------+------+-------+--------+
| S3 | Ethan | 2 | 89 | boy |
+----+----------+------+-------+--------+
| S4 | Sophie | 2 | 56 | girl |
+----+----------+------+-------+--------+
| S5 | Michael | 3 | 82 | boy |
+----+----------+------+-------+--------+
The methods BTRowCollection.update()
and BTColumnCollection.update()
can be used to perform the operations discussed in this section.
Note that you can only update existing columns but can’t create
a new column using this method. For that you need to use the
methods BTRowCollection.append()
, BTRowCollection.insert()
,
BTColumnCollection.append()
or BTColumnCollection.insert()
.
Searching for rows or columns headers¶
Cheking if a column header is in the table.
>>> 'rank' in table.columns.header
True
Cheking if a row header is in the table.
>>> 'S2' in table.rows.header
True
Cheking if a row is in table
>>> ["Ethan", 2, 89, "boy"] in table.rows
True
Cheking if a column is in table
>>> ["Jacob", "Isabella", "Ethan", "Sophie", "Michael"] in table.columns
True
Sorting based on a Column¶
You can also BTRowCollection.sort()
the table based on a column
by specifying it’s index or it’s header.
>>> table.rows.sort('marks')
>>> print(table)
+----+----------+------+-------+--------+
| | name | rank | marks | gender |
+----+----------+------+-------+--------+
| S2 | Isabella | 1 | 46 | girl |
+----+----------+------+-------+--------+
| S4 | Sophia | 2 | 56 | girl |
+----+----------+------+-------+--------+
| S1 | Jacob | 1 | 75 | boy |
+----+----------+------+-------+--------+
| S5 | Michael | 3 | 82 | boy |
+----+----------+------+-------+--------+
| S3 | Ethan | 2 | 89 | boy |
+----+----------+------+-------+--------+
Customizing the look of the Table¶
Alignment¶
Let’s change the way some columns are aligned in our table.
>>> table.columns.alignment['name'] = BeautifulTable.ALIGN_LEFT
>>> table.columns.alignment['gender'] = BeautifulTable.ALIGN_RIGHT
>>> print(table)
+----+----------+------+-------+--------+
| | name | rank | marks | gender |
+----+----------+------+-------+--------+
| S2 | Isabella | 1 | 46 | girl |
+----+----------+------+-------+--------+
| S4 | Sophia | 2 | 56 | girl |
+----+----------+------+-------+--------+
| S1 | Jacob | 1 | 75 | boy |
+----+----------+------+-------+--------+
| S5 | Michael | 3 | 82 | boy |
+----+----------+------+-------+--------+
| S3 | Ethan | 2 | 89 | boy |
+----+----------+------+-------+--------+
You can also set all columns to a specific alignment
>>> table.columns.alignment = BeautifulTable.ALIGN_RIGHT
>>> print(table)
+----+----------+------+-------+--------+
| | name | rank | marks | gender |
+----+----------+------+-------+--------+
| S2 | Isabella | 1 | 46 | girl |
+----+----------+------+-------+--------+
| S4 | Sophia | 2 | 56 | girl |
+----+----------+------+-------+--------+
| S1 | Jacob | 1 | 75 | boy |
+----+----------+------+-------+--------+
| S5 | Michael | 3 | 82 | boy |
+----+----------+------+-------+--------+
| S3 | Ethan | 2 | 89 | boy |
+----+----------+------+-------+--------+
Headers can have a different alignment that the column.
>>> table.columns.header.alignment= BeautifulTable.ALIGN_RIGHT
>>> table.columns.alignment = BeautifulTable.ALIGN_LEFT
>>> print(table)
+----+----------+------+-------+--------+
| | name | rank | marks | gender |
+----+----------+------+-------+--------+
| S2 | Isabella | 1 | 46 | girl |
+----+----------+------+-------+--------+
| S4 | Sophia | 2 | 56 | girl |
+----+----------+------+-------+--------+
| S1 | Jacob | 1 | 75 | boy |
+----+----------+------+-------+--------+
| S5 | Michael | 3 | 82 | boy |
+----+----------+------+-------+--------+
| S3 | Ethan | 2 | 89 | boy |
+----+----------+------+-------+--------+
Padding¶
You can change the padding for individual column similar to the alignment.
>>> table.columns.padding_left['rank'] = 5
>>> table.columns.padding_right['rank'] = 3
>>> print(table)
+----+----------+------------+--------+
| | name | rank | gender |
+----+----------+------------+--------+
| S1 | Jacob | 1 | boy |
+----+----------+------------+--------+
| S2 | Isabella | 1 | girl |
+----+----------+------------+--------+
| S3 | Ethan | 2 | boy |
+----+----------+------------+--------+
| S4 | Sophia | 2 | girl |
+----+----------+------------+--------+
| S5 | Michael | 3 | boy |
+----+----------+------------+--------+
You can use a helper attribute BTColumnCollection.padding
to
set the left and right padding to a common value.
Styling¶
beautifultable comes with several predefined styles for various use cases.
You can use the BeautifulTable.set_style()
method to set the style
of the table. The following styles are available:
STYLE_DEFAULT
>>> table.set_style(BeautifulTable.STYLE_DEFAULT) >>> print(table) +----+----------+------+--------+ | | name | rank | gender | +----+----------+------+--------+ | S1 | Jacob | 1 | boy | +----+----------+------+--------+ | S2 | Isabella | 1 | girl | +----+----------+------+--------+ | S3 | Ethan | 2 | boy | +----+----------+------+--------+ | S4 | Sophia | 2 | girl | +----+----------+------+--------+ | S5 | Michael | 3 | boy | +----+----------+------+--------+
STYLE_NONE
>>> table.set_style(BeautifulTable.STYLE_NONE) >>> print(table) name rank gender S1 Jacob 1 boy S2 Isabella 1 girl S3 Ethan 2 boy S4 Sophia 2 girl S5 Michael 3 boy
STYLE_DOTTED
>>> table.set_style(BeautifulTable.STYLE_DOTTED) >>> print(table) ................................. : : name : rank : gender : ................................. : S1 : Jacob : 1 : boy : : S2 : Isabella : 1 : girl : : S3 : Ethan : 2 : boy : : S4 : Sophia : 2 : girl : : S5 : Michael : 3 : boy : .................................
STYLE_SEPARATED
>>> table.set_style(BeautifulTable.STYLE_SEPARATED) >>> print(table) +====+==========+======+========+ | | name | rank | gender | +====+==========+======+========+ | S1 | Jacob | 1 | boy | +----+----------+------+--------+ | S2 | Isabella | 1 | girl | +----+----------+------+--------+ | S3 | Ethan | 2 | boy | +----+----------+------+--------+ | S4 | Sophia | 2 | girl | +----+----------+------+--------+ | S5 | Michael | 3 | boy | +----+----------+------+--------+
STYLE_COMPACT
>>> table.set_style(BeautifulTable.STYLE_COMPACT) >>> print(table) name rank gender ---- ---------- ------ -------- S1 Jacob 1 boy S2 Isabella 1 girl S3 Ethan 2 boy S4 Sophia 2 girl S5 Michael 3 boy
STYLE_MYSQL
>>> table.set_style(BeautifulTable.STYLE_MYSQL) >>> print(table) # Yes, the default style is same as this style +----+----------+------+--------+ | | name | rank | gender | +----+----------+------+--------+ | S1 | Jacob | 1 | boy | +----+----------+------+--------+ | S2 | Isabella | 1 | girl | +----+----------+------+--------+ | S3 | Ethan | 2 | boy | +----+----------+------+--------+ | S4 | Sophia | 2 | girl | +----+----------+------+--------+ | S5 | Michael | 3 | boy | +----+----------+------+--------+
STYLE_MARKDOWN
>>> table.set_style(BeautifulTable.STYLE_MARKDOWN) >>> print(table) # Markdown alignment not supported currently | | name | rank | gender | |----|----------|------|--------| | S1 | Jacob | 1 | boy | | S2 | Isabella | 1 | girl | | S3 | Ethan | 2 | boy | | S4 | Sophia | 2 | girl | | S5 | Michael | 3 | boy |
STYLE_RST
>>> table.set_style(BeautifulTable.STYLE_RST) >>> print(table) ==== ========== ====== ======== name rank gender ==== ========== ====== ======== S1 Jacob 1 boy S2 Isabella 1 girl S3 Ethan 2 boy S4 Sophia 2 girl S5 Michael 3 boy ==== ========== ====== ========
STYLE_BOX
>>> table.set_style(BeautifulTable.STYLE_BOX) >>> print(table) ┌────┬──────────┬──────┬────────┐ │ │ name │ rank │ gender │ ├────┼──────────┼──────┼────────┤ │ S1 │ Jacob │ 1 │ boy │ ├────┼──────────┼──────┼────────┤ │ S2 │ Isabella │ 1 │ girl │ ├────┼──────────┼──────┼────────┤ │ S3 │ Ethan │ 2 │ boy │ ├────┼──────────┼──────┼────────┤ │ S4 │ Sophia │ 2 │ girl │ ├────┼──────────┼──────┼────────┤ │ S5 │ Michael │ 3 │ boy │ └────┴──────────┴──────┴────────┘
STYLE_BOX_DOUBLED
>>> table.set_style(BeautifulTable.STYLE_BOX_DOUBLED) >>> print(table) ╔════╦══════════╦══════╦════════╗ ║ ║ name ║ rank ║ gender ║ ╠════╬══════════╬══════╬════════╣ ║ S1 ║ Jacob ║ 1 ║ boy ║ ╠════╬══════════╬══════╬════════╣ ║ S2 ║ Isabella ║ 1 ║ girl ║ ╠════╬══════════╬══════╬════════╣ ║ S3 ║ Ethan ║ 2 ║ boy ║ ╠════╬══════════╬══════╬════════╣ ║ S4 ║ Sophia ║ 2 ║ girl ║ ╠════╬══════════╬══════╬════════╣ ║ S5 ║ Michael ║ 3 ║ boy ║ ╚════╩══════════╩══════╩════════╝
STYLE_BOX_ROUNDED
>>> table.set_style(BeautifulTable.STYLE_BOX_ROUNDED) >>> print(table) ╭────┬──────────┬──────┬────────╮ │ │ name │ rank │ gender │ ├────┼──────────┼──────┼────────┤ │ S1 │ Jacob │ 1 │ boy │ ├────┼──────────┼──────┼────────┤ │ S2 │ Isabella │ 1 │ girl │ ├────┼──────────┼──────┼────────┤ │ S3 │ Ethan │ 2 │ boy │ ├────┼──────────┼──────┼────────┤ │ S4 │ Sophia │ 2 │ girl │ ├────┼──────────┼──────┼────────┤ │ S5 │ Michael │ 3 │ boy │ ╰────┴──────────┴──────┴────────╯
STYLE_GRID
>>> table.set_style(BeautifulTable.STYLE_GRID) >>> print(table) ╔════╤══════════╤══════╤════════╗ ║ │ name │ rank │ gender ║ ╟────┼──────────┼──────┼────────╢ ║ S1 │ Jacob │ 1 │ boy ║ ╟────┼──────────┼──────┼────────╢ ║ S2 │ Isabella │ 1 │ girl ║ ╟────┼──────────┼──────┼────────╢ ║ S3 │ Ethan │ 2 │ boy ║ ╟────┼──────────┼──────┼────────╢ ║ S4 │ Sophia │ 2 │ girl ║ ╟────┼──────────┼──────┼────────╢ ║ S5 │ Michael │ 3 │ boy ║ ╚════╧══════════╧══════╧════════╝
For more finer customization, you can change what characters are used to draw various parts of the table. Here we show you an example of how you can use this feature. You can read the API Reference for more details.
>>> table.set_style(BeautifulTable.STYLE_NONE) # clear all formatting
>>> table.border.left = 'o'
>>> table.border.right = 'o'
>>> table.border.top = '<~>'
>>> table.border.bottom = '='
>>> table.columns.header.separator = '^'
>>> table.columns.separator = ':'
>>> table.rows.separator = '~'
>>> print(table)
<~><~><~><~><~><~><~><~><~><~><~>
o : name : rank : gender o
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
o S1 : Jacob : 1 : boy o
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
o S2 : Isabella : 1 : girl o
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
o S3 : Ethan : 2 : boy o
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
o S4 : Sophia : 2 : girl o
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
o S5 : Michael : 3 : boy o
=================================
As you can see, you can change quite a lot about your BeautifulTable instance. For further sections, We switch the look of the table to default again.
Colored Tables¶
beautifultable comes with out of the box support for colored tables using ansi escape sequences. You can also use any library which makes use of these sequences to produce colored text output.
python3 -m pip install termcolor
>>> from termcolor import colored
>>> table.rows.append([colored("John", 'red'), 4, colored("boy", 'blue')])
>>> print(table)
+----+----------+------+--------+
| | name | rank | gender |
+----+----------+------+--------+
| S1 | Jacob | 1 | boy |
+----+----------+------+--------+
| S2 | Isabella | 1 | girl |
+----+----------+------+--------+
| S3 | Ethan | 2 | boy |
+----+----------+------+--------+
| S4 | Sophia | 2 | girl |
+----+----------+------+--------+
| S5 | Michael | 3 | boy |
+----+----------+------+--------+
| S6 | John | 4 | boy |
+----+----------+------+--------+
You can also use these sequences for making texts bold, italics, etc.
Paragraphs¶
A cell can contain multiple paragraphs such that each one start from
a new line. beautifultable parses \n
as a paragraph change.
>>> new_table = BeautifulTable(max_width=40)
>>> new_table.columns.header = ["Heading 1", "Heading 2"]
>>> new_table.rows.append(["first Line\nsecond Line", "single line"])
>>> new_table.rows.append(["first Line\nsecond Line\nthird Line", "first Line\nsecond Line"])
>>> new_table.rows.append(["single line", "this is a very long first line\nThis is a very long second line"])
>>> print(new_table)
+-------------+------------------------+
| Heading 1 | Heading 2 |
+-------------+------------------------+
| first Line | single line |
| second Line | |
+-------------+------------------------+
| first Line | first Line |
| second Line | second Line |
| third Line | |
+-------------+------------------------+
| single line | this is a very long fi |
| | rst line |
| | This is a very long se |
| | cond line |
+-------------+------------------------+
Subtables¶
You can even render a BeautifulTable
instance inside another
table. To do that, just pass the table as any regular text and it just
works.
>>> # Setting up the inner table
>>> subtable = BeautifulTable()
>>> subtable.rows.append(["Jacob", 1, "boy"])
>>> subtable.rows.append(["Isabella", 1, "girl"])
>>> subtable.border.left = ''
>>> subtable.border.right = ''
>>> subtable.border.top = ''
>>> subtable.border.right = ''
>>>
>>> # Setting up the outer table
>>> table = BeautifulTable()
>>> table.columns.header = ["Heading 1", "Heading 2"]
>>> table.rows.append(["Sample text", "Another sample text"])
>>> table.rows.append([subtable, "More sample text"])
>>> table.columns.padding_left[0] = 0
>>> table.columns.padding_right[0] = 0
>>> print(table)
+---------------------+---------------------+
| Heading 1 | Heading 2 |
+---------------------+---------------------+
| Sample text | Another sample text |
+---------------------+---------------------+
| Jacob | 1 | boy | More sample text |
|----------+---+------| |
| Isabella | 1 | girl | |
+---------------------+---------------------+
Streaming Tables¶
There are situations where data retrieval is slow such as when data is recieved over a network and you want to display the data as soon as possible. In these cases, you can use streaming tables to render the table with the help of a generator.
Streaming table do have their limitation. The width calculation routine requires you to either set it manually or specify the column header or add atleast 1 row. You also cannot have row headers for streaming tables.
>>> import time
>>> def time_taking_process():
... for i in range(5):
... time.sleep(1)
... yield [i, i**2]
...
...
>>> table = BeautifulTable()
>>> table.columns.header = ["Number", "It's Square"]
>>> for line in table.stream(time_taking_process()):
... print(line)
...
+--------+-------------+
| Number | It's Square |
+--------+-------------+
| 0 | 0 |
+--------+-------------+
| 1 | 1 |
+--------+-------------+
| 2 | 4 |
+--------+-------------+
| 3 | 9 |
+--------+-------------+
| 4 | 16 |
+--------+-------------+
Support for Multibyte Unicode characters¶
beautifultable comes with built-in support for multibyte unicode such as east-asian characters.
You can do much more with BeautifulTable but this much should give you a good start. Those of you who are interested to have more control can read the API Documentation.
Changelog¶
Development¶
v1.1.0¶
- Drop support for Python 3.4, 3.5 and 3.6
- Add official support for python 3.9 and 3.10
- Added asdict and aslist method on the row object. (Thanks to @Agent-Hellboy)
- Added from_csv and to_csv methods to export/import a csv file. (Thanks to @Agent-Hellboy)
- Added from_df and to_df methods to export/import a dataframe. (Thanks to @Agent-Hellboy)
v1.0.1¶
- Fixed an issue where appending a column with a header to an empty table left the table instance in an inconsistent state.
v1.0.0¶
- Added two new views
rows
andcolumns
to theBeautifulTable
class. Most of the existing methods have been deprecated. Methods of the form{}_row
and{}_column
have been moved to viewsrows.{}
andcolumns.{}``(ex. ``append_row
is nowrows.append
). Calling older deprecated methods will now raise aFutureWarning
. Special methods such as__len__
,__iter__
, etc. have also been moved to the respective views. For details, refer the API documentation and the Updated Tutorial - The existing styling attributes have also been deprecated. A new
border
property can be accessed to control all styling attributes affecting the border. Rest of the attributes can be accessed from it’s respective view. - Added support for row headers. As a result rows can now be accessed by their keys similar to columns
- Added two new methods
to_csv
andfrom_csv
to directly export/import to a csv file. (Thanks to @dinko-pehar) - Added
BeautifulTable.rows.filter
method to generate a new table with only certain rows - Added a new
shape
attribute to theBeautifulTable
class which returns a tuple of form (nrow, ncol) - Added new attribute
BeautifulTable.columns.header.alignment
which can be used to have a seperate header alignment. The default behaviour is to inheritBeautifulTable.columns.alignment
- Updated
BeautifulTable.rows.sort
(earlierBeautifulTable.sort
) method to now also accept any callables as a key. - Updated behaviour of
BeautifulTable.columns.width
(earlierBeautifulTable.column_widths
). It no longer overrides user specified widths by default. You can reset it to default by setting it to “auto” - Deprecated attribute
serialno
andserialno_header
. User can now easily implement this functionality by using row headers if required - Deprecated methods
get_table_width()
,copy()
andget_string()
. - Deprecated constructor arguments and class attributes named
sign_mode
,numeric_precision
,max_width
and renamed tosign
,precision
andmaxwidth
respectively - Fixed an issue where table was malformed if
blessings
module was used to generate colored strings. - Fixed issues with the existing implementation of
__iter__
,__copy__
and__deepcopy__
which should now work more reliably. - Fixed an issue where default padding could not be set to 0. (Thanks to @furlongm)
- Fixed several memory leak issues by ensuring that all internal objects hold only a weak reference to the table instance.
- Dropped support for Python 2
v0.8.0¶
- Dropped support for Python 3.3
- Added support for streaming tables using a generator for cases where data retrieval is slow
- Alignment, padding, width can now be set for all columns using a simplified syntax like
table.column_alignments = beautifultable.ALIGN_LEFT
v0.7.0¶
- Added 4 new styles, STYLE_BOX, STYLE_BOX_DOUBLED, STYLE_BOX_ROUNDED, STYLE_GRID.
- Renamed STYLE_RESTRUCTURED_TEXT to STYLE_RST
- wcwidth is now an optional dependency
- Updated the algorithm for calculating width of columns(better division of space among columns)
- Added support for Paragraphs(using
\n
character) - Added finer control for intersection characters using 12 new
attributes
intersect_{top|header|row|bottom}_{left|mid|right}
- Added the ability to also accept bytestrings instead of unicode
- Deprecated attribute
intersection_char
- Deprecated methods
get_top_border()
,get_bottom_border()
,get_header_separator()
,get_row_separator()
,auto_calculate_width()
- Fixed an issue with WEP_ELLIPSIS and WEP_STRIP when using multibyte characters
- Fixed an issue where table would not be in proper form if
column_width
is too low
v0.6.0¶
- Added support for handling Multi byte strings
- Added support for colored strings using ANSI escape sequences
- Added constraint where all strings must be unicode
- Fixed an issue where sometimes width was calculated as higher than intended
v0.5.3¶
- Added support for handing color codes using ANSI escape sequences(experimental)
- Fixed collections ABCs deprecation warning
v0.5.2¶
- Added new style STYLE_NONE
- Fixed issue regarding improper conversion of non-string floats
v0.5.1¶
- Added
detect_numerics
boolean for toggling automatic numeric conversion
v0.5.0¶
- Added new property
serialno_header
- Deprecated methods with misspelled “seperator” in their name.
- Fixed an issue where table was corrupted when
column_count
was too high
v0.4.0¶
- Added predefined styles for easier customization
- Added reverse argument to
sort()
method - Fixed enum34 dependency for python versions prior to 3.4
v0.3.0¶
- Added property
serialno
for auto printing serial number - Fixed an issue with
sign_mode
related to str conversion - Fixed bugs related to python version prior to 3.3
- Fixed exception on WEP_ELLIPSIS and token length less than 3
- Fixed printing issues with empty table
v0.2.0¶
- Added python 2 support
v0.1.3¶
- Fixed minor issues
v0.1.2¶
- Added new property
default_padding
- Added new method
update_row
- Fixed an issue in
auto_calculate_width()
v0.1.1¶
- Initial release on PyPI