ランキングに戻る

phsym/prettytable-rs

Rustcrates.io/crates/prettytable-rs

A rust library to print aligned and formatted tables

rustcratescliformatting
スター成長
スター
1.1k
フォーク
78
週間成長
Issue
31
5001k
2015年7月2019年3月2022年11月2026年7月
成果物crates.iocargo add prettytable-rs
README

License Build Status Build status codecov Crates.io Doc.rs Doc.rs

prettytable-rs

A formatted and aligned table printer library for Rust.

Copyright © 2022 Pierre-Henri Symoneaux

THIS SOFTWARE IS DISTRIBUTED WITHOUT ANY WARRANTY
Check LICENSE.txt file for more information.

How to use

Including

Include the library as a dependency to your project by adding the following lines to your Cargo.toml file:

[dependencies]
prettytable-rs = "^0.10"

The library requires at least rust v1.56.

Any changes to the MSRV will be done with a minor version bump.

SemVer Policy

  • Pre-1.0.0 breaking changes will follow a minor version bump
  • Post-1.0.0 All default features of this library are covered by SemVer
  • MSRV is considered exempt from SemVer as noted above

Basic usage

Start using it like this:

#[macro_use] extern crate prettytable;
use prettytable::{Table, Row, Cell};

fn main() {
    // Create the table
    let mut table = Table::new();

    // Add a row per time
    table.add_row(row!["ABC", "DEFG", "HIJKLMN"]);
    table.add_row(row!["foobar", "bar", "foo"]);
    // A more complicated way to add a row:
    table.add_row(Row::new(vec![
        Cell::new("foobar2"),
        Cell::new("bar2"),
        Cell::new("foo2")]));

    // Print the table to stdout
    table.printstd();
}

The code above will output

+---------+------+---------+
| ABC     | DEFG | HIJKLMN |
+---------+------+---------+
| foobar  | bar  | foo     |
+---------+------+---------+
| foobar2 | bar2 | foo2    |
+---------+------+---------+

Using macros

For everyday usage consider table! macro. This code will produce the same output as above:

#[macro_use] extern crate prettytable;

fn main() {
    let table = table!(["ABC", "DEFG", "HIJKLMN"],
                       ["foobar", "bar", "foo"],
                       ["foobar2", "bar2", "foo2"]);

    table.printstd();
}

The ptable! macro combines creating and printing a table:

#[macro_use] extern crate prettytable;

fn main() {
    let table = ptable!(["ABC", "DEFG", "HIJKLMN"],
                        ["foobar", "bar", "foo"],
                        ["foobar2", "bar2", "foo2"]);
}

Tables also support multiline cells content. As a result, you can print a table into another table (yo dawg ;). For example:

let table1 = table!(["ABC", "DEFG", "HIJKLMN"],
                    ["foobar", "bar", "foo"],
                    ["foobar2", "bar2", "foo2"]);

let table2 = table!(["Title 1", "Title 2"],
                    ["This is\na multiline\ncell", "foo"],
                    ["Yo dawg ;) You can even\nprint tables\ninto tables", table1]);

table2.printstd();

will print

+-------------------------+------------------------------+
| Title 1                 | Title 2                      |
+-------------------------+------------------------------+
| This is                 | foo                          |
| a multiline             |                              |
| cell                    |                              |
+-------------------------+------------------------------+
| Yo dawg ;) You can even | +---------+------+---------+ |
| print tables            | | ABC     | DEFG | HIJKLMN | |
| into tables             | +---------+------+---------+ |
|                         | | foobar  | bar  | foo     | |
|                         | +---------+------+---------+ |
|                         | | foobar2 | bar2 | foo2    | |
|                         | +---------+------+---------+ |
+-------------------------+------------------------------+

Rows may have different numbers of cells. The table will automatically adapt to the largest row by printing additional empty cells in smaller rows.

Do it with style!

Tables can have a styled output with background and foreground colors, bold and italic as configurable settings, thanks to the term crate. Alignment in cells can also be set (Left, Right, Center), and a cell can span accross multiple columns.

