Table

Table

When building a console application it may be useful to display tabular data:

  1. +---------------+--------------------------+------------------+
  2. | ISBN | Title | Author |
  3. +---------------+--------------------------+------------------+
  4. | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
  5. | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
  6. | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
  7. | 80-902734-1-6 | And Then There Were None | Agatha Christie |
  8. +---------------+--------------------------+------------------+

To display a table, use Symfony\Component\Console\Helper\Table, set the headers, set the rows and then render the table:

  1. use Symfony\Component\Console\Command\Command;
  2. use Symfony\Component\Console\Helper\Table;
  3. use Symfony\Component\Console\Input\InputInterface;
  4. use Symfony\Component\Console\Output\OutputInterface;
  5. // ...
  6. class SomeCommand extends Command
  7. {
  8. public function execute(InputInterface $input, OutputInterface $output)
  9. {
  10. $table = new Table($output);
  11. $table
  12. ->setHeaders(['ISBN', 'Title', 'Author'])
  13. ->setRows([
  14. ['99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'],
  15. ['9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'],
  16. ['960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'],
  17. ['80-902734-1-6', 'And Then There Were None', 'Agatha Christie'],
  18. ])
  19. ;
  20. $table->render();
  21. }
  22. }

You can add a table separator anywhere in the output by passing an instance of Symfony\Component\Console\Helper\TableSeparator as a row:

  1. use Symfony\Component\Console\Helper\TableSeparator;
  2. $table->setRows([
  3. ['99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'],
  4. ['9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'],
  5. new TableSeparator(),
  6. ['960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'],
  7. ['80-902734-1-6', 'And Then There Were None', 'Agatha Christie'],
  8. ]);
  1. +---------------+--------------------------+------------------+
  2. | ISBN | Title | Author |
  3. +---------------+--------------------------+------------------+
  4. | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
  5. | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
  6. +---------------+--------------------------+------------------+
  7. | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
  8. | 80-902734-1-6 | And Then There Were None | Agatha Christie |
  9. +---------------+--------------------------+------------------+

You can optionally display titles at the top and the bottom of the table:

  1. // ...
  2. $table->setHeaderTitle('Books');
  3. $table->setFooterTitle('Page 1/2');
  4. $table->render();
  1. +---------------+----------- Books --------+------------------+
  2. | ISBN | Title | Author |
  3. +---------------+--------------------------+------------------+
  4. | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
  5. | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
  6. +---------------+--------------------------+------------------+
  7. | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
  8. | 80-902734-1-6 | And Then There Were None | Agatha Christie |
  9. +---------------+--------- Page 1/2 -------+------------------+

