PHPを使ってExcelファイルを作る。
研修前の段階でExcelで作ったテーブルをCSVファイルで保存し、特定のセルの値を特定のフォームに入れる、ということをやってました。
今回はその逆、入力したフォームを元にExcelで読み込むファイルにするというもの。
CSVならまだしも最初からxlsやxlsxで保存するなんてことできんのか?と思ってたら
PHPExcel というライブラリを見つけました。
このライブラリ、普通のExcel上ですることを全てプログラムコード上でやっちゃうという便利なライブラリのようです。使わない手は無い。
と、言っても新しく使うライブラリなんて「どんな機能があるの?」と言って結局生かしきれないことが多いのですけれども・・・
とりあえず今回はそんなPHPExcelの話。
fuelPHPは・・・今回は関係ないはず。
とりあえずまずしなきゃいけないこと。
とりあえずライブラリをダウンロードしてきましょう。
http://phpexcel.codeplex.com/releases/view/107442
保存したファイルを使用するソフトはまずMicrosoftのExcelだと思うので
PHPExcel 1.7.9 - with Documentation in MS Office format
をダウンロードしておけばいいと思います(2013年11月5日時点での最新バージョン)
他のバージョン名を見るとOpenOfficeとかPDF形式にしてくれるものもあるみたいですね。
ダウンロードしたら解凍して中にある Classes と言うフォルダをWebサーバのどこかに置いておきます。
この後すぐにライブラリの読み込みをPHPで行うので参照先が分かりやすい位置に置いておくと吉。
PHP内でライブラリを読み込み~名をつけて保存まで。
いちいち説明していくよりこっちの方が見やすいと思うので・・・
<?php
//ライブラリ読み込み
require_once 'Classes/PHPExcel.php';
require_once 'Classes/PHPExcel/IOFactory.php';
// PHPExcelオブジェクトを生成する
$book = new PHPExcel();
//シート設定
$book->setActiveSheetIndex(0);
$sheet = $book->getActiveSheet();
$sheet->setTitle('シート1'); //シート名指定
// セルに値を入れる
$sheet->setCellValue('A1', 'テスト');
// Excel2003形式で出力する
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="o.xls"');
header('Cache-Control: max-age=0');
$writer = PHPExcel_IOFactory::createWriter($book, "Excel5");
$writer->save('php://output');
ざっとこんなところ。(参考:http://piyopiyocs.blog115.fc2.com/blog-entry-240.html)
シート設定やセルの値入力なんかは関数名覚えればすぐ使えそうですね。
よく分からなかったのがheaderの部分。headerなんて宣言した覚えはないのですが使えてます。
調べてみたら
http://php.net/manual/ja/function.header.php
どうやらphpに標準で入っている関数だったもよう。どうりで使える訳だ。
この部分、参考サイトによるとExcelの内容を出力バッファへ書き込んでいるだけだそうです。
で、最後のwriterで保存する元になるPHPExcelクラスと形式を選択。
Excel5というのは旧Excel(2003まで)の形式での保存になります。
この部分をExcel2007に替え、真ん中のheaderにあるファイルの拡張子をxlsxにすると今のExcelの機能を使った形式で保存ができます。
あとsheetの部分でセルを指定するのにA1と書きました。
これは直感的に分かりやすいでのすがループ処理をしたいということになると非常に厄介な存在。
この部分は
$sheet->setCellValueByColumnAndRow(1, 2, 'テスト');
と書き変えるとXとY座標で指定するみたいに使うことができます。
ループ処理で入力したい時はこっちがよさげですね。
ただこの関数、アルファベットの列部分は0から始まり、数字の行部分は1から始まります。
行部分は1から始まるのがいいでしょうけど列部分もそれに合わせて欲しかったな・・・