Skip to content

How to Generate ASCII Tables Using PrettyTable in Python

Learn how to create clean, formatted ASCII tables in Python using PrettyTable, including data insertion, sorting, styling, and HTML export for CLI tools and reports.

When building CLI tools, debugging scripts, or displaying structured data in the terminal, a well-formatted table is far easier to read than raw print statements. PrettyTable is a lightweight Python library that generates clean, formatted ASCII tables with minimal effort. It supports sorting, filtering, alignment control, and can even output tables as HTML.

This guide covers installation, data insertion, formatting, and advanced features to help you create professional-looking tables in your Python applications.

Installation

PrettyTable is available via pip:

pip install prettytable

Then import it in your script:

from prettytable import PrettyTable

Creating a Table and Inserting Data

PrettyTable supports two primary ways to add data: row by row or column by column.

Adding Data Row by Row

Set the column headers using field_names, then add each row with add_row():

from prettytable import PrettyTable

table = PrettyTable()

table.field_names = ["Name", "Role", "Salary", "City"]
table.add_row(["Alice", "Engineer", 95000, "New York"])
table.add_row(["Bob", "Designer", 82000, "San Francisco"])
table.add_row(["Charlie", "Manager", 105000, "Chicago"])
table.add_row(["Diana", "Analyst", 78000, "Boston"])
table.add_row(["Eve", "Developer", 91000, "Seattle"])

print(table)

Output:

+---------+-----------+--------+---------------+
|   Name  |    Role   | Salary |      City     |
+---------+-----------+--------+---------------+
|  Alice  |  Engineer | 95000  |    New York   |
|   Bob   |  Designer | 82000  | San Francisco |
| Charlie |  Manager  | 105000 |    Chicago    |
|  Diana  |  Analyst  | 78000  |     Boston    |
|   Eve   | Developer | 91000  |    Seattle    |
+---------+-----------+--------+---------------+

Adding Data Column by Column

Use add_column() to add data one column at a time. The first argument is the column name, and the second is a list of values:

from prettytable import PrettyTable

table = PrettyTable()

table.add_column("Name", ["Alice", "Bob", "Charlie", "Diana", "Eve"])
table.add_column("Role", ["Engineer", "Designer", "Manager", "Analyst", "Developer"])
table.add_column("Salary", [95000, 82000, 105000, 78000, 91000])
table.add_column("City", ["New York", "San Francisco", "Chicago", "Boston", "Seattle"])

print(table)

Output:

+---------+-----------+--------+---------------+
|   Name  |    Role   | Salary |      City     |
+---------+-----------+--------+---------------+
|  Alice  |  Engineer | 95000  |    New York   |
|   Bob   |  Designer | 82000  | San Francisco |
| Charlie |  Manager  | 105000 |    Chicago    |
|  Diana  |  Analyst  | 78000  |     Boston    |
|   Eve   | Developer | 91000  |    Seattle    |
+---------+-----------+--------+---------------+

This produces the same output as the row-by-row approach.

Deleting Data

Deleting Specific Rows

Use del_row(index) to remove a row by its zero-based index:

from prettytable import PrettyTable

table = PrettyTable()
table.field_names = ["Name", "Score"]
table.add_row(["Alice", 95])
table.add_row(["Bob", 82])
table.add_row(["Charlie", 78])
table.add_row(["Diana", 91])

table.del_row(1)

print(table)

Output:

+---------+-------+
|   Name  | Score |
+---------+-------+
|  Alice  |   95  |
| Charlie |   78  |
|  Diana  |   91  |
+---------+-------+

Clearing All Data

from prettytable import PrettyTable

table = PrettyTable()
table.field_names = ["Name", "Score"]
table.add_row(["Alice", 95])
table.add_row(["Bob", 82])
table.add_row(["Charlie", 78])
table.add_row(["Diana", 91])

table.clear_rows()
print(table)

print()

table.clear()
print(table)

Output:

+------+-------+
| Name | Score |
+------+-------+
+------+-------+

++
||
++
++

Controlling What Gets Displayed

PrettyTable lets you selectively display specific rows or specific columns without modifying the underlying data.

Selecting Rows

Use the start and end parameters in get_string():

from prettytable import PrettyTable

table = PrettyTable()
table.field_names = ["Name", "Role", "Salary"]
table.add_row(["Alice", "Engineer", 95000])
table.add_row(["Bob", "Designer", 82000])
table.add_row(["Charlie", "Manager", 105000])
table.add_row(["Diana", "Analyst", 78000])
table.add_row(["Eve", "Developer", 91000])

print(table.get_string(start=1, end=3))

Output:

+---------+----------+--------+
|   Name  |   Role   | Salary |
+---------+----------+--------+
|   Bob   | Designer | 82000  |
| Charlie | Manager  | 105000 |
+---------+----------+--------+

Selecting Columns

Use the fields parameter to choose which columns to display:

print(table.get_string(fields=["Name", "Salary"]))

Output:

+---------+--------+
|   Name  | Salary |
+---------+--------+
|  Alice  | 95000  |
|   Bob   | 82000  |
| Charlie | 105000 |
|  Diana  | 78000  |
|   Eve   | 91000  |
+---------+--------+

Sorting Tables

Sort by any column using the sortby property. Use reversesort for descending order:

from prettytable import PrettyTable

