| 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;    }}
 |