Таблиця

Дата оновлення перекладу 2022-12-12

Таблиця

При побудові додатку консоллі може бути корисно відображати дані у табличному вигляді:

1
2
3
4
5
6
7
8
+---------------+--------------------------+------------------+
| ISBN          | Назва                    | Автор            |
+---------------+--------------------------+------------------+
| 99921-58-10-7 | Божественна комедія      | Данте Алігʼєрі   |
| 9971-5-0210-0 | Повість про двоє міст    | Чарлз Дікенс     |
| 960-425-059-0 | Володар перснів          | Дж. Р. Р. Толкін |
| 80-902734-1-6 | І нікого не стало        | Агата Крісті     |
+---------------+--------------------------+------------------+

Щоб відобразити таблицю, використайте 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', 'Божественна комедія', 'Данте Алігʼєрі'],
                ['9971-5-0210-0', 'Повість про двоє міст', 'Чарлз Дікенс'],
                ['960-425-059-0', 'Володар перснів', 'Дж. Р. Р. Толкін'],
                ['80-902734-1-6', 'І нікого не стало', 'Агата Крісті'],
            ])
        ;
        $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', 'Божественна комедія', 'Данте Алігʼєрі'],
    ['9971-5-0210-0', 'Повість про двоє міст', 'Чарлз Дікенс'],
    new TableSeparator(),
    ['960-425-059-0', 'Володар перснів', 'Дж. Р. Р. Толкін'],
    ['80-902734-1-6', 'І нікого не стало', 'Агата Крісті'],
]);
1
2
3
4
5
6
7
8
9
+---------------+--------------------------+------------------+
| ISBN          | Назва                    | Автор            |
+---------------+--------------------------+------------------+
| 99921-58-10-7 | Божественна комедія      | Данте Алігʼєрі   |
| 9971-5-0210-0 | Повість про двоє міст    | Чарлз Дікенс     |
+---------------+--------------------------+------------------+
| 960-425-059-0 | Володар перснів          | Дж. Р. Р. Толкін |
| 80-902734-1-6 | І нікого не стало        | Агата Крісті     |
+---------------+--------------------------+------------------+

Як варіант, ви можете відобразити назви зверху та знизу таблиці:

1
2
3
4
// ...
$table->setHeaderTitle('Books');
$table->setFooterTitle('Page 1/2');
$table->render();
1
2
3
4
5
6
7
8
9
+---------------+--------------------------+--------------------------------+
| ISBN          | Назва                    | Автор                          |
+---------------+--------------------------+--------------------------------+
| 99921-58-10-7 | Божественна комедія      | Данте Алігʼєрі                 |
| 9971-5-0210-0 | Повість про двоє міст    | Чарлз Дікенс                   |
+---------------+--------------------------+--------------------------------+
| 960-425-059-0 | Володар перснів          | Дж. Р. Р. Толкіен              |
| 80-902734-1-6 | І нікого не стало        | Агата Крісті                   |
+---------------+----- Сторінка 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          | Назва                    | Автор                          |
+---------------+--------------------------+--------------------------------+
| 99921-58-10-7 | Божественна комедія      | Данте Алігʼєрі                 |
| 9971-5-0210-0 | Повість про двоє міст    | Чарлз Дікенс                   |
+---------------+--------------------------+--------------------------------+
| 960-425-059-0 | Володар перснів          | Дж. Р. Р. Толкін               |
| 80-902734-1-6 | І нікого не стало        | Агата Крісті                   |
+---------------+--------------------------+--------------------------------+

Відмітьте, що визначені ширини стовпців завжди розглядаються як мінімальна ширина стовпця. Якщо зміт не влазить, задана ширина стовпця збільшується до довжини найдовшого змісту. Тому у пеопередньому прикладі перший стовпець має довжину 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  | Назва      | Автор                          |
+-------+------------+--------------------------------+
| 99921 | Божествен  | Данте Алігʼєрі                 |
| -58-1 | на комедія |                                |
| 0-7   |            |                                |
|                (решта рядків...)                    |
+-------+------------+--------------------------------+

За замовчуванням, зміст таблиці відображається горизонтально. Ви можете змінити цю поведінку через метод setVertical():

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

Виведення цієї команди буде:

1
2
3
4
5
6
7
8
9
+------------------------------+
|   ISBN: 99921-58-10-7        |
|  Назва: Божественна комедія  |
|  Автор: Данте Алігʼєрі       |
|------------------------------|
|   ISBN: 9971-5-0210-0        |
|  Назва: Повість про двоє міст|
|  Автор: Чарлз Дікенс         |
+------------------------------+

6.1

Підтримка вертикального відображення була представлена в Symfony 6.1.

Стиль таблиці можна змінити на будь-який вбудований стіль через setStyle():

1
2
3
4
5
6
// те ж саме, що не викликати нічого
$table->setStyle('default');

// змінює стиль за замовчуванням на компактний
$table->setStyle('compact');
$table->render();

Цей код призведе до:

