WindowsでPHPから入力したデータをExcelに出力する

## PHPからデータをExcelに出力する手順
### composerの入手

**`composer`は`PHP`のパッケージ管理ツール**

もっと簡単に言えば、何かパッケージをインストールするときに、それを動かすのに必要な他のパッケージも一緒にインストールしてくれるというもの。

`PHP`から`Excel`にデータを出力するには、`PhpSpreadsheet`というパッケージが必要になる。
それを入手するためにまず、この`composer`をPCで使えるようにする。

[Introduction - Composer](https://getcomposer.org/doc/00-intro.md#installation-windows) から `Composer-Setup.exe`をダウンロードして、実行。
インストールの詳しい手順は[Composerインストール手順(Windows)](https://qiita.com/mikoski01/items/266469535e860312145d) を参考に。
インストール完了後、コマンドプロントで`composer`を実行し、以下のような表記が出たら完了。

```
>composer
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 1.10.6 2020-05-06 10:28:10
```

### パッケージのインストール

作業するディレクトリを作成し、そこに移動。
そして、コマンドプロントで以下のコマンドを実行。
このコマンドを実行することで、`PHP`のデータを`Excel`に出力できるパッケージがインストールされる。

```
composer require phpoffice/phpspreadsheet
```

また、`vender`というディレクトリ、`composer.json`,`composer.lock`というファイルも作成されるため、どのような記述がされているか確認しておく。
それぞれの構成や`composer`の使い方に関しては以下の記事を参照。
[composerとは](https://qiita.com/atwata/items/d6f1cf95ce96ebe58010)

### PHPファイルの作成
続いて、`PHP`ファイルの作成に移る。
`Excel`にデータを出力するといっても色々な形があるが、今回はセルにいくつかの値を埋め込んだ`Excel`ファイルを作成する。
[PHPExcelでエクセル出力入門](https://qiita.com/suin/items/7a8d0979b7675d6fd05b)を参考に`PHP`ファイルを作成した。
上記の記事は`phpExcel`という少し前のパッケージを使用していたため、[PhpSpreadsheetの使い方](https://qiita.com/sudnonk12/items/a0d58cc0f6ff1c6e2765)も参考に、`phpSpreadsheet`でのコード記入を行った。

```ExcelOutput.php
<?php
date_default_timezone_set("Asia/Tokyo");
require __DIR__ . "/vendor/autoload.php";

// Excelの読み込み
$spreadsheet = new PhpOffice\PhpSpreadsheet\Spreadsheet();
$sheet = $spreadsheet->getSheet(0);

// Excelに出力するデータの設定
$sheet->setCellValue("A1", "データ1");
$sheet->setCellValue("A2", "データ2");
$sheet->setCellValue("A3", "データ3");

$sheet->setCellValue("B4", "データ4");
$sheet->setCellValue("B5", "データ5");
$sheet->setCellValue("B6", "データ6");

// Excelに出力
$writer = new PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save("ExcelOutput.xlsx");
?>
```

その後、コマンドプロントで作業ディレクトリに移り、以下のコマンドを実行する。

```
>php ExcelOutput.php
```

エラーがなければ、作業ディレクトリに`ExcelOutput.xlsx`が作成されている。
その中身は以下のようになっている。

![screeenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218398/340bc99e-45a6-cc52-0b0e-1bab15a22848.png)

## テンプレートを読み込んで出力
もう少し踏み込んで、`PhpSpreadsheet`を使いならせるようにしていく。
既存の`Excel`を読み、その形式をコピーした新しい`Excel`ファイルを出力できるようにする。

### テンプレートのダウンロード
MicrosoftがExcelのテンプレートを配布しているので、そこから好きなテンプレートをダウンロードして、作業ディレクトリに置く。
自分は[業務計画表（下半期）](https://www.microsoft.com/ja-jp/office/pipc/template/result.aspx?id=10466)をダウンロードした。

ファイル名がローマ字表記なので、`php`ファイルで書く量を減らせるように名前を変えるのもアリ。
自分は`業務計画表.xltx`にした。

### テンプレートの読み込み
[PhpSpreadsheetに書き込む](https://qiita.com/mst_7colors/items/35cda620669c8e7fbe17)を参考に進めていく。

`IOFactry::load("テンプレートのファイル")`でテンプレートの`Excel`ファイルを読み込む。
`$sheet = $spreadsheet->getSheet(1);`で2枚目のシートの読み込みを設定。
シートの読み方は配列と同じように、**`0,1…`**と0から数えるので設定する数字を間違えないように注意。

```ExcelOutput.php
// テンプレートの読み込みとシートの読み込み
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load("業務計画表.xltx");
$sheet = $spreadsheet->getSheet(1);
```

あとは、出力部分は変わらないので、データを記入するセルを書き込みたい場所に変更するだけでOK。

出力するとこんな感じに。
![screeenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218398/dbdf2351-2934-baa8-42e6-1c6f0bf8fb21.png)


シート名を変えたい場合は以下のコードを出力部分に設定するだけでOK。

```ExcelOutput.php
$sheet->setTitle("シート名");
```

### シートの削除
`業務計画表.xltx`にはシートが2つあり、1枚目が「使い方」、2枚目がデータを記入する「下半期　業務計画表」となっている。
使用するテンプレートは2枚目だけなので1枚目を削除した状態で出力したい。
そのような場合は、以下のコードでシートを削除できる。
[PhpSpreadsheetでシートのコピーと削除｜teratail](https://teratail.com/questions/144042)を参考にさせてもらった。

```ExcelOutput.php
$sheetIndex = $spreadsheet->getIndex(
    $spreadsheet->getSheetByName("使い方")
    // 削除したいシート名を""に記入
);
$spreadsheet->removeSheetByIndex($sheetIndex);
```

処理としては、`""`で指定されたシート名のインデックスを取得し、それを用いて削除するという単純なもの。

ただ、テンプレートによってはシート間で連携している可能性もあり、片方のシートを削除してしまうと`Excel`ファイルとして使えなくなることもある。
削除する前にシート間での連携などがないか、あっても削除して大丈夫かを確認しておく。

### ExcelOutput.php

```ExcelOutput.php
<?php
// https://qiita.com/kaitaku/items/d7c7b91d2f995fad3fc8
date_default_timezone_set("Asia/Tokyo");
require __DIR__ . "/vendor/autoload.php";

$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load("業務計画表.xltx");
$sheet = $spreadsheet->getSheet(1);
$sheetIndex = $spreadsheet->getIndex(
    $spreadsheet->getSheetByName("使い方")
);
$spreadsheet->removeSheetByIndex($sheetIndex);

$sheet->setCellValue("B22", "データ1");
$sheet->setCellValue("E22", "データ2");
$sheet->setCellValue("G22", "データ3");

$sheet->setCellValue("I23", "データ4");
$sheet->setCellValue("K23", "データ5");
$sheet->setCellValue("M23", "データ6");

$sheet->setTitle("ExcelOutput");
$writer = new PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save("ExcelOutput.xlsx");
?>
```

## 参考資料
- [Composerインストール手順(Windows)](https://qiita.com/mikoski01/items/266469535e860312145d)
- [composerとは](https://qiita.com/atwata/items/d6f1cf95ce96ebe58010)
- [PHPExcelでエクセル出力入門](https://qiita.com/suin/items/7a8d0979b7675d6fd05b)
- [PhpSpreadsheetの使い方](https://qiita.com/sudnonk12/items/a0d58cc0f6ff1c6e2765)
- [PhpSpreadsheetに書き込む](https://qiita.com/mst_7colors/items/35cda620669c8e7fbe17)
- [PhpSpreadsheetでシートのコピーと削除｜teratail](https://teratail.com/questions/144042)