123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- <?php
- // +----------------------------------------------------------------------
- // | ThinkPHP [ WE CAN DO IT JUST THINK ]
- // +----------------------------------------------------------------------
- // | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
- // +----------------------------------------------------------------------
- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
- // +----------------------------------------------------------------------
- // | Author: yunwuxin <448901948@qq.com>
- // +----------------------------------------------------------------------
-
- namespace think\console;
-
- class Table
- {
- const ALIGN_LEFT = 1;
- const ALIGN_RIGHT = 0;
- const ALIGN_CENTER = 2;
-
- /**
- * 头信息数据
- * @var array
- */
- protected $header = [];
-
- /**
- * 头部对齐方式 默认1 ALGIN_LEFT 0 ALIGN_RIGHT 2 ALIGN_CENTER
- * @var int
- */
- protected $headerAlign = 1;
-
- /**
- * 表格数据(二维数组)
- * @var array
- */
- protected $rows = [];
-
- /**
- * 单元格对齐方式 默认1 ALGIN_LEFT 0 ALIGN_RIGHT 2 ALIGN_CENTER
- * @var int
- */
- protected $cellAlign = 1;
-
- /**
- * 单元格宽度信息
- * @var array
- */
- protected $colWidth = [];
-
- /**
- * 表格输出样式
- * @var string
- */
- protected $style = 'default';
-
- /**
- * 表格样式定义
- * @var array
- */
- protected $format = [
- 'compact' => [],
- 'default' => [
- 'top' => ['+', '-', '+', '+'],
- 'cell' => ['|', ' ', '|', '|'],
- 'middle' => ['+', '-', '+', '+'],
- 'bottom' => ['+', '-', '+', '+'],
- 'cross-top' => ['+', '-', '-', '+'],
- 'cross-bottom' => ['+', '-', '-', '+'],
- ],
- 'markdown' => [
- 'top' => [' ', ' ', ' ', ' '],
- 'cell' => ['|', ' ', '|', '|'],
- 'middle' => ['|', '-', '|', '|'],
- 'bottom' => [' ', ' ', ' ', ' '],
- 'cross-top' => ['|', ' ', ' ', '|'],
- 'cross-bottom' => ['|', ' ', ' ', '|'],
- ],
- 'borderless' => [
- 'top' => ['=', '=', ' ', '='],
- 'cell' => [' ', ' ', ' ', ' '],
- 'middle' => ['=', '=', ' ', '='],
- 'bottom' => ['=', '=', ' ', '='],
- 'cross-top' => ['=', '=', ' ', '='],
- 'cross-bottom' => ['=', '=', ' ', '='],
- ],
- 'box' => [
- 'top' => ['┌', '─', '┬', '┐'],
- 'cell' => ['│', ' ', '│', '│'],
- 'middle' => ['├', '─', '┼', '┤'],
- 'bottom' => ['└', '─', '┴', '┘'],
- 'cross-top' => ['├', '─', '┴', '┤'],
- 'cross-bottom' => ['├', '─', '┬', '┤'],
- ],
- 'box-double' => [
- 'top' => ['╔', '═', '╤', '╗'],
- 'cell' => ['║', ' ', '│', '║'],
- 'middle' => ['╠', '─', '╪', '╣'],
- 'bottom' => ['╚', '═', '╧', '╝'],
- 'cross-top' => ['╠', '═', '╧', '╣'],
- 'cross-bottom' => ['╠', '═', '╤', '╣'],
- ],
- ];
-
- /**
- * 设置表格头信息 以及对齐方式
- * @access public
- * @param array $header 要输出的Header信息
- * @param int $align 对齐方式 默认1 ALGIN_LEFT 0 ALIGN_RIGHT 2 ALIGN_CENTER
- * @return void
- */
- public function setHeader(array $header, $align = self::ALIGN_LEFT)
- {
- $this->header = $header;
- $this->headerAlign = $align;
-
- $this->checkColWidth($header);
- }
-
- /**
- * 设置输出表格数据 及对齐方式
- * @access public
- * @param array $rows 要输出的表格数据(二维数组)
- * @param int $align 对齐方式 默认1 ALGIN_LEFT 0 ALIGN_RIGHT 2 ALIGN_CENTER
- * @return void
- */
- public function setRows(array $rows, $align = self::ALIGN_LEFT)
- {
- $this->rows = $rows;
- $this->cellAlign = $align;
-
- foreach ($rows as $row) {
- $this->checkColWidth($row);
- }
- }
-
- /**
- * 检查列数据的显示宽度
- * @access public
- * @param mixed $row 行数据
- * @return void
- */
- protected function checkColWidth($row)
- {
- if (is_array($row)) {
- foreach ($row as $key => $cell) {
- if (!isset($this->colWidth[$key]) || strlen($cell) > $this->colWidth[$key]) {
- $this->colWidth[$key] = strlen($cell);
- }
- }
- }
- }
-
- /**
- * 增加一行表格数据
- * @access public
- * @param mixed $row 行数据
- * @param bool $first 是否在开头插入
- * @return void
- */
- public function addRow($row, $first = false)
- {
- if ($first) {
- array_unshift($this->rows, $row);
- } else {
- $this->rows[] = $row;
- }
-
- $this->checkColWidth($row);
- }
-
- /**
- * 设置输出表格的样式
- * @access public
- * @param string $style 样式名
- * @return void
- */
- public function setStyle($style)
- {
- $this->style = isset($this->format[$style]) ? $style : 'default';
- }
-
- /**
- * 输出分隔行
- * @access public
- * @param string $pos 位置
- * @return string
- */
- protected function renderSeparator($pos)
- {
- $style = $this->getStyle($pos);
- $array = [];
-
- foreach ($this->colWidth as $width) {
- $array[] = str_repeat($style[1], $width + 2);
- }
-
- return $style[0] . implode($style[2], $array) . $style[3] . PHP_EOL;
- }
-
- /**
- * 输出表格头部
- * @access public
- * @return string
- */
- protected function renderHeader()
- {
- $style = $this->getStyle('cell');
- $content = $this->renderSeparator('top');
-
- foreach ($this->header as $key => $header) {
- $array[] = ' ' . str_pad($header, $this->colWidth[$key], $style[1], $this->headerAlign);
- }
-
- if (!empty($array)) {
- $content .= $style[0] . implode(' ' . $style[2], $array) . ' ' . $style[3] . PHP_EOL;
-
- if ($this->rows) {
- $content .= $this->renderSeparator('middle');
- }
- }
-
- return $content;
- }
-
- protected function getStyle($style)
- {
- if ($this->format[$this->style]) {
- $style = $this->format[$this->style][$style];
- } else {
- $style = [' ', ' ', ' ', ' '];
- }
-
- return $style;
- }
-
- /**
- * 输出表格
- * @access public
- * @param array $dataList 表格数据
- * @return string
- */
- public function render($dataList = [])
- {
- if ($dataList) {
- $this->setRows($dataList);
- }
-
- // 输出头部
- $content = $this->renderHeader();
- $style = $this->getStyle('cell');
-
- if ($this->rows) {
- foreach ($this->rows as $row) {
- if (is_string($row) && '-' === $row) {
- $content .= $this->renderSeparator('middle');
- } elseif (is_scalar($row)) {
- $content .= $this->renderSeparator('cross-top');
- $array = str_pad($row, 3 * (count($this->colWidth) - 1) + array_reduce($this->colWidth, function ($a, $b) {
- return $a + $b;
- }));
-
- $content .= $style[0] . ' ' . $array . ' ' . $style[3] . PHP_EOL;
- $content .= $this->renderSeparator('cross-bottom');
- } else {
- $array = [];
-
- foreach ($row as $key => $val) {
- $array[] = ' ' . str_pad($val, $this->colWidth[$key], ' ', $this->cellAlign);
- }
-
- $content .= $style[0] . implode(' ' . $style[2], $array) . ' ' . $style[3] . PHP_EOL;
-
- }
- }
- }
-
- $content .= $this->renderSeparator('bottom');
-
- return $content;
- }
- }
|