term style attributes are reexported

  • directly:

    use prettytable::{Attr, color};
    
    /* ... */
    
    table.add_row(Row::new(vec![
        Cell::new("foobar")
            .with_style(Attr::Bold)
            .with_style(Attr::ForegroundColor(color::GREEN)),
        Cell::new("bar")
            .with_style(Attr::BackgroundColor(color::RED))
            .with_style(Attr::Italic(true))
            .with_hspan(2),
        Cell::new("foo")
        ]));
    
  • through style strings:

    table.add_row(Row::new(vec![
        Cell::new("foobar").style_spec("bFg"),
        Cell::new("bar").style_spec("BriH2"),
        Cell::new("foo")]));
    
  • using row! macro:

    table.add_row(row![bFg->"foobar", BriH2->"bar", "foo"]);
    
  • using table! macro (this one creates a new table, unlike previous examples):

    table!([bFg->"foobar", BriH2->"bar", "foo"]);
    

Here

  • bFg means bold, Foreground: green,
  • BriH2 means Background: red, italic, Horizontal span of 2.

Another example: FrBybc means Foreground: red, Background: yellow, bold, center.

All cases of styling cells in macros:

  • With row!, for each cell separately:
    row![FrByb->"ABC", FrByb->"DEFG", "HIJKLMN"];
    
  • With row!, for the whole row:
    row![FY => "styled", "bar", "foo"];
    
  • With table!, for each cell separately:
    table!([FrBybl->"A", FrBybc->"B", FrBybr->"C"], [123, 234, 345, 456]);
    
  • With table!, for whole rows:
    table!([Frb => "A", "B", "C"], [Frb => 1, 2, 3, 4], [1, 2, 3]);
    
  • With table!, mixed styling:
    table!([Frb => "A", "B", "C"], [Frb->1, Fgi->2, 3, 4], [1, 2, 3]);
    

List of style specifiers:

  • F : Foreground (must be followed by a color specifier)
  • B : Background (must be followed by a color specifier)
  • H : Horizontal span (must be followed by a number)
  • b : bold
  • i : italic
  • u : underline
  • c : Align center
  • l : Align left
  • r : Align right
  • d : default style

List of color specifiers:

Lowercase letters stand for usual colors:

  • r : Red
  • b : Blue
  • g : Green
  • y : Yellow
  • c : Cyan
  • m : Magenta
  • w : White
  • d : Black

Uppercase letters stand for bright counterparts of the above colors:

  • R : Bright Red
  • B : Bright Blue
  • ... and so on ...

Slicing

Tables can be sliced into immutable borrowed subtables. Slices are of type prettytable::TableSlice<'a>.

For example,

use prettytable::Slice;
/* ... */
let slice = table.slice(2..5);
table.printstd();

will print a table with only lines 2, 3 and 4 from table.

Other Range syntaxes are supported. For example:

table.slice(..); // Returns a borrowed immutable table with all rows
table.slice(2..); // Returns a table with rows starting at index 2
table.slice(..3); // Returns a table with rows until the one at index 3

Customize look and feel of a table

The look and feel of a table can be customized with prettytable::format::TableFormat.

Configurable settings include:

  • Borders (left and right)
  • Junctions
  • Column separators
  • Line separators
  • Titles (using table.set_titles())

To do this, either:

  • create a new TableFormat object, then call setters until you get the desired configuration;
  • or use the convenient FormatBuilder and Builder pattern, shown below
let mut table = Table::new();
let format = format::FormatBuilder::new()
    .column_separator('|')
    .borders('|')
    .separators(&[format::LinePosition::Top,
                  format::LinePosition::Bottom],
                format::LineSeparator::new('-', '+', '+', '+'))
    .padding(1, 1)
    .build();
table.set_format(format);

table.set_titles(row!["Title 1", "Title 2"]);
table.add_row(row!["Value 1", "Value 2"]);
table.add_row(row!["Value three", "Value four"]);

The code above will make the table look like

+-------------+------------+
| Title 1     | Title 2    |
| Value 1     | Value 2    |
| Value three | Value four |
+-------------+------------+

For convenience, several formats are predefined in prettytable::format::consts module.

Some formats and their respective outputs:

  • use prettytable::format;
    
    table.set_format(*format::consts::FORMAT_NO_LINESEP_WITH_TITLE);
    
    +-------------+------------+
    | Title 1     | Title 2    |
    +-------------+------------+
    | Value 1     | Value 2    |
    | Value three | Value four |
    +-------------+------------+
    
  • use prettytable::format;
    
    table.set_format(*format::consts::FORMAT_NO_BORDER_LINE_SEPARATOR);
    
    Title 1     | Title 2
    ------------+------------
    Value 1     | Value 2
    Value three | Value four
    

Check API documentation for the full list of available predefined formats.

CSV import/export

