{"id":13496647,"url":"https://github.com/phsym/prettytable-rs","last_synced_at":"2025-05-14T06:14:36.468Z","repository":{"id":32838386,"uuid":"36431733","full_name":"phsym/prettytable-rs","owner":"phsym","description":"A rust library to print aligned and formatted tables","archived":false,"fork":false,"pushed_at":"2024-09-20T04:41:24.000Z","size":40426,"stargazers_count":993,"open_issues_count":47,"forks_count":76,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-05-06T22:50:06.284Z","etag":null,"topics":["cli","crates","formatting","rust"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/prettytable-rs","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phsym.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-05-28T10:38:11.000Z","updated_at":"2025-05-06T05:26:14.000Z","dependencies_parsed_at":"2022-06-29T22:41:32.351Z","dependency_job_id":"bbf597a3-382a-42f4-8194-3eacf0972e10","html_url":"https://github.com/phsym/prettytable-rs","commit_stats":{"total_commits":253,"total_committers":28,"mean_commits":9.035714285714286,"dds":0.5770750988142292,"last_synced_commit":"4d66e6ebddcd52b641369042b68959ad323d9ad0"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phsym%2Fprettytable-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phsym%2Fprettytable-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phsym%2Fprettytable-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phsym%2Fprettytable-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phsym","download_url":"https://codeload.github.com/phsym/prettytable-rs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254083939,"owners_count":22011905,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","crates","formatting","rust"],"created_at":"2024-07-31T19:01:54.387Z","updated_at":"2025-05-14T06:14:36.421Z","avatar_url":"https://github.com/phsym.png","language":"Rust","readme":"![License](http://img.shields.io/badge/license-BSD-lightgrey.svg)\r\n[![Build Status](https://travis-ci.org/phsym/prettytable-rs.svg?branch=master)](https://travis-ci.org/phsym/prettytable-rs)\r\n[![Build status](https://ci.appveyor.com/api/projects/status/wdh9klb35fed6ik9?svg=true)](https://ci.appveyor.com/project/phsym/tabprint)\r\n[![codecov](https://codecov.io/gh/phsym/prettytable-rs/branch/master/graph/badge.svg)](https://codecov.io/gh/phsym/prettytable-rs)\r\n[![Crates.io](https://img.shields.io/crates/v/prettytable-rs.svg)](https://crates.io/crates/prettytable-rs)\r\n[![Doc.rs](https://docs.rs/prettytable-rs/badge.svg)](https://docs.rs/crate/prettytable-rs/)\r\n[![Doc.rs](https://img.shields.io/badge/docs-master-blue.svg)](http://phsym.github.io/prettytable-rs/master)\r\n\r\n# prettytable-rs\r\n\r\nA formatted and aligned table printer library for [Rust](https://www.rust-lang.org).\r\n\r\n*Copyright \u0026copy; 2022 Pierre-Henri Symoneaux*\r\n\r\n\u003e THIS SOFTWARE IS DISTRIBUTED WITHOUT ANY WARRANTY \u003cbr\u003e\r\n\u003e Check LICENSE.txt file for more information. \u003cbr\u003e\r\n\r\n# How to use\r\n\r\n  * [Including](#user-content-including)\r\n  * [Basic usage](#user-content-basic-usage)\r\n  * [Using macros](#user-content-using-macros)\r\n  * [Do it with style](#user-content-do-it-with-style)\r\n    * [List of style specifiers](#user-content-list-of-style-specifiers)\r\n    * [List of color specifiers](#user-content-list-of-color-specifiers)\r\n  * [Slicing](#user-content-slicing)\r\n  * [Customize look and feel of a table](#customize-look-and-feel-of-a-table)\r\n  * [CSV import/export](#user-content-csv-importexport)\r\n    * [Importing](#user-content-importing)\r\n    * [Exporting](#user-content-exporting)\r\n  * [Note on line endings](#user-content-note-on-line-endings)\r\n  * [Evcxr Integration](#evcxr-integration)\r\n\r\n## Including\r\n\r\nInclude the library as a dependency to your project by adding the following lines to your **Cargo.toml** file:\r\n\r\n```toml\r\n[dependencies]\r\nprettytable-rs = \"^0.10\"\r\n```\r\n\r\nThe library requires at least `rust v1.56`.\r\n\r\nAny changes to the MSRV will be done with a minor version bump.\r\n\r\n## SemVer Policy\r\n\r\n* Pre-1.0.0 breaking changes will follow a minor version bump\r\n* Post-1.0.0 All default features of this library are covered by SemVer\r\n* MSRV is considered exempt from SemVer as noted above\r\n\r\n## Basic usage\r\n\r\nStart using it like this:\r\n\r\n```rust\r\n#[macro_use] extern crate prettytable;\r\nuse prettytable::{Table, Row, Cell};\r\n\r\nfn main() {\r\n    // Create the table\r\n    let mut table = Table::new();\r\n\r\n    // Add a row per time\r\n    table.add_row(row![\"ABC\", \"DEFG\", \"HIJKLMN\"]);\r\n    table.add_row(row![\"foobar\", \"bar\", \"foo\"]);\r\n    // A more complicated way to add a row:\r\n    table.add_row(Row::new(vec![\r\n        Cell::new(\"foobar2\"),\r\n        Cell::new(\"bar2\"),\r\n        Cell::new(\"foo2\")]));\r\n\r\n    // Print the table to stdout\r\n    table.printstd();\r\n}\r\n```\r\n\r\nThe code above will output\r\n\r\n```text\r\n+---------+------+---------+\r\n| ABC     | DEFG | HIJKLMN |\r\n+---------+------+---------+\r\n| foobar  | bar  | foo     |\r\n+---------+------+---------+\r\n| foobar2 | bar2 | foo2    |\r\n+---------+------+---------+\r\n```\r\n\r\n## Using macros\r\n\r\nFor everyday usage consider `table!` macro. This code will produce the same output as above:\r\n```rust\r\n#[macro_use] extern crate prettytable;\r\n\r\nfn main() {\r\n    let table = table!([\"ABC\", \"DEFG\", \"HIJKLMN\"],\r\n                       [\"foobar\", \"bar\", \"foo\"],\r\n                       [\"foobar2\", \"bar2\", \"foo2\"]);\r\n\r\n    table.printstd();\r\n}\r\n```\r\n\r\nThe `ptable!` macro combines creating and printing a table:\r\n```rust\r\n#[macro_use] extern crate prettytable;\r\n\r\nfn main() {\r\n    let table = ptable!([\"ABC\", \"DEFG\", \"HIJKLMN\"],\r\n                        [\"foobar\", \"bar\", \"foo\"],\r\n                        [\"foobar2\", \"bar2\", \"foo2\"]);\r\n}\r\n```\r\n\r\nTables also support multiline cells content. As a result, you can print a table into another table (yo dawg ;).\r\nFor example:\r\n```rust\r\nlet table1 = table!([\"ABC\", \"DEFG\", \"HIJKLMN\"],\r\n                    [\"foobar\", \"bar\", \"foo\"],\r\n                    [\"foobar2\", \"bar2\", \"foo2\"]);\r\n\r\nlet table2 = table!([\"Title 1\", \"Title 2\"],\r\n                    [\"This is\\na multiline\\ncell\", \"foo\"],\r\n                    [\"Yo dawg ;) You can even\\nprint tables\\ninto tables\", table1]);\r\n\r\ntable2.printstd();\r\n```\r\nwill print\r\n```text\r\n+-------------------------+------------------------------+\r\n| Title 1                 | Title 2                      |\r\n+-------------------------+------------------------------+\r\n| This is                 | foo                          |\r\n| a multiline             |                              |\r\n| cell                    |                              |\r\n+-------------------------+------------------------------+\r\n| Yo dawg ;) You can even | +---------+------+---------+ |\r\n| print tables            | | ABC     | DEFG | HIJKLMN | |\r\n| into tables             | +---------+------+---------+ |\r\n|                         | | foobar  | bar  | foo     | |\r\n|                         | +---------+------+---------+ |\r\n|                         | | foobar2 | bar2 | foo2    | |\r\n|                         | +---------+------+---------+ |\r\n+-------------------------+------------------------------+\r\n```\r\n\r\nRows may have different numbers of cells. The table will automatically adapt to the largest row by printing additional empty cells in smaller rows.\r\n\r\n## Do it with style!\r\n\r\nTables 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.\r\n\r\n`term` style attributes are reexported\r\n\r\n- directly:\r\n  ```rust\r\n  use prettytable::{Attr, color};\r\n\r\n  /* ... */\r\n\r\n  table.add_row(Row::new(vec![\r\n      Cell::new(\"foobar\")\r\n          .with_style(Attr::Bold)\r\n          .with_style(Attr::ForegroundColor(color::GREEN)),\r\n      Cell::new(\"bar\")\r\n          .with_style(Attr::BackgroundColor(color::RED))\r\n          .with_style(Attr::Italic(true))\r\n          .with_hspan(2),\r\n      Cell::new(\"foo\")\r\n      ]));\r\n  ```\r\n\r\n- through style strings:\r\n  ```rust\r\n  table.add_row(Row::new(vec![\r\n      Cell::new(\"foobar\").style_spec(\"bFg\"),\r\n      Cell::new(\"bar\").style_spec(\"BriH2\"),\r\n      Cell::new(\"foo\")]));\r\n  ```\r\n\r\n- using `row!` macro:\r\n  ```rust\r\n  table.add_row(row![bFg-\u003e\"foobar\", BriH2-\u003e\"bar\", \"foo\"]);\r\n  ```\r\n\r\n- using `table!` macro (this one creates a new table, unlike previous examples):\r\n  ```rust\r\n  table!([bFg-\u003e\"foobar\", BriH2-\u003e\"bar\", \"foo\"]);\r\n  ```\r\n\r\nHere\r\n- **bFg** means **bold**, **F**oreground: **g**reen,\r\n- **BriH2** means **B**ackground: **r**ed, **i**talic, **H**orizontal span of **2**.\r\n\r\nAnother example: **FrBybc** means **F**oreground: **r**ed, **B**ackground: **y**ellow, **b**old, **c**enter.\r\n\r\nAll cases of styling cells in macros:\r\n\r\n- With `row!`, for each cell separately:\r\n  ```rust\r\n  row![FrByb-\u003e\"ABC\", FrByb-\u003e\"DEFG\", \"HIJKLMN\"];\r\n  ```\r\n- With `row!`, for the whole row:\r\n  ```rust\r\n  row![FY =\u003e \"styled\", \"bar\", \"foo\"];\r\n  ```\r\n- With `table!`, for each cell separately:\r\n  ```rust\r\n  table!([FrBybl-\u003e\"A\", FrBybc-\u003e\"B\", FrBybr-\u003e\"C\"], [123, 234, 345, 456]);\r\n  ```\r\n- With `table!`, for whole rows:\r\n  ```rust\r\n  table!([Frb =\u003e \"A\", \"B\", \"C\"], [Frb =\u003e 1, 2, 3, 4], [1, 2, 3]);\r\n  ```\r\n- With `table!`, mixed styling:\r\n  ```rust\r\n  table!([Frb =\u003e \"A\", \"B\", \"C\"], [Frb-\u003e1, Fgi-\u003e2, 3, 4], [1, 2, 3]);\r\n  ```\r\n\r\n### List of style specifiers:\r\n\r\n* **F** : **F**oreground (must be followed by a color specifier)\r\n* **B** : **B**ackground (must be followed by a color specifier)\r\n* **H** : **H**orizontal span (must be followed by a number)\r\n* **b** : **b**old\r\n* **i** : **i**talic\r\n* **u** : **u**nderline\r\n* **c** : Align **c**enter\r\n* **l** : Align **l**eft\r\n* **r** : Align **r**ight\r\n* **d** : **d**efault style\r\n\r\n### List of color specifiers:\r\n\r\nLowercase letters stand for **usual** colors:\r\n* **r** : Red\r\n* **b** : Blue\r\n* **g** : Green\r\n* **y** : Yellow\r\n* **c** : Cyan\r\n* **m** : Magenta\r\n* **w** : White\r\n* **d** : Black\r\n\r\nUppercase letters stand for **bright** counterparts of the above colors:\r\n* **R** : Bright Red\r\n* **B** : Bright Blue\r\n* ... and so on ...\r\n\r\n## Slicing\r\n\r\nTables can be sliced into immutable borrowed subtables.\r\nSlices are of type `prettytable::TableSlice\u003c'a\u003e`.\r\n\r\nFor example,\r\n```rust\r\nuse prettytable::Slice;\r\n/* ... */\r\nlet slice = table.slice(2..5);\r\ntable.printstd();\r\n```\r\nwill print a table with only lines 2, 3 and 4 from `table`.\r\n\r\nOther `Range` syntaxes are supported. For example:\r\n```rust\r\ntable.slice(..); // Returns a borrowed immutable table with all rows\r\ntable.slice(2..); // Returns a table with rows starting at index 2\r\ntable.slice(..3); // Returns a table with rows until the one at index 3\r\n```\r\n\r\n## Customize look and feel of a table\r\n\r\nThe look and feel of a table can be customized with `prettytable::format::TableFormat`.\r\n\r\nConfigurable settings include:\r\n- Borders (left and right)\r\n- Junctions\r\n- Column separators\r\n- Line separators\r\n- Titles (using `table.set_titles()`)\r\n\r\nTo do this, either:\r\n- create a new `TableFormat` object, then call setters until you get the desired configuration;\r\n- or use the convenient `FormatBuilder` and Builder pattern, shown below\r\n\r\n```rust\r\nlet mut table = Table::new();\r\nlet format = format::FormatBuilder::new()\r\n    .column_separator('|')\r\n    .borders('|')\r\n    .separators(\u0026[format::LinePosition::Top,\r\n                  format::LinePosition::Bottom],\r\n                format::LineSeparator::new('-', '+', '+', '+'))\r\n    .padding(1, 1)\r\n    .build();\r\ntable.set_format(format);\r\n\r\ntable.set_titles(row![\"Title 1\", \"Title 2\"]);\r\ntable.add_row(row![\"Value 1\", \"Value 2\"]);\r\ntable.add_row(row![\"Value three\", \"Value four\"]);\r\n```\r\n\r\nThe code above will make the table look like\r\n```\r\n+-------------+------------+\r\n| Title 1     | Title 2    |\r\n| Value 1     | Value 2    |\r\n| Value three | Value four |\r\n+-------------+------------+\r\n```\r\n\r\nFor convenience, several formats are predefined in `prettytable::format::consts` module.\r\n\r\nSome formats and their respective outputs:\r\n- ```rust\r\n  use prettytable::format;\r\n\r\n  table.set_format(*format::consts::FORMAT_NO_LINESEP_WITH_TITLE);\r\n  ```\r\n  ```\r\n  +-------------+------------+\r\n  | Title 1     | Title 2    |\r\n  +-------------+------------+\r\n  | Value 1     | Value 2    |\r\n  | Value three | Value four |\r\n  +-------------+------------+\r\n  ```\r\n- ```rust\r\n  use prettytable::format;\r\n\r\n  table.set_format(*format::consts::FORMAT_NO_BORDER_LINE_SEPARATOR);\r\n  ```\r\n  ```\r\n  Title 1     | Title 2\r\n  ------------+------------\r\n  Value 1     | Value 2\r\n  Value three | Value four\r\n  ```\r\n\r\nCheck API documentation for the full list of available predefined formats.\r\n\r\n## CSV import/export\r\nTables can be imported from and exported to **CSV**.  This is possible thanks to the default \u0026 optional feature `csv`.\r\n\u003e The `csv` feature may become deactivated by default on future major releases.\r\n\r\n### Importing\r\nA `Table` can be imported from a string:\r\n```rust\r\nlet table = Table::from_csv_string(\"ABC,DEFG,HIJKLMN\\n\\\r\n                                    foobar,bar,foo\\n\\\r\n                                    foobar2,bar2,foo2\")?;\r\n```\r\nor from CSV files:\r\n```rust\r\nlet table = Table::from_csv_file(\"input_csv.txt\")?;\r\n```\r\n\u003e Those 2 ways of importing CSV assumes a CSV format with `no headers`, and delimited with `commas`\r\n\r\nImport can also be done from a CSV reader which allows more customization around the CSV format:\r\n```rust\r\nlet reader = /* create a reader */;\r\n/* do something with the reader */\r\nlet table = Table::from_csv(reader);\r\n```\r\n\r\n### Exporting\r\nExport to a generic `Write`:\r\n```rust\r\nlet out = File::create(\"output_csv.txt\")?;\r\ntable.to_csv(out)?;\r\n```\r\nor to a `csv::Writer\u003cW: Write\u003e`:\r\n```rust\r\nlet writer = /* create a writer */;\r\n/* do something with the writer */\r\ntable.to_csv_writer(writer)?;\r\n```\r\n\r\n## Note on line endings\r\nBy default, the library prints tables with platform specific line ending. This means on Windows,\r\nnewlines will be rendered with `\\r\\n` while on other platforms they will be rendered with `\\n`.\r\nSince `v0.6.3`, platform specific line endings are activated though the default feature `win_crlf`, which can be deactivated.\r\nWhen this feature is deactivated (for instance with the `--no-default-features` flag in cargo), line endings will be rendered with `\\n`\r\non any platform.\r\n\r\nThis customization capability will probably move to Formatting API in a future release.\r\n\r\nAdditional examples are provided in the documentation and in [examples](./examples/) directory.\r\n\r\n## Evcxr Integration\r\n\r\n[Evcxr][evcxr] is a Rust REPL and a [Jupyter notebook kernel][evcxr-jupyter].\r\nThis crate integrates into Evcxr and the Jupyter notebooks using the `evcxr` feature flag, which enables native displays of tables.\r\nThis includes support for displaying colors and various formattings.\r\n\r\nYou can include prettytable as a dependency using this line:\r\n```\r\n:dep prettytable = { git = \"https://github.com/phsym/prettytable-rs\", package = \"prettytable-rs\", features = [\"evcxr\"] }\r\n```\r\n\r\n![prettytable being used in a Jupyter notebook with Evcxr Rust kernel.](./prettytable-evcxr.png)\r\n\r\n[evcxr]: https://github.com/google/evcxr/\r\n[evcxr-jupyter]: https://github.com/google/evcxr/blob/master/evcxr_jupyter/README.md\r\n","funding_links":[],"categories":["Rust","cli"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphsym%2Fprettytable-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphsym%2Fprettytable-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphsym%2Fprettytable-rs/lists"}