table = PrettyTable()
table.field_names = ["Name", "Role", "Salary"]
table.add_row(["Alice", "Engineer", 95000])
table.add_row(["Bob", "Designer", 82000])
table.add_row(["Charlie", "Manager", 105000])
table.add_row(["Diana", "Analyst", 78000])
table.add_row(["Eve", "Developer", 91000])

table.sortby = "Salary"
print("Sorted by Salary (ascending):")
print(table)

table.reversesort = True
print("\nSorted by Salary (descending):")
print(table)

Output:

Sorted by Salary (ascending):
+---------+-----------+--------+
|   Name  |    Role   | Salary |
+---------+-----------+--------+
|  Diana  |  Analyst  | 78000  |
|   Bob   |  Designer | 82000  |
|   Eve   | Developer | 91000  |
|  Alice  |  Engineer | 95000  |
| Charlie |  Manager  | 105000 |
+---------+-----------+--------+

Sorted by Salary (descending):
+---------+-----------+--------+
|   Name  |    Role   | Salary |
+---------+-----------+--------+
| Charlie |  Manager  | 105000 |
|  Alice  |  Engineer | 95000  |
|   Eve   | Developer | 91000  |
|   Bob   |  Designer | 82000  |
|  Diana  |  Analyst  | 78000  |
+---------+-----------+--------+

You can also sort inline using get_string():

print(table.get_string(sortby="Name", reversesort=False))

Customizing Table Appearance

Text Alignment

Control alignment per column using the align property:

from prettytable import PrettyTable

table = PrettyTable()
table.field_names = ["Item", "Quantity", "Price"]
table.add_row(["Laptop", 5, "$1,200"])
table.add_row(["Mouse", 50, "$25"])
table.add_row(["Keyboard", 30, "$75"])

table.align["Item"] = "l"
table.align["Quantity"] = "r"
table.align["Price"] = "r"

print(table)

Output:

+----------+----------+--------+
| Item     | Quantity |  Price |
+----------+----------+--------+
| Laptop   |        5 | $1,200 |
| Mouse    |       50 |    $25 |
| Keyboard |       30 |    $75 |
+----------+----------+--------+

Changing Table Style

PrettyTable includes several preset styles:

from prettytable import PrettyTable, MARKDOWN, MSWORD_FRIENDLY, PLAIN_COLUMNS

table = PrettyTable()
table.field_names = ["Name", "Score"]
table.add_row(["Alice", 95])
table.add_row(["Bob", 82])

table.set_style(MARKDOWN)
print("Markdown style:")
print(table)

table.set_style(PLAIN_COLUMNS)
print("\nPlain columns style:")
print(table)

Output:

Markdown style:
|  Name | Score |
| :---: | :---: |
| Alice |   95  |
|  Bob  |   82  |

Plain columns style:
 Name        Score
Alice          95
 Bob           82

Customizing Borders and Padding

from prettytable import PrettyTable

table = PrettyTable()
table.field_names = ["Name", "Score"]
table.add_row(["Alice", 95])
table.add_row(["Bob", 82])

table.padding_width = 3

table.junction_char = "+"
table.horizontal_char = "="
table.vertical_char = "‖"

print(table)

Output:

+===========+===========+
‖    Name   ‖   Score   ‖
+===========+===========+
‖   Alice   ‖     95    ‖
‖    Bob    ‖     82    ‖
+===========+===========+

Generating HTML Output

PrettyTable can export your table as an HTML string, useful for embedding in web pages or reports:

from prettytable import PrettyTable

table = PrettyTable()
table.field_names = ["Name", "Role", "Salary"]
table.add_row(["Alice", "Engineer", 95000])
table.add_row(["Bob", "Designer", 82000])

html = table.get_html_string()
print(html)

Output:

<table>
    <thead>
        <tr>
            <th>Name</th>
            <th>Role</th>
            <th>Salary</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Alice</td>
            <td>Engineer</td>
            <td>95000</td>
        </tr>
        <tr>
            <td>Bob</td>
            <td>Designer</td>
            <td>82000</td>
        </tr>
    </tbody>
</table>

You can add HTML attributes like classes or IDs:

html = table.get_html_string(attributes={"id": "salary-table", "class": "data-table"})

Loading Data from CSV Files

PrettyTable can read data directly from CSV files:

from prettytable import from_csv

with open("employees.csv", "r") as f:
    table = from_csv(f)

print(table)

This automatically uses the first row of the CSV as column headers and populates the table with the remaining rows.

Quick Reference

Feature Code
Create table table = PrettyTable()
Set headers table.field_names = ["A", "B"]
Add row table.add_row(["val1", "val2"])
Add column table.add_column("Name", [values])
Delete row table.del_row(index)
Clear rows table.clear_rows()
Sort ascending table.sortby = "Column"
Sort descending table.reversesort = True
Select columns table.get_string(fields=["A"])
Select rows table.get_string(start=1, end=3)
Set alignment table.align["Column"] = "l"
Get HTML table.get_html_string()

Conclusion

PrettyTable is a simple yet powerful library for generating formatted ASCII tables in Python. It handles all the tedious work of calculating column widths, aligning text, and drawing borders.

  • Whether you're building CLI tools, generating reports, or simply debugging data in the terminal, PrettyTable gives you clean, professional output with just a few lines of code.
  • Its support for sorting, filtering, custom styling, and HTML export makes it versatile enough for a wide range of applications.
Navigation