[Console] Add non-auto column width functionality

This commit is contained in:
Arjan Keeman 2016-02-11 11:00:25 +01:00 committed by Fabien Potencier
parent 33c797ee05
commit 20c81b2bd6
3 changed files with 114 additions and 9 deletions

View File

@ -5,6 +5,7 @@ CHANGELOG
-----
* added truncate method to FormatterHelper
* added setColumnWidth(s) method to Table
2.8.3
-----

View File

@ -43,7 +43,7 @@ class Table
*
* @var array
*/
private $columnWidths = array();
private $effectiveColumnWidths = array();
/**
* Number of columns cache.
@ -67,6 +67,13 @@ class Table
*/
private $columnStyles = array();
/**
* User set column widths.
*
* @var array
*/
private $columnWidths = array();
private static $styles;
public function __construct(OutputInterface $output)
@ -186,6 +193,38 @@ class Table
return $this->getStyle();
}
/**
* Sets the minimum width of a column.
*
* @param int $columnIndex Column index
* @param int $width Minimum column width in characters
*
* @return Table
*/
public function setColumnWidth($columnIndex, $width)
{
$this->columnWidths[intval($columnIndex)] = intval($width);
return $this;
}
/**
* Sets the minimum width of all columns.
*
* @param array $widths
*
* @return Table
*/
public function setColumnWidths(array $widths)
{
$this->columnWidths = array();
foreach ($widths as $index => $width) {
$this->setColumnWidth($index, $width);
}
return $this;
}
public function setHeaders(array $headers)
{
$headers = array_values($headers);
@ -296,7 +335,7 @@ class Table
$markup = $this->style->getCrossingChar();
for ($column = 0; $column < $count; ++$column) {
$markup .= str_repeat($this->style->getHorizontalBorderChar(), $this->columnWidths[$column]).$this->style->getCrossingChar();
$markup .= str_repeat($this->style->getHorizontalBorderChar(), $this->effectiveColumnWidths[$column]).$this->style->getCrossingChar();
}
$this->output->writeln(sprintf($this->style->getBorderFormat(), $markup));
@ -342,11 +381,11 @@ class Table
private function renderCell(array $row, $column, $cellFormat)
{
$cell = isset($row[$column]) ? $row[$column] : '';
$width = $this->columnWidths[$column];
$width = $this->effectiveColumnWidths[$column];
if ($cell instanceof TableCell && $cell->getColspan() > 1) {
// add the width of the following columns(numbers of colspan).
foreach (range($column + 1, $column + $cell->getColspan() - 1) as $nextColumn) {
$width += $this->getColumnSeparatorWidth() + $this->columnWidths[$nextColumn];
$width += $this->getColumnSeparatorWidth() + $this->effectiveColumnWidths[$nextColumn];
}
}
@ -572,7 +611,7 @@ class Table
$lengths[] = $this->getCellWidth($row, $column);
}
$this->columnWidths[$column] = max($lengths) + strlen($this->style->getCellRowContentFormat()) - 2;
$this->effectiveColumnWidths[$column] = max($lengths) + strlen($this->style->getCellRowContentFormat()) - 2;
}
}
@ -596,6 +635,8 @@ class Table
*/
private function getCellWidth(array $row, $column)
{
$cellWidth = 0;
if (isset($row[$column])) {
$cell = $row[$column];
$cellWidth = Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
@ -603,11 +644,11 @@ class Table
// we assume that cell value will be across more than one column.
$cellWidth = $cellWidth / $cell->getColspan();
}
return $cellWidth;
}
return 0;
$columnWidth = isset($this->columnWidths[$column]) ? $this->columnWidths[$column] : 0;
return max($cellWidth, $columnWidth);
}
/**
@ -615,7 +656,7 @@ class Table
*/
private function cleanup()
{
$this->columnWidths = array();
$this->effectiveColumnWidths = array();
$this->numberOfColumns = null;
}

View File

@ -620,6 +620,69 @@ TABLE;
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | 139.25 |
+---------------+----------------------+-----------------+--------+
TABLE;
$this->assertEquals($expected, $this->getOutputContent($output));
}
public function testColumnWith()
{
$table = new Table($output = $this->getOutputStream());
$table
->setHeaders(array('ISBN', 'Title', 'Author', 'Price'))
->setRows(array(
array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri', '9.95'),
array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens', '139.25'),
))
->setColumnWidth(0, 15)
->setColumnWidth(3, 10);
$style = new TableStyle();
$style->setPadType(STR_PAD_LEFT);
$table->setColumnStyle(3, $style);
$table->render();
$expected =
<<<TABLE
+-----------------+----------------------+-----------------+------------+
| ISBN | Title | Author | Price |
+-----------------+----------------------+-----------------+------------+
| 99921-58-10-7 | Divine Comedy | Dante Alighieri | 9.95 |
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | 139.25 |
+-----------------+----------------------+-----------------+------------+
TABLE;
$this->assertEquals($expected, $this->getOutputContent($output));
}
public function testColumnWiths()
{
$table = new Table($output = $this->getOutputStream());
$table
->setHeaders(array('ISBN', 'Title', 'Author', 'Price'))
->setRows(array(
array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri', '9.95'),
array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens', '139.25'),
))
->setColumnWidths(array(15, 0, -1, 10));
$style = new TableStyle();
$style->setPadType(STR_PAD_LEFT);
$table->setColumnStyle(3, $style);
$table->render();
$expected =
<<<TABLE
+-----------------+----------------------+-----------------+------------+
| ISBN | Title | Author | Price |
+-----------------+----------------------+-----------------+------------+
| 99921-58-10-7 | Divine Comedy | Dante Alighieri | 9.95 |
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | 139.25 |
+-----------------+----------------------+-----------------+------------+
TABLE;
$this->assertEquals($expected, $this->getOutputContent($output));