TextGrid.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. <?php
  2. namespace PhpOffice\PhpSpreadsheet\Helper;
  3. class TextGrid
  4. {
  5. /**
  6. * @var bool
  7. */
  8. private $isCli = true;
  9. /**
  10. * @var array
  11. */
  12. protected $matrix;
  13. /**
  14. * @var array
  15. */
  16. protected $rows;
  17. /**
  18. * @var array
  19. */
  20. protected $columns;
  21. /**
  22. * @var string
  23. */
  24. private $gridDisplay;
  25. public function __construct(array $matrix, bool $isCli = true)
  26. {
  27. $this->rows = array_keys($matrix);
  28. $this->columns = array_keys($matrix[$this->rows[0]]);
  29. $matrix = array_values($matrix);
  30. array_walk(
  31. $matrix,
  32. function (&$row): void {
  33. $row = array_values($row);
  34. }
  35. );
  36. $this->matrix = $matrix;
  37. $this->isCli = $isCli;
  38. }
  39. public function render(): string
  40. {
  41. $this->gridDisplay = $this->isCli ? '' : '<pre>';
  42. $maxRow = max($this->rows);
  43. $maxRowLength = mb_strlen((string) $maxRow) + 1;
  44. $columnWidths = $this->getColumnWidths();
  45. $this->renderColumnHeader($maxRowLength, $columnWidths);
  46. $this->renderRows($maxRowLength, $columnWidths);
  47. $this->renderFooter($maxRowLength, $columnWidths);
  48. $this->gridDisplay .= $this->isCli ? '' : '</pre>';
  49. return $this->gridDisplay;
  50. }
  51. private function renderRows(int $maxRowLength, array $columnWidths): void
  52. {
  53. foreach ($this->matrix as $row => $rowData) {
  54. $this->gridDisplay .= '|' . str_pad((string) $this->rows[$row], $maxRowLength, ' ', STR_PAD_LEFT) . ' ';
  55. $this->renderCells($rowData, $columnWidths);
  56. $this->gridDisplay .= '|' . PHP_EOL;
  57. }
  58. }
  59. private function renderCells(array $rowData, array $columnWidths): void
  60. {
  61. foreach ($rowData as $column => $cell) {
  62. $displayCell = ($this->isCli) ? (string) $cell : htmlentities((string) $cell);
  63. $this->gridDisplay .= '| ';
  64. $this->gridDisplay .= $displayCell . str_repeat(' ', $columnWidths[$column] - mb_strlen($cell ?? '') + 1);
  65. }
  66. }
  67. private function renderColumnHeader(int $maxRowLength, array $columnWidths): void
  68. {
  69. $this->gridDisplay .= str_repeat(' ', $maxRowLength + 2);
  70. foreach ($this->columns as $column => $reference) {
  71. $this->gridDisplay .= '+-' . str_repeat('-', $columnWidths[$column] + 1);
  72. }
  73. $this->gridDisplay .= '+' . PHP_EOL;
  74. $this->gridDisplay .= str_repeat(' ', $maxRowLength + 2);
  75. foreach ($this->columns as $column => $reference) {
  76. $this->gridDisplay .= '| ' . str_pad((string) $reference, $columnWidths[$column] + 1, ' ');
  77. }
  78. $this->gridDisplay .= '|' . PHP_EOL;
  79. $this->renderFooter($maxRowLength, $columnWidths);
  80. }
  81. private function renderFooter(int $maxRowLength, array $columnWidths): void
  82. {
  83. $this->gridDisplay .= '+' . str_repeat('-', $maxRowLength + 1);
  84. foreach ($this->columns as $column => $reference) {
  85. $this->gridDisplay .= '+-';
  86. $this->gridDisplay .= str_pad((string) '', $columnWidths[$column] + 1, '-');
  87. }
  88. $this->gridDisplay .= '+' . PHP_EOL;
  89. }
  90. private function getColumnWidths(): array
  91. {
  92. $columnCount = count($this->matrix, COUNT_RECURSIVE) / count($this->matrix);
  93. $columnWidths = [];
  94. for ($column = 0; $column < $columnCount; ++$column) {
  95. $columnWidths[] = $this->getColumnWidth(array_column($this->matrix, $column));
  96. }
  97. return $columnWidths;
  98. }
  99. private function getColumnWidth(array $columnData): int
  100. {
  101. $columnWidth = 0;
  102. $columnData = array_values($columnData);
  103. foreach ($columnData as $columnValue) {
  104. if (is_string($columnValue)) {
  105. $columnWidth = max($columnWidth, mb_strlen($columnValue));
  106. } elseif (is_bool($columnValue)) {
  107. $columnWidth = max($columnWidth, mb_strlen($columnValue ? 'TRUE' : 'FALSE'));
  108. }
  109. $columnWidth = max($columnWidth, mb_strlen((string) $columnWidth));
  110. }
  111. return $columnWidth;
  112. }
  113. }