PhpSpreadsheetでデータベース定義書を出力

データベースツールによってはテーブル定義書をexcel出力できる機能があるので、それを真似してみました。

私が勉強しながら、作業したしたことの備忘録的な内容ですので、書いている内容がいろいろダメな部分もあると思いますが、
コピペしただけで、とりあえず簡単なexcel出力ができるサンプルにはなるように書きました。
※excel出力の勉強で書いたので、テーブルの情報はそんなに細かく出力しません。
よろしくお願いいたします。

# バージョン
- php 7.1
- MySQL 5.7
- Windows 7

# インストール
```
composer require phpoffice/phpspreadsheet
```

# テーブル作成
動画を保存するようなテーブル

```mysql
CREATE TABLE IF NOT EXISTS videotest (
    id        INT(11) unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'ID',
    videoname VARCHAR(100) NOT NULL COMMENT '動画名',
    path      VARCHAR(100) UNIQUE NOT NULL COMMENT '保存パス',
    created   DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '作成日',
    modified  DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '変更日',
    del_flg   TINYINT(1) NOT NULL DEFAULT 0 COMMENT '削除フラグ'
) DEFAULT CHARSET=utf8mb4;
```

# excel出力

```php:index.php
<?php

require 'vendor/autoload.php';

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

$schema = 'sample';
$table = 'videotest';

try{
    $pdo = new PDO(
        "mysql:dbname={$schema};host=127.0.0.1;charset=utf8mb4;",
        'root',
        '',
        [
            PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE=>PDO::FETCH_NUM,
        ]
    );

    $spreadsheet = new Spreadsheet();
    $sheet = $spreadsheet->getActiveSheet();
    
    $sheet
        ->setCellValue('A1','テーブル情報')
        ->getStyle('A1')->getFont()->setBold(true)->setItalic(true);

    $sheet
        ->fromArray(
            [
                ['Schema','Table'],
                [$schema,$table], 
            ],
            NULL,
            'B2',
            true
        )
        ->getStyle('B2:C2')
        ->applyFromArray([
            'font'=>[
                'bold'=>true,
                'color'=>[
                    'argb'=>'FFFFFFFF'
                ],
            ],
            'alignment'=>[
                'horizontal'=>\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER
            ],
            'fill'=>[
                'fillType'=>\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
                'color'=>[
                    'argb'=>'FF008B00'
                ],
            ]
        ]);

    $sheet->getStyle('B2:C3')->getBorders()->getOutline()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_MEDIUM);
    $sheet->getStyle('B2:C3')->getBorders()->getHorizontal()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN);
    $sheet->getStyle('B2:C3')->getBorders()->getVertical()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_DOTTED);
        
    $sheet
        ->setCellValue('A5', 'カラム情報')
        ->getStyle('A5')->getFont()->setBold(true)->setItalic(true);

    $sheet
        ->fromArray(
            [
                ['No','COLUMN','COLUMN_TYPE','COLLATION_NAME','Null','COLUMN_DEFAULT','COLUMN_KEY','EXTRA','COMMENT']
            ],
            NULL,
            'B6',
            true
        )
        ->getStyle('B6:J6')
        ->applyFromArray([
            'font'=>[
                'bold'=>true,
                'color'=>[
                    'argb'=>'FFFFFFFF'
                ],
            ],
            'alignment'=>[
                'horizontal'=>\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER
            ],
            'borders'=>[
                'outline'=>[
                    'borderStyle'=>\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN
                ],
                'vertical'=>[
                    'borderStyle'=>\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_DOTTED
                ]
            ],
            'fill'=>[
                'fillType'=>\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
                'color'=>[
                    'argb'=>'FF00008B'
                ],
            ]
        ]);

    $sheet
        ->fromArray(
           $res=$pdo->query(
                "SELECT ORDINAL_POSITION
                       ,COLUMN_NAME
                       ,COLUMN_TYPE
                       ,COLLATION_NAME
                       ,IS_NULLABLE
                       ,COLUMN_DEFAULT
                       ,COLUMN_KEY
                       ,EXTRA
                       ,COLUMN_COMMENT
                 FROM information_schema.columns
                 WHERE table_schema = '{$schema}'
                 AND table_name = '{$table}'
                 ORDER BY ordinal_position"
            )
            ->fetchAll(),
            NULL,
            'B7',
            true
        )
        ->getStyle('B7:J'.(6+count($res)))
        ->applyFromArray([
            'borders'=>[
                'outline'=>[
                    'borderStyle'=>\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN
                ],
                'horizontal'=>[
                    'borderStyle'=>\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN
                ],
                'vertical'=>[
                    'borderStyle'=>\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_DOTTED
                ],
            ],
        ]);

    $sheet->getColumnDimension('A')->setWidth(3);
    $sheet->getColumnDimension('B')->setAutoSize(true);
    $sheet->getColumnDimension('C')->setAutoSize(true);
    $sheet->getColumnDimension('D')->setAutoSize(true);
    $sheet->getColumnDimension('E')->setAutoSize(true);
    $sheet->getColumnDimension('F')->setAutoSize(true);
    $sheet->getColumnDimension('G')->setAutoSize(true);
    $sheet->getColumnDimension('H')->setAutoSize(true);
    $sheet->getColumnDimension('I')->setAutoSize(true);
    $sheet->getColumnDimension('J')->setWidth(50);
    
    $writer = new Xlsx($spreadsheet);
    $writer->save('test_'.(new DateTime('Asia/Tokyo'))->format('YmdHis').'.xlsx');

    header('Content-Type:text/plain;charset=Shift_JIS');
    echo `dir /b`;
    
}catch(PDOException $e){
    exit($e->getMessage());
}
```

# 実行

出力されたexcelファイルがあることを確認。
![実行後フォルダ.png](https://qiita-image-store.s3.amazonaws.com/0/142910/ee54c486-afbb-349e-26ff-3bca851094a7.png)

出力されたファイルを確認。
![test_20180114172527.xlsx.png](https://qiita-image-store.s3.amazonaws.com/0/142910/dda7eef6-233e-5429-8480-939af293a984.png)

最後まで見ていただいて、ありがとうございました。m(_ _)m