跳到内容

表格

编辑此页

在构建控制台应用程序时,显示表格数据可能很有用

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

注意

作为替代方案,请考虑使用 SymfonyStyle 来显示表格。

要显示表格,请使用 Table,设置标题,设置行,然后渲染表格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
// ...

class SomeCommand extends Command
{
    public function execute(InputInterface $input, OutputInterface $output): int
    {
        $table = new Table($output);
        $table
            ->setHeaders(['ISBN', 'Title', 'Author'])
            ->setRows([
                ['99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'],
                ['9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'],
                ['960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'],
                ['80-902734-1-6', 'And Then There Were None', 'Agatha Christie'],
            ])
        ;
        $table->render();

        return Command::SUCCESS;
    }
}

你可以通过传递 TableSeparator 的实例作为行,在输出中的任何位置添加表格分隔符

1
2
3
4
5
6
7
8
9
use Symfony\Component\Console\Helper\TableSeparator;

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

你可以选择在表格的顶部和底部显示标题

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

默认情况下,列的宽度是根据其内容自动计算的。使用 setColumnWidths() 方法显式设置列宽

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

在此示例中,第一列的宽度将为 10,最后一列的宽度将为 30,而第二列的宽度将由于 0 值而自动计算。

你还可以使用 setColumnWidth() 方法为每列单独设置宽度。它的第一个参数是列索引(从 0 开始),第二个参数是列宽

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

此命令的输出将是

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

请注意,定义的列宽始终被视为最小列宽。如果内容不适合,则给定的列宽将增加到最长内容的长度。这就是为什么在前面的示例中,第一列的长度为 13 个字符,尽管用户定义了 10 作为其宽度。

如果你希望将长内容包装在多行中,请使用 setColumnMaxWidth() 方法

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

此命令的输出将是

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

默认情况下,表格内容水平显示。你可以通过 setVertical() 方法更改此行为

1
2
3
// ...
$table->setVertical();
$table->render();

此命令的输出将是

1
2
3
4
5
6
7
8
9
+------------------------------+
|   ISBN: 99921-58-10-7        |
|  Title: Divine Comedy        |
| Author: Dante Alighieri      |
|------------------------------|
|   ISBN: 9971-5-0210-0        |
|  Title: A Tale of Two Cities |
| Author: Charles Dickens      |
+------------------------------+

表格样式可以通过 setStyle() 更改为任何内置样式

1
2
3
4
5
6
// same as calling nothing
$table->setStyle('default');

// changes the default style to compact
$table->setStyle('compact');
$table->render();

此代码结果为

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

你也可以将样式设置为 borderless

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

输出结果为

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

你也可以将样式设置为 box

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

输出结果为

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

你也可以将样式设置为 box-double

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

输出结果为

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

如果内置样式不符合你的需求,请自定义样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
use Symfony\Component\Console\Helper\TableStyle;

// by default, this is based on the default style
$tableStyle = new TableStyle();

// customizes the style
$tableStyle
    ->setHorizontalBorderChars('<fg=magenta>|</>')
    ->setVerticalBorderChars('<fg=magenta>-</>')
    ->setDefaultCrossingChar(' ')
;

// uses the custom style for this table
$table->setStyle($tableStyle);

以下是你可以自定义的所有内容列表

提示

你也可以全局注册样式

1
2
3
4
5
// registers the style under the colorful name
Table::setStyleDefinition('colorful', $tableStyle);

// applies the custom style for the given table
$table->setStyle('colorful');

此方法也可以用于覆盖内置样式。

除了内置的表格样式外,你还可以通过 TableCellStyle 对每个表格单元格应用不同的样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Helper\TableCellStyle;

$table = new Table($output);

$table->setRows([
    [
        '978-0804169127',
        new TableCell(
            'Divine Comedy',
            [
                'style' => new TableCellStyle([
                    'align' => 'center',
                    'fg' => 'red',
                    'bg' => 'green',

                    // or
                    'cellFormat' => '<info>%s</info>',
                ])
            ]
        )
    ],
]);

$table->render();

跨多列和多行

要创建跨多列的表格单元格,你可以使用 TableCell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Helper\TableCell;
use Symfony\Component\Console\Helper\TableSeparator;

$table = new Table($output);
$table
    ->setHeaders(['ISBN', 'Title', 'Author'])
    ->setRows([
        ['99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'],
        new TableSeparator(),
        [new TableCell('This value spans 3 columns.', ['colspan' => 3])],
    ])
;
$table->render();

结果为

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

提示

你可以使用跨越整个表格宽度的标题单元格创建多行页面标题

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

这将生成

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

以类似的方式,你可以跨越多行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Helper\TableCell;

$table = new Table($output);
$table
    ->setHeaders(['ISBN', 'Title', 'Author'])
    ->setRows([
        [
            '978-0521567817',
            'De Monarchia',
            new TableCell("Dante Alighieri\nspans multiple rows", ['rowspan' => 2]),
        ],
        ['978-0804169127', 'Divine Comedy'],
    ])
;
$table->render();

输出结果为

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

你可以同时使用 colspanrowspan 选项,这使你可以创建任何你想要的表格布局。

修改渲染的表格

render() 方法需要传递整个表格内容。但是,有时这些信息事先不可用,因为它是在动态生成的。在这些情况下,请使用 appendRow() 方法,该方法采用与 addRow() 方法相同的参数,以在已渲染表格的底部添加行。

追加行的唯一要求是表格必须在 控制台输出节 中渲染

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
use Symfony\Component\Console\Helper\Table;
// ...

class SomeCommand extends Command
{
    public function execute(InputInterface $input, OutputInterface $output): int
    {
        $section = $output->section();
        $table = new Table($section);

        $table->addRow(['Love']);
        $table->render();

        $table->appendRow(['Symfony']);

        return Command::SUCCESS;
    }
}

这将在终端中显示以下表格

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

提示

你可以使用 addRows() 方法创建多行

1
2
3
4
5
6
7
// ...
$table->addRows([
    ['Hello', 'World'],
    ['Love', 'Symfony'],
]);
$table->render();
// ...

这将显示

1
2
3
4
+-------+---------+
| Hello | World   |
| Love  | Symfony |
+-------+---------+
本作品,包括代码示例,根据 Creative Commons BY-SA 3.0 许可协议获得许可。
目录
    版本