By default, the width of the columns is calculated automatically based on their contents. Use the [setColumnWidths()](https://github.com/symfony/symfony/blob/4.4/src/Symfony/Component/Console/Helper/Table.php "Symfony\Component\Console\Helper\Table::setColumnWidths()") method to set the column widths explicitly:

  1. // ...
  2. $table->setColumnWidths([10, 0, 30]);
  3. $table->render();

In this example, the first column width will be 10, the last column width will be 30 and the second column width will be calculated automatically because of the 0 value.

You can also set the width individually for each column with the [setColumnWidth()](https://github.com/symfony/symfony/blob/4.4/src/Symfony/Component/Console/Helper/Table.php "Symfony\Component\Console\Helper\Table::setColumnWidth()") method. Its first argument is the column index (starting from 0) and the second argument is the column width:

  1. // ...
  2. $table->setColumnWidth(0, 10);
  3. $table->setColumnWidth(2, 30);
  4. $table->render();

The output of this command will be:

  1. +---------------+--------------------------+--------------------------------+
  2. | ISBN | Title | Author |
  3. +---------------+--------------------------+--------------------------------+
  4. | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
  5. | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
  6. +---------------+--------------------------+--------------------------------+
  7. | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
  8. | 80-902734-1-6 | And Then There Were None | Agatha Christie |
  9. +---------------+--------------------------+--------------------------------+

Note that the defined column widths are always considered as the minimum column widths. If the contents don’t fit, the given column width is increased up to the longest content length. That’s why in the previous example the first column has a 13 character length although the user defined 10 as its width.

If you prefer to wrap long contents in multiple rows, use the [setColumnMaxWidth()](https://github.com/symfony/symfony/blob/4.4/src/Symfony/Component/Console/Helper/Table.php "Symfony\Component\Console\Helper\Table::setColumnMaxWidth()") method:

  1. // ...
  2. $table->setColumnMaxWidth(0, 5);
  3. $table->setColumnMaxWidth(1, 10);
  4. $table->render();

The output of this command will be:

  1. +-------+------------+--------------------------------+
  2. | ISBN | Title | Author |
  3. +-------+------------+--------------------------------+
  4. | 99921 | Divine Com | Dante Alighieri |
  5. | -58-1 | edy | |
  6. | 0-7 | | |
  7. | (the rest of rows...) |
  8. +-------+------------+--------------------------------+

The table style can be changed to any built-in styles via [setStyle()](https://github.com/symfony/symfony/blob/4.4/src/Symfony/Component/Console/Helper/Table.php "Symfony\Component\Console\Helper\Table::setStyle()"):

  1. // same as calling nothing
  2. $table->setStyle('default');
  3. // changes the default style to compact
  4. $table->setStyle('compact');
  5. $table->render();

This code results in:

  1. ISBN Title Author
  2. 99921-58-10-7 Divine Comedy Dante Alighieri
  3. 9971-5-0210-0 A Tale of Two Cities Charles Dickens
  4. 960-425-059-0 The Lord of the Rings J. R. R. Tolkien
  5. 80-902734-1-6 And Then There Were None Agatha Christie

You can also set the style to borderless:

  1. $table->setStyle('borderless');
  2. $table->render();

which outputs:

  1. =============== ========================== ==================
  2. ISBN Title Author
  3. =============== ========================== ==================
  4. 99921-58-10-7 Divine Comedy Dante Alighieri
  5. 9971-5-0210-0 A Tale of Two Cities Charles Dickens
  6. 960-425-059-0 The Lord of the Rings J. R. R. Tolkien
  7. 80-902734-1-6 And Then There Were None Agatha Christie
  8. =============== ========================== ==================

You can also set the style to box:

  1. $table->setStyle('box');
  2. $table->render();

which outputs:

  1. ┌───────────────┬──────────────────────────┬──────────────────┐
  2. ISBN Title Author
  3. ├───────────────┼──────────────────────────┼──────────────────┤
  4. 99921-58-10-7 Divine Comedy Dante Alighieri
  5. 9971-5-0210-0 A Tale of Two Cities Charles Dickens
  6. 960-425-059-0 The Lord of the Rings J. R. R. Tolkien
  7. 80-902734-1-6 And Then There Were None Agatha Christie
  8. └───────────────┴──────────────────────────┴──────────────────┘

You can also set the style to box-double:

  1. $table->setStyle('box-double');
  2. $table->render();

which outputs:

  1. ╔═══════════════╤══════════════════════════╤══════════════════╗
  2. ISBN Title Author
  3. ╠═══════════════╪══════════════════════════╪══════════════════╣
  4. 99921-58-10-7 Divine Comedy Dante Alighieri
  5. 9971-5-0210-0 A Tale of Two Cities Charles Dickens
  6. 960-425-059-0 The Lord of the Rings J. R. R. Tolkien
  7. 80-902734-1-6 And Then There Were None Agatha Christie
  8. ╚═══════════════╧══════════════════════════╧══════════════════╝

If the built-in styles do not fit your need, define your own:

  1. use Symfony\Component\Console\Helper\TableStyle;
  2. // by default, this is based on the default style
  3. $tableStyle = new TableStyle();
  4. // customizes the style
  5. $tableStyle
  6. ->setHorizontalBorderChars('<fg=magenta>|</>')
  7. ->setVerticalBorderChars('<fg=magenta>-</>')
  8. ->setDefaultCrossingChar(' ')
  9. ;
  10. // uses the custom style for this table
  11. $table->setStyle($tableStyle);

Here is a full list of things you can customize:

  • [setPaddingChar()](https://github.com/symfony/symfony/blob/4.4/src/Symfony/Component/Console/Helper/TableStyle.php "Symfony\Component\Console\Helper\TableStyle::setPaddingChar()")
  • [setHorizontalBorderChars()](https://github.com/symfony/symfony/blob/4.4/src/Symfony/Component/Console/Helper/TableStyle.php "Symfony\Component\Console\Helper\TableStyle::setHorizontalBorderChars()")
  • [setVerticalBorderChars()](https://github.com/symfony/symfony/blob/4.4/src/Symfony/Component/Console/Helper/TableStyle.php "Symfony\Component\Console\Helper\TableStyle::setVerticalBorderChars()")
  • [setCrossingChars()](https://github.com/symfony/symfony/blob/4.4/src/Symfony/Component/Console/Helper/TableStyle.php "Symfony\Component\Console\Helper\TableStyle::setCrossingChars()")
  • [setDefaultCrossingChar()](https://github.com/symfony/symfony/blob/4.4/src/Symfony/Component/Console/Helper/TableStyle.php "Symfony\Component\Console\Helper\TableStyle::setDefaultCrossingChar()")
  • [setCellHeaderFormat()](https://github.com/symfony/symfony/blob/4.4/src/Symfony/Component/Console/Helper/TableStyle.php "Symfony\Component\Console\Helper\TableStyle::setCellHeaderFormat()")
  • [setCellRowFormat()](https://github.com/symfony/symfony/blob/4.4/src/Symfony/Component/Console/Helper/TableStyle.php "Symfony\Component\Console\Helper\TableStyle::setCellRowFormat()")
  • [setBorderFormat()](https://github.com/symfony/symfony/blob/4.4/src/Symfony/Component/Console/Helper/TableStyle.php "Symfony\Component\Console\Helper\TableStyle::setBorderFormat()")
  • [setPadType()](https://github.com/symfony/symfony/blob/4.4/src/Symfony/Component/Console/Helper/TableStyle.php "Symfony\Component\Console\Helper\TableStyle::setPadType()")

Tip

You can also register a style globally:

  1. // registers the style under the colorful name
  2. Table::setStyleDefinition('colorful', $tableStyle);
  3. // applies the custom style for the given table
  4. $table->setStyle('colorful');

This method can also be used to override a built-in style.

Spanning Multiple Columns and Rows

To make a table cell that spans multiple columns you can use a Symfony\Component\Console\Helper\TableCell:

  1. use Symfony\Component\Console\Helper\Table;
  2. use Symfony\Component\Console\Helper\TableCell;
  3. use Symfony\Component\Console\Helper\TableSeparator;
  4. $table = new Table($output);
  5. $table
  6. ->setHeaders(['ISBN', 'Title', 'Author'])
  7. ->setRows([
  8. ['99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'],
  9. new TableSeparator(),
  10. [new TableCell('This value spans 3 columns.', ['colspan' => 3])],
  11. ])
  12. ;
  13. $table->render();

This results in:

  1. +---------------+---------------+-----------------+
  2. | ISBN | Title | Author |
  3. +---------------+---------------+-----------------+
  4. | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
  5. +---------------+---------------+-----------------+
  6. | This value spans 3 columns. |
  7. +---------------+---------------+-----------------+

Tip

You can create a multiple-line page title using a header cell that spans the entire table width:

  1. $table->setHeaders([
  2. [new TableCell('Main table title', ['colspan' => 3])],
  3. ['ISBN', 'Title', 'Author'],
  4. ]);
  5. // ...

This generates:

  1. +-------+-------+--------+
  2. | Main table title |
  3. +-------+-------+--------+
  4. | ISBN | Title | Author |
  5. +-------+-------+--------+
  6. | ... |
  7. +-------+-------+--------+

In a similar way you can span multiple rows:

  1. use Symfony\Component\Console\Helper\Table;
  2. use Symfony\Component\Console\Helper\TableCell;
  3. $table = new Table($output);
  4. $table
  5. ->setHeaders(['ISBN', 'Title', 'Author'])
  6. ->setRows([
  7. [
  8. '978-0521567817',
  9. 'De Monarchia',
  10. new TableCell("Dante Alighieri\nspans multiple rows", ['rowspan' => 2]),
  11. ],
  12. ['978-0804169127', 'Divine Comedy'],
  13. ])
  14. ;
  15. $table->render();

This outputs:

  1. +----------------+---------------+---------------------+
  2. | ISBN | Title | Author |
  3. +----------------+---------------+---------------------+
  4. | 978-0521567817 | De Monarchia | Dante Alighieri |
  5. | 978-0804169127 | Divine Comedy | spans multiple rows |
  6. +----------------+---------------+---------------------+

You can use the colspan and rowspan options at the same time which allows you to create any table layout you may wish.

Modifying Rendered Tables

The render() method requires passing the entire table contents. However, sometimes that information is not available beforehand because it’s generated dynamically. In those cases, use the [appendRow()](https://github.com/symfony/symfony/blob/4.4/src/Symfony/Component/Console/Helper/Table.php "Symfony\Component\Console\Helper\Table::appendRow()") method, which takes the same arguments as the addRow() method, to add rows at the bottom of an already rendered table.

The only requirement to append rows is that the table must be rendered inside a Console output section:

  1. use Symfony\Component\Console\Helper\Table;
  2. // ...
  3. class SomeCommand extends Command
  4. {
  5. public function execute(InputInterface $input, OutputInterface $output)
  6. {
  7. $section = $output->section();
  8. $table = new Table($section);
  9. $table->addRow(['Love']);
  10. $table->render();
  11. $table->appendRow(['Symfony']);
  12. }
  13. }

This will display the following table in the terminal:

  1. +---------+
  2. | Love |
  3. | Symfony |
  4. +---------+

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.