Tables can be imported from and exported to CSV. This is possible thanks to the default & optional feature csv.

The csv feature may become deactivated by default on future major releases.

Importing

A Table can be imported from a string:

let table = Table::from_csv_string("ABC,DEFG,HIJKLMN\n\
                                    foobar,bar,foo\n\
                                    foobar2,bar2,foo2")?;

or from CSV files:

let table = Table::from_csv_file("input_csv.txt")?;

Those 2 ways of importing CSV assumes a CSV format with no headers, and delimited with commas

Import can also be done from a CSV reader which allows more customization around the CSV format:

let reader = /* create a reader */;
/* do something with the reader */
let table = Table::from_csv(reader);

Exporting

Export to a generic Write:

let out = File::create("output_csv.txt")?;
table.to_csv(out)?;

or to a csv::Writer<W: Write>:

let writer = /* create a writer */;
/* do something with the writer */
table.to_csv_writer(writer)?;

Note on line endings

By default, the library prints tables with platform specific line ending. This means on Windows, newlines will be rendered with \r\n while on other platforms they will be rendered with \n. Since v0.6.3, platform specific line endings are activated though the default feature win_crlf, which can be deactivated. When this feature is deactivated (for instance with the --no-default-features flag in cargo), line endings will be rendered with \n on any platform.

This customization capability will probably move to Formatting API in a future release.

Additional examples are provided in the documentation and in examples directory.

Evcxr Integration

Evcxr is a Rust REPL and a Jupyter notebook kernel. This crate integrates into Evcxr and the Jupyter notebooks using the evcxr feature flag, which enables native displays of tables. This includes support for displaying colors and various formattings.

You can include prettytable as a dependency using this line:

:dep prettytable = { git = "https://github.com/phsym/prettytable-rs", package = "prettytable-rs", features = ["evcxr"] }

prettytable being used in a Jupyter notebook with Evcxr Rust kernel.

関連リポジトリ
farion1231/cc-switch

A cross-platform desktop All-in-One assistant for Claude Code, Codex, OpenCode, OpenClaw, Grok Build & Hermes Agent. Only official website: ccswitch.io

Rustcrates.ioMIT Licenseai-toolsclaude-code
ccswitch.io
119.8k8k
rustdesk/rustdesk

An open-source remote desktop application designed for self-hosting, as an alternative to TeamViewer.

Rustcrates.ioGNU Affero General Public License v3.0remote-controlremote-desktop
rustdesk.com
118.6k18.1k
rust-lang/rust

Empowering everyone to build reliable and efficient software.

Rustcrates.ioApache License 2.0rustcompiler
rust-lang.org
114.8k15.4k
tauri-apps/tauri

Build smaller, faster, and more secure desktop and mobile applications with a web frontend.

Rustcrates.ioApache License 2.0rustwebview
tauri.app
109.3k3.8k
denoland/deno

A modern runtime for JavaScript and TypeScript.

Rustcrates.ioMIT Licensedenotypescript
deno.com
107.8k6.2k
oven-sh/bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one

Rustcrates.ioOtherbunbundler
bun.com
95k4.9k
unionlabs/union

The trust-minimized, zero-knowledge bridging protocol, designed for censorship resistance, extremely high security, and usage in decentralized finance.

Rustcrates.ioApache License 2.0blockchaincosmos
union.build
73.9k3.9k
rtk-ai/rtk

CLI proxy that reduces LLM token consumption by 60-90% on common dev commands. Single Rust binary, zero dependencies

Rustcrates.ioApache License 2.0agentic-codingai-coding
rtk-ai.app
72.4k4.5k
toeverything/AFFiNE

There can be more than Notion and Miro. AFFiNE(pronounced [ə‘fain]) is a next-gen knowledge base that brings planning, sorting and creating all together. Privacy first, open-source, customizable and ready to use.

TypeScriptnpmOthereditorcrdt
affine.pro
70.7k5.1k
openinterpreter/openinterpreter

A coding agent for open models like Kimi K3

Rustcrates.ioApache License 2.0coding-agentdeepseek
openinterpreter.com
67.1k5.8k
BurntSushi/ripgrep

ripgrep recursively searches directories for a regex pattern while respecting your gitignore

Rustcrates.ioThe Unlicenseripgreprecursively-search
66.4k2.7k
alacritty/alacritty

A cross-platform, OpenGL terminal emulator.

Rustcrates.ioApache License 2.0terminal-emulatorsopengl
alacritty.org
65k3.5k