A formatted and aligned table printer library for Rust.
Copyright © 2018 Pierre-Henri Symoneaux
THIS SOFTWARE IS DISTRIBUTED WITHOUT ANY WARRANTY
Check LICENSE.txt file for more information.
- Including
- Basic usage
- Using macros
- Do it with style
- Slicing
- Customize your table look and feel
- CSV import/export
- Note on line endings
Include the library as a dependency to your project by adding the following lines to your Cargo.toml file:
[dependencies]
prettytable-rs = "^0.8"
The library requires at least rust v1.26.0
.
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 |
+---------+------+---------+
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.
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]);
- 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
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 ...
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
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.
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.
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 withcommas
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);
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)?;
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.