是否可以使用 Symfony 控制台实现并排 table 布局?

Is it possible to achieve side-by-side table layout with Symfony Console?

┌──────── Summary:  1.1.5 update ─┬───────┐        ┌─────────────────────── Success ─┬─────────────────────┐
│ Success │ Failure │ In Progress │ Total │        │ Site                            │ End Time            │
├─────────┼─────────┼─────────────┼───────┤        ├─────────────────────────────────┼─────────────────────┤
│         │         │             │       │        │ wpscon-clone-400years           │ 2021-10-06 23:51:08 │
│   4     │   0     │   0         │   4   │        │ wpscon-clone-academic-senate-ob │ 2021-10-06 23:51:35 │
│         │         │             │       │        │ wpscon-clone-150w               │ 2021-10-06 23:52:46 │
└─────────┴─────────┴─────────────┴───────┘        │ wpscon-clone-access-ob          │ 2021-10-06 23:51:51 │
                                                   │ wpscon-clone-200                │ 2021-10-06 23:52:46 │
Overall Progress:                                  │ wpscon-clone-200                │ 2021-10-06 23:52:46 │
 4/4 sites complete [==================] 100%      │ wpscon-clone-200                │ 2021-10-06 23:52:46 │ 
                                                   │ wpscon-clone-200                │ 2021-10-06 23:52:46 │
┌──────── Errors  ─┬─────────────────────┐         │ wpscon-clone-200                │ 2021-10-06 23:52:46 │ 
│ Site             │ End Time            │         │ wpscon-clone-200                │ 2021-10-06 23:52:46 │
├──────────────────┼─────────────────────┤         │ wpscon-clone-200                │ 2021-10-06 23:52:46 │ 
│ wpscon-clone-100 │ 2021-10-06 23:51:08 │         │ wpscon-clone-200                │ 2021-10-06 23:52:46 │
│ wpscon-clone-101 │ 2021-10-06 23:51:35 │         │ wpscon-clone-200                │ 2021-10-06 23:52:46 │ 
│ wpscon-clone-102 │ 2021-10-06 23:52:46 │         │ wpscon-clone-200                │ 2021-10-06 23:52:46 │ 
│ wpscon-clone-102 │ 2021-10-06 23:51:51 │         │ wpscon-clone-200                │ 2021-10-06 23:52:46 │
└──────────────────┴─────────────────────┘         └──────────────────────Page 1/4───┴─────────────────────┘          

为了在用户终端中充分利用 space,我想像上面的例子一样并排排列 table。我研究了将这些 table 嵌套在父 table 中的可能性,但我不确定这是否可能。

关键是使用 Symfony 的 BufferedOutput class。这是 Symfony 控制台命令形式的示例:

<?php

namespace Wps\Console\Commands\Update;

use Robo\Common\OutputAwareTrait;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Helper\TableStyle;
use Symfony\Component\Console\Output\BufferedOutput;
use Wps\Console\RawBufferedOutput\RawBufferedOutput;

class NestedTablesCommand extends \Wps\Console\Commands\WpsCommandBase {

  use OutputAwareTrait;

  protected $outputBuffer;

  /**
   * @command nested
   */
  public function execute() {
    $this->setOutputBuffer();
    $this->parentTable();
  }

  protected function setOutputBuffer() {
    $this->outputBuffer = new RawBufferedOutput();
  }

  protected function parentTable() {
    $table = new Table($this->output);

    $tableStyle = $this->parentTable->getStyleDefinition('box');
    $tableStyle
      ->setPadType(STR_PAD_BOTH);
    $table->setStyle($tableStyle);

    $this->topLeftChildTable();
    $topRightChild = $this->outputBuffer->fetch();
    $this->bottomRightChildTable();
    $bottomRightChild = $this->outputBuffer->fetch();

    $table->setHeaderTitle('Parent Table');
    $table->setheaders(['Left', 'Right']);
    $rows = [
      [$topRightChild, 'r1'],
      ['l2', $bottomRightChild],
    ];
    $table->setRows($rows);
    $table->render();
  }

  protected function topLeftChildTable() {
    $table = new Table($this->outputBuffer);
    $table->setStyle('box');
    $tableStyle = new TableStyle();
    $tableStyle
      ->setPadType(STR_PAD_BOTH);
    $table->setHeaderTitle('TL Child');
    $table->setheaders(['Left', 'Right']);
    $rows = [
      ['L1', 'R1'],
      ['L2', 'R2'],
    ];
    $table->setRows($rows);
    $table->render();
  }

  protected function bottomRightChildTable() {
    $table = new Table($this->outputBuffer);
    $table->setStyle('box');

    $tableStyle = new TableStyle();
    $tableStyle
      ->setPadType(STR_PAD_BOTH);
    $table->setHeaderTitle('BR Child');
    $table->setheaders(['Left', 'Right']);
    $rows = [
      ['L1', 'R1'],
      ['L2', 'R2'],
    ];
    $table->setRows($rows);
    $table->render();
  }

}

为了在将表呈现到缓冲区时保留 ANSI 代码装饰,我们需要扩展 BufferedOutput:

<?php

namespace Wps\Console\RawBufferedOutput;

use Symfony\Component\Console\Output\Output;

class RawBufferedOutput extends \Symfony\Component\Console\Output\BufferedOutput {

  public function write($messages, $newline = FALSE, $options = self::OUTPUT_NORMAL) {
    parent::write($messages, $newline, self::OUTPUT_RAW);
  }

  public function writeln($messages, $options = self::OUTPUT_NORMAL) {
    parent::writeln($messages, $options, self::OUTPUT_RAW);
  }

}

这呈现: