Skip to content

Commit 2d1e5ce

Browse files
Arjan Keemanfabpot
authored andcommitted
[Console] Add non-auto column width functionality
1 parent a76821c commit 2d1e5ce

File tree

3 files changed

+114
-9
lines changed

3 files changed

+114
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
-----
66

77
* added truncate method to FormatterHelper
8+
* added setColumnWidth(s) method to Table
89

910
2.8.3
1011
-----

Helper/Table.php

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class Table
4343
*
4444
* @var array
4545
*/
46-
private $columnWidths = array();
46+
private $effectiveColumnWidths = array();
4747

4848
/**
4949
* Number of columns cache.
@@ -67,6 +67,13 @@ class Table
6767
*/
6868
private $columnStyles = array();
6969

70+
/**
71+
* User set column widths.
72+
*
73+
* @var array
74+
*/
75+
private $columnWidths = array();
76+
7077
private static $styles;
7178

7279
public function __construct(OutputInterface $output)
@@ -186,6 +193,38 @@ public function getColumnStyle($columnIndex)
186193
return $this->getStyle();
187194
}
188195

196+
/**
197+
* Sets the minimum width of a column.
198+
*
199+
* @param int $columnIndex Column index
200+
* @param int $width Minimum column width in characters
201+
*
202+
* @return Table
203+
*/
204+
public function setColumnWidth($columnIndex, $width)
205+
{
206+
$this->columnWidths[intval($columnIndex)] = intval($width);
207+
208+
return $this;
209+
}
210+
211+
/**
212+
* Sets the minimum width of all columns.
213+
*
214+
* @param array $widths
215+
*
216+
* @return Table
217+
*/
218+
public function setColumnWidths(array $widths)
219+
{
220+
$this->columnWidths = array();
221+
foreach ($widths as $index => $width) {
222+
$this->setColumnWidth($index, $width);
223+
}
224+
225+
return $this;
226+
}
227+
189228
public function setHeaders(array $headers)
190229
{
191230
$headers = array_values($headers);
@@ -296,7 +335,7 @@ private function renderRowSeparator()
296335

297336
$markup = $this->style->getCrossingChar();
298337
for ($column = 0; $column < $count; ++$column) {
299-
$markup .= str_repeat($this->style->getHorizontalBorderChar(), $this->columnWidths[$column]).$this->style->getCrossingChar();
338+
$markup .= str_repeat($this->style->getHorizontalBorderChar(), $this->effectiveColumnWidths[$column]).$this->style->getCrossingChar();
300339
}
301340

302341
$this->output->writeln(sprintf($this->style->getBorderFormat(), $markup));
@@ -342,11 +381,11 @@ private function renderRow(array $row, $cellFormat)
342381
private function renderCell(array $row, $column, $cellFormat)
343382
{
344383
$cell = isset($row[$column]) ? $row[$column] : '';
345-
$width = $this->columnWidths[$column];
384+
$width = $this->effectiveColumnWidths[$column];
346385
if ($cell instanceof TableCell && $cell->getColspan() > 1) {
347386
// add the width of the following columns(numbers of colspan).
348387
foreach (range($column + 1, $column + $cell->getColspan() - 1) as $nextColumn) {
349-
$width += $this->getColumnSeparatorWidth() + $this->columnWidths[$nextColumn];
388+
$width += $this->getColumnSeparatorWidth() + $this->effectiveColumnWidths[$nextColumn];
350389
}
351390
}
352391

@@ -572,7 +611,7 @@ private function calculateColumnsWidth($rows)
572611
$lengths[] = $this->getCellWidth($row, $column);
573612
}
574613

575-
$this->columnWidths[$column] = max($lengths) + strlen($this->style->getCellRowContentFormat()) - 2;
614+
$this->effectiveColumnWidths[$column] = max($lengths) + strlen($this->style->getCellRowContentFormat()) - 2;
576615
}
577616
}
578617

@@ -596,26 +635,28 @@ private function getColumnSeparatorWidth()
596635
*/
597636
private function getCellWidth(array $row, $column)
598637
{
638+
$cellWidth = 0;
639+
599640
if (isset($row[$column])) {
600641
$cell = $row[$column];
601642
$cellWidth = Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
602643
if ($cell instanceof TableCell && $cell->getColspan() > 1) {
603644
// we assume that cell value will be across more than one column.
604645
$cellWidth = $cellWidth / $cell->getColspan();
605646
}
606-
607-
return $cellWidth;
608647
}
609648

610-
return 0;
649+
$columnWidth = isset($this->columnWidths[$column]) ? $this->columnWidths[$column] : 0;
650+
651+
return max($cellWidth, $columnWidth);
611652
}
612653

613654
/**
614655
* Called after rendering to cleanup cache data.
615656
*/
616657
private function cleanup()
617658
{
618-
$this->columnWidths = array();
659+
$this->effectiveColumnWidths = array();
619660
$this->numberOfColumns = null;
620661
}
621662

Tests/Helper/TableTest.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,69 @@ public function testColumnStyle()
620620
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | 139.25 |
621621
+---------------+----------------------+-----------------+--------+
622622
623+
TABLE;
624+
625+
$this->assertEquals($expected, $this->getOutputContent($output));
626+
}
627+
628+
public function testColumnWith()
629+
{
630+
$table = new Table($output = $this->getOutputStream());
631+
$table
632+
->setHeaders(array('ISBN', 'Title', 'Author', 'Price'))
633+
->setRows(array(
634+
array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri', '9.95'),
635+
array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens', '139.25'),
636+
))
637+
->setColumnWidth(0, 15)
638+
->setColumnWidth(3, 10);
639+
640+
$style = new TableStyle();
641+
$style->setPadType(STR_PAD_LEFT);
642+
$table->setColumnStyle(3, $style);
643+
644+
$table->render();
645+
646+
$expected =
647+
<<<TABLE
648+
+-----------------+----------------------+-----------------+------------+
649+
| ISBN | Title | Author | Price |
650+
+-----------------+----------------------+-----------------+------------+
651+
| 99921-58-10-7 | Divine Comedy | Dante Alighieri | 9.95 |
652+
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | 139.25 |
653+
+-----------------+----------------------+-----------------+------------+
654+
655+
TABLE;
656+
657+
$this->assertEquals($expected, $this->getOutputContent($output));
658+
}
659+
660+
public function testColumnWiths()
661+
{
662+
$table = new Table($output = $this->getOutputStream());
663+
$table
664+
->setHeaders(array('ISBN', 'Title', 'Author', 'Price'))
665+
->setRows(array(
666+
array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri', '9.95'),
667+
array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens', '139.25'),
668+
))
669+
->setColumnWidths(array(15, 0, -1, 10));
670+
671+
$style = new TableStyle();
672+
$style->setPadType(STR_PAD_LEFT);
673+
$table->setColumnStyle(3, $style);
674+
675+
$table->render();
676+
677+
$expected =
678+
<<<TABLE
679+
+-----------------+----------------------+-----------------+------------+
680+
| ISBN | Title | Author | Price |
681+
+-----------------+----------------------+-----------------+------------+
682+
| 99921-58-10-7 | Divine Comedy | Dante Alighieri | 9.95 |
683+
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | 139.25 |
684+
+-----------------+----------------------+-----------------+------------+
685+
623686
TABLE;
624687

625688
$this->assertEquals($expected, $this->getOutputContent($output));

0 commit comments

Comments
 (0)