1
2
3
4
5
ISBN          Назва                    Автор
99921-58-10-7 Божественна комедія      Данте Алігʼєрі
9971-5-0210-0 Повість про двоє міст    Чарлз Дікенс
960-425-059-0 Володар перснів.         Дж. Р. Р. Толкін
80-902734-1-6 І нікого не стало        Агата Крісті

Ви також можете встановити стиль borderless:

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

що виведе:

1
2
3
4
5
6
7
8
=============== ========================== ==================
 ISBN            Назва                      Автор
=============== ========================== ==================
 99921-58-10-7   Божественна комедія        Данте Алігʼєрі
 9971-5-0210-0   Повість про двоє міст      Чарлз Дікенс
 960-425-059-0   Володар перснів            Дж. Р. Р. Толкін
 80-902734-1-6   І нікого не стало          Агата Крісті
=============== ========================== ==================

Ви також можете встановити стиль box:

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

which outputs:

1
2
3
4
5
6
7
8
┌───────────────┬──────────────────────────┬──────────────────┐
│ ISBN          │ Назва                    │ Автор            │
├───────────────┼──────────────────────────┼──────────────────┤
│ 99921-58-10-7 │ Божественна комедія      │ Данте Алігʼєрі   │
│ 9971-5-0210-0 │ Повість про двоє міст    │ Чарлз Дікенс     │
│ 960-425-059-0 │ Володар перснів          │ Дж. Р. Р. Толкін │
│ 80-902734-1-6 │ І нікого не стало        │ Агата Крісті     │
└───────────────┴──────────────────────────┴──────────────────┘

Ви також можете встановити стиль box-double:

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

що виведе:

1
2
3
4
5
6
7
8
╔═══════════════╤══════════════════════════╤══════════════════╗
║ ISBN          │ Назва                    │ Автор            ║
╠═══════════════╪══════════════════════════╪══════════════════╣
║ 99921-58-10-7 │ Божественна комедія      │ Данте Алігʼєрі   ║
║ 9971-5-0210-0 │ Повість про двоє міст    │ Чарлз Дікенс     ║
║ 960-425-059-0 │ Володар перснів          │ Дж. Р. Р. Толкін ║
║ 80-902734-1-6 │ І нікого не стало        │ Агата Крісті     ║
╚═══════════════╧══════════════════════════╧══════════════════╝

Якщо вбудовані стилі не відповідають вашим потребами, визначте власний:

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

// за замовчуванням, це засновано на стилі за замовчуванням
$tableStyle = new TableStyle();

// налаштовує стиль
$tableStyle
    ->setHorizontalBorderChars('<fg=magenta>|</>')
    ->setVerticalBorderChars('<fg=magenta>-</>')
    ->setDefaultCrossingChar(' ')
;

// використовує користувацький стиль для цієї таблиці
$table->setStyle($tableStyle);

Ось повний список речей, які ви можете налаштувати:

Tip

Ви також можете зареєструвати стиль глобально:

1
2
3
4
5
// реєструє стиль під назвою "сcolorful"
Table::setStyleDefinition('colorful', $tableStyle);

// застосовує користувацький стиль для заданої таблиці
$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(
            'Божественна комедія',
            [
                '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', 'Божественна комедія', 'Данте Алігʼєрі'],
        new TableSeparator(),
        [new TableCell('Це значення обʼєднує 3 стовпці.', ['colspan' => 3])],
    ])
;
$table->render();

Це призводить до:

1
2
3
4
5
6
7
+---------------+----------------------+-----------------+
| ISBN          | Назва                | Автор           |
+---------------+----------------------+-----------------+
| 99921-58-10-7 | Божественна комедія  | Данте Алігʼєрі  |
+---------------+----------------------+-----------------+
| Це значення обʼєднує 3 стовпці.                        |
+---------------+----------------------+-----------------+

Tip

Ви можете створити назву сторінки у декілька рядків, використовуючи комірку, що обʼєднує всю ширину таблиці:

1
2
3
4
5
$table->setHeaders([
    [new TableCell('Назва головної таблиці', ['colspan' => 3])],
    ['ISBN', 'Title', 'Author'],
]);
// ...

Це генерує:

1
2
3
4
5
6
7
+-------+----------+--------+
| Назва головної таблиці    |
+-------+----------+--------+
| ISBN  | Назва    | Автор  |
+-------+----------+--------+
| ...                       |
+-------+----------+--------+

Схожим чином ви можете обʼєднати декілька рядків:

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',
            'Монархія',
            new TableCell("Данте Алігʼєрі\nspans multiple rows", ['rowspan' => 2]),
        ],
        ['978-0804169127', 'Divine Comedy'],
    ])
;
$table->render();

Це виводить:

1
2
3
4
5
6
+----------------+----------------------+----------------------------+
| ISBN           | Назва                | Автор                      |
+----------------+----------------------+----------------------------+
| 978-0521567817 | Монархія             | Данте Алігʼєрі             |
| 978-0804169127 | Божественна комедія  | обʼєднує декілька рядків   |
+----------------+----------------------+----------------------------+

Ви можете використовувати опції colspan і rowspan одночасно, що дозволяє вам створювати будь-який бажаний макет таблиці.

Зміна відображених таблиць

Метод 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 |
+---------+