Github IssuesをExcelに出力する

# はじめに

Quadでは開発フェーズでのタスク管理や運用フェーズでの障害管理にGithub Issueを使っています。
最初は何が良いのかよくわからないけど、一度Issueに慣れてしまうと他の方法でやりたくなくなるぐらいの魅力を持ったサービスですね。

ただ受託案件の場合、クライアントとの課題一覧のやりとりにIssueを見せるわけにもいかず、課題管理表をExcelで作ることが多いです。2重管理だし手間かかりますよね。
今回はIssueをExcelに書き出してみました。

# GitHubからIssuesを取得する

前回GitHubからAPIを利用してデータを取得したので、これを利用します。
http://qiita.com/segawa/items/8c97e626326b68d5750a

Issue APIの詳細は下記を参照してください。
https://developer.github.com/v3/issues/

GitHub APIでIssueのデータを取得して、配列で返しています。

```php:GithubIssue.php
<?php
class GithubIssue
{
    const END_POINT = 'https://api.github.com/repos/%1$s/%2$s/issues?filter=all&state=all&sort=created&direction=asc';
    private $owner, $repo, $user, $token;
    private $issues;

    /**
     * コンストラクタ
     */
	public function __construct($owner, $repo, $user, $token)
    {
        $this->owner    = $owner;
        $this->repo     = $repo;
        $this->user     = $user;
        $this->token    = $token;
    }

    /**
     * メイン処理
     */
    public function process()
    {
        $this->getDataFromGithub();
        $res = $this->formatIssueData();

        return $res;
    }

    /**
     * GitHub APIでデータをIssueデータを取得
     */
    private function getDataFromGithub()
    {
        $params = [
            'filter'    => 'all',
            'state'     => 'all',
            'sort'      => 'created',
            'direction' => 'asc'
        ];
        $query = http_build_query($params);
        $endpoint = sprintf(self::END_POINT, $this->owner, $this->repo) . $query;

        $ch = curl_init($endpoint);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
        curl_setopt($ch, CURLOPT_HTTPGET, true);
        curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
        curl_setopt($ch, CURLOPT_USERPWD, "{$this->user}:{$this->token}");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $res = curl_exec($ch);
        curl_close($ch);
        
        $this->issues = json_decode($res);
    }

    /**
     * Issueデータを整形して返す
     */
    private function formatIssueData()
    {
        $res = [];
        $issues = $this->issues;
        foreach ($issues as $issue) {
            $temp = [];
            $temp['No']         = $issue->number;
            $temp['Title']      = $issue->title;
            $temp['Labels']     = $issue->labels[0]->name; // ラベルが複数の場合に非対応
            $temp['State']      = $issue->state;
            $temp['Assignee']   = $issue->assignee->login;
            $temp['Milestone']  = $issue->milestone->title;
            $temp['Created']    = $issue->created_at;
            $temp['Updated']    = $issue->updated_at;
            $res[] = $temp;                        
        }
        return $res;
    }
}
```

# Excelに出力する

PHPExcelを使用してExcelにデータを出力します。
エラー処理やExcelの見栄え調整はやっていません、、

PHPExcelは下記からダウンロードできます。
https://phpexcel.codeplex.com/

```php:ExcelCreator.php
<?php
require_once 'PHPExcel_1.8.0/Classes/PHPExcel.php';
require_once 'PHPExcel_1.8.0/Classes/PHPExcel/IOFactory.php';

class ExcelCreator
{
    private $path, $data;
    
    // ヘッダ
    private static $header = ['No', 'タイトル', '起票日', '更新日', '担当者', 'ステータス', 'ラベル', 'リリース予定'];

    /**
     * コンストラクタ
     */
    public function __construct($data)
    {
        $this->path = dirname(__FILE__) . '/issues.xls';
        $this->data = $data;
    }

    /**
     * Excelにデータを出力し、ダウンロードする
     */
    public function generate()
    {
        $excel = new PHPExcel();
        $excel->setActiveSheetIndex(0);
        $sheet = $excel->getActiveSheet();

        // ヘッダ設定
        foreach (self::$header as $key => $val) {
            $sheet->setCellValueByColumnAndRow($key, 1, $val);
        }

        // データ設定
        foreach ($this->data as $key => $issue) {
            $row = $key + 2;
            $sheet->setCellValueByColumnAndRow(0, $row, $issue['No']);
            $sheet->setCellValueByColumnAndRow(1, $row, $issue['Title']);
            $sheet->setCellValueByColumnAndRow(2, $row, $issue['Created']);
            $sheet->setCellValueByColumnAndRow(3, $row, $issue['Updated']);
            $sheet->setCellValueByColumnAndRow(4, $row, $issue['Assignee']);
            $sheet->setCellValueByColumnAndRow(5, $row, $issue['State']);
            $sheet->setCellValueByColumnAndRow(6, $row, $issue['Labels']);
            $sheet->setCellValueByColumnAndRow(7, $row, $issue['Milestone']);
        }

        $writer = PHPExcel_IOFactory::createWriter($excel, 'Excel2007');
        $writer->save($this->path);

        // 出力
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment; filename=' . basename($this->path) . ';');
        header('Content-Transfer-Encoding: binary');
        header('Content-Length: ' . filesize($this->path));
        readfile($this->path);
        unlink($this->path);
        exit();
    }
}
```

# 出力してみる

上記の2ファイルと下記のプログラムをWEBサーバに置いて、出力してみます。

http://localhost/excel_export.php

```php:excel_export.php
<?php
require_once 'GithubIssue.php';
require_once 'ExcelCreator.php';

$issue = new GithubIssue('kung-fu', 'labels-sample', 'kung-fu', 'トークンを入れます');
$data = $issue->process();

$ec = new ExcelCreator($data);
$ec->generate();
```

できたファイル
<img width="795" alt="スクリーンショット 2015-12-12 19.19.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/20940/ed7c8c20-ff6b-061f-4b95-5b55b0570060.png">

うーん、さすがにこのままでは使えないですね :sweat_smile: 
PHPExcelで書式設定することもできますが結構めんどくさそうなので、Excelのテンプレートを用意して、そこにデータを出力するようにすれば、見た目は良くなると思います。