phpspreadsheetをインストールしPHPプログラムでExcelファイル出力を可能にする

プログラミング言語

PHPで作ったシステムにphpspreadsheetをインストールしExcelファイル出力を可能にしました。

別でBIツールとか導入していれば別ですが、業務ユーザーにとって統計データとかはExcelで落とせたほうが便利です。

Composerを用いてphpspreadsheetをインストールする

Composerをインストールする

phpspreadsheetをインストールするにはComposerが便利であるためインストールします。

ComposerはPHPプロジェクトにおける依存関係を管理するツールです。

まずはComposerがインストールされていないことを確認します。

php composer.phar -V

これでバージョン情報が出てこなければインストールされていません。

されていればComposerのインストール手順は飛ばして構いません。

Composerをインストールします。

cd /usr/local/bin 
curl -sS https://getcomposer.org/installer | php

curlは指定したURLからデータを取得するコマンドです。

sオプションはヘッダーとプロンプトの非表示、Sオプションは暗号化された接続をしたい際に使います。

sSをつけることで暗号化された接続でデータのみを取得することが可能です。

installerの内容を取得した後、パイプ(❘)で渡してphpで実行しています。

Composerの設定をする

Composerの設定をするためcomposer.jsonを作成します。

touch composer.json

composer.jsonファイルを編集していきます。

vi composer.json

下記のように記載してください。

{
     "require":  {   "phpoffice/phpspreadsheet": "^1.23"
     },
     "config": {
         "platform": {
             "php": "7.3.33"
         }
     }
}

phpspreadsheetの最新バージョンはphpのサポートが切れてから半年間しか対応しないとされているため、現在はPHP8.0以上しか動作保証されていません。

自身の環境のPHPのバージョンは上げておいたほうが安心かもしれません。

私は他のプログラムもあるためバージョンをあげられずPHP7.3でphpspreadsheet1.23をインストールしましたが、私の使いたい機能は動きました。

php-pecl-zipをインストールする

phpspreadsheetでExcelファイルを扱う際にzipファイルを読み書きできる必要があるため、php-pecl-zipをインストールします。

yum -y install --enablerepo=remi,remi-php73 php-pecl-zip

php-pecl-zipはZipアーカイブを操作するためのPHPの拡張機能です。

remi-php73はRedHat系ディストリビューションにPHPのRPMパッケージを追加するためのリポジトリです。

RPMパッケージはRed Hat Package Managerの略で、ソフトウェアパッケージのインストール・管理で使います。

ここではremiとremi-php73のリポジトリを使ってphp-pecl-zipをインストールしています。

phpspreadsheetをインストールする

Composerでphpspreadsheetをインストールします。

php /usr/local/bin/composer.phar install

こちらでcomposer.jsonファイルに記述されたパッケージをインストールすることができます。

先ほどcomposer.jsonにphpoffice/phpspreadsheetを記載しているため、phpspreadsheetがインストールされます。

/usr/local/bin配下のvendorディレクトリにインストールされているため、PHPプロジェクトのあるディレクトリに配置します。

cp /usr/local/bin/vendor /var/www/html

私の場合は/var/www/html配下にPHPプロジェクトを作成しているため、そちらにコピーしました。

phpspreadsheetを利用してExcelファイルを出力する

phpspreadsheetをPHPプロジェクトから呼び出す準備ができたため、実際に利用してExcelファイルを作成してみます。

下記のデータのExcelファイルを出力する例を記載します。

idprefecturecity
1TokyoMusashino
2OosakaSakai
3AichiNagoya
適当なデータ

このデータは$dataArr()という配列に1,Tokyo,Musashinoというようにカンマ区切りで1行ずつ入っていると仮定して後ほどの記載は進めます。

プログラム内でphpspreadsheetを読み込む

phpspreadsheetをインストールしたため、プログラム内から呼び出せるようにします。

まずは呼び出したいプログラムファイル内で下記を宣言し、Composerでインストールしたパッケージを使用できるようにします。

require '../vendor/autoload.php'

phpspreadsheetのパッケージが使えるようになったため、phpspreadsheetのクラスや関数をインポートします。

use PhpOffice\PhpSpreadsheet\Spreadsheet
use PhpOffice\PhpSpreadsheet\Style
use PhpOffice\PhpSpreadsheet\Style\Border
use PhpOffice\PhpSpreadsheet\Writer\Xlsx

PhpOffice\PhpSpreadsheet\SpreadsheetはPHPでスプレッドシートのファイルの読み書きを行えるようにするライブラリです。

PhpOffice\PhpSpreadsheet\Styleはスプレッドシートの外観を設定するためのライブラリです。

PhpOffice\PhpSpreadsheet\Writer\XlsxはxlsxフォーマットのExcelファイルの作成・保存を可能にするライブラリです。

spreadsheetオブジェクトを設定する

クラスや関数が使えるようになったためspreadsheetオブジェクトの設定をします。

まずはSpreadsheetオブジェクトを作成します。

$spreadsheet = new Spreadsheet();

次にSpeadsheetオブジェクトのシートを取得します。

$sheet = $spreadsheet.getActiveSheet();

シートを取得したらシートのタイトルを指定します。

$sheet->setTitle("テスト出力");

そのシートの表頭(1列目)の値を指定します。

$sheet->setCellValue('A1','id');
$sheet->setCellValue('B1','prefecture');
$sheet->setCellValue('C1','city');

シートに値を出力します。

まずデータを入れるための形に加工していきます。

前記した$datArrのデータを1レコードずつカンマ区切りで分割し$dataにいれていきます。

$i = 0
foreach($dataArr as $dataRec) {
 $data = explode(",",$dataRec);
 $dataList[$i] = $data;
 $i + 1;
}

$dataArrにはカンマ区切りのデータが入っているため、それをexplodeで分割して配列$dataにし別の配列$dataListの1要素としています。

この記事の主題と関係ないところですので詳細は割愛します。

シートにデータをセットします。

$sheet->fromArray($dataList, null, 'A2', true);

fromArrayの第1引数に配列を指定することで配列を読み込めます。

第2引数は配列から値が渡されなかったセルに入るデフォルト値、第3引数は値をセットする開始位置です。

シートに値がセットできたので、スタイルを設定します。

まずは枠線を設定します。

$lastRow = $i + 1;
$sheet->getStyle('A1:C'.$lastRow)->getBorders-›getAllBorders()-›setBorderStyle(Border::BORDER_THIN);

前のコードの$iを使ってレコード数を取得し、それに表頭分+1してシートの列数として$lastRowに入れます。

列数を利用しgetStyleでシートの指定範囲のスタイルを取得、getBordersとgetAllBordersで枠線を取得します。

setBorderStyleでBORDER::BORDER_THINを引数とすることで薄い枠線を引くことができます。

枠線の種類を変えるときはBORDER::BORDER_MEDIUMやBORDER::BORDER_DASHEDのように記載します。

次に列幅を変更します。

for ($j = 0; $j < count($data); $j++){
$sheet->getColumnDimensionByColumn($j)->setWidth(16);
}

forで列ごとに列幅の変更を行います。

$dataは前の処理で作った1レコード分のデータの配列です。

今回その要素数が列数になっているためこの処理で使っています。

シート$sheetからgetColumnDimensionByColumnで引数の列の列幅を取得しています。

そしてsetWidthで列幅を16ピクセルに変更しています。

httpヘッダーの設定をする

Excelファイル出力でクライアントとサーバーのやり取りをすることになるため、httpヘッダー情報を設定して通信を制御します。

header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); 
header('Content-Disposition: attachment;filename="'.$fileName.'"'); 
header('Cache-Control: max-age=0'); 
header('Cache-Control: cache, must-revalidate'); 
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); 

Content-Typeはクライアントに送信されるコンテンツの種類と形式を指定するために使用します。

application/vnd.openxmlformats-officedocument.spreadsheetml.sheetはExcelファイルのMIMEタイプです。

MIMEタイプとはインターネット上で送受信されるファイルの種類を識別するための情報を指します。

Content-Dispositionはブラウザにコンテンツをどのように扱うべきかを指定します。

attachmentを指定するとファイルをダウンロードさせ、filenameではダウンロードファイルの名前を指定できます。

$filenameは後ほど値を設定します。

Cache-Controlはキャッシュの制御に使用します。

max-ageでキャッシュの有効期限を指定できます。

cache, must-revalidateでキャッシュされたコンテンツを再検証する必要があることを示しています。

Expiresではコンテンツの有効期限を指定できます。

あえて過去日付を指定することでブラウザやプロキシサーバーにコンテンツがキャッシュされないようにしています。

Last-Modifiedはリソースが最後に変更された日時を示します。

gmdateはphpの関数でGMTの日時を示します。

GMTは世界共通の標準時でロンドンのグリニッジ天文台の時刻です。

phpspreadsheetでExcelファイルを出力する

出力するファイル名を指定します。

$fileName = "test_generate.xlsx";

Excelファイルを書き出します。

$writer = new Xlsx($spreadsheet);
$writer->save('php://output');

先ほどまで設定していた$spreadsheetの内容でXlsxオブジェクトを作成し、saveメソッドを使ってファイルを出力しています。

php://outputを引数に指定することでブラウザに直接出力ができます。

これで出力処理の記載は完了です。

適切にPHPプロジェクト内に組み込んでもらえればExcelファイルを出力できるはずです。

タイトルとURLをコピーしました