
前回、ExcelReviserを使おうとしたのですが、
サーバーが64bitだったため使えず・・・
そのため、結構使われている
PHPExcelを設置しました。
Excel出力の流れ
今回は「Excel作成」というボタンを押すと
事前に用意してあるテンプレートファイルに
DBからのデータを埋めていって
Excel95形式(.xls)でダウンロードするという流れです。
PHPExcelをダウンロード
まず、PHPExcelのサイトで
赤枠の「download」からダウンロードします。
※現時点ではバージョンは1.7.9です。

ダウンロードするとフォルダの中身以下のような感じです。

使うのは「Classes」フォルダの中身だけです。
CakePHP側にPHPExcelを移動
先ほどダウンロードしたフォルダの中にある「Classes」の中にある
「PHPExcel.php」と「PHPExcel」フォルダをapp/Vendorに移動します。
今回はVendorに「phpexcel」というフォルダを作ってそこに入れました。
app
|-Vendor
|-phpexcel
|-PHPExcel.php
|-PHPExcel
テンプレートファイルを設置
今回はテンプレートファイルにデータを埋めていくので
template.xlsというファイルをapp/tmpのフォルダの中に
「excel」というフォルダを作ってそこに入れてます。
app
|-tmp
|-cache
|-logs
|-sessions
|tests
|-excel
|-template.xls
コントローラーで表示データを用意
今回のイメージはあるビューページに「Excel作成」ボタンを用意して
ボタンを押すとそのアクションからDBのデータを取ってきて
Excel出力するという流れです。
まず、「Excel作成」ボタン用のexcelアクションを作ります。
public function excel(){
//レイアウトは使わない
$this->layout = '';
//$this->layout = false; でもOK!
//DBのデータを読み込む
$data = $this->Model->find('all');
$this->set('data', $data);
}
※findメソッドで取ってくるデータは普通に使う時と同じです。
レイアウトと使うと出力したExcelに
普通に使っていうページのデータまで一緒に出るので
レイアウトは使わないに設定します。
ビューファイルでExcelの中身を作成
ビューファイルでExcelに出力する中身を作っていきます。
// Excel出力用ライブラリ
App::import('Vendor', 'PHPExcel', array('file'=>'phpexcel' . DS . 'PHPExcel.php'));
App::import('Vendor', 'PHPExcel_IOFactory', array('file'=>'phpexcel' . DS . 'PHPExcel' . DS . 'IOFactory.php'));
App::import('Vendor', 'PHPExcel_Cell_AdvancedValueBinder', array('file'=>'phpexcel' . DS . 'PHPExcel' . DS . 'Cell' . DS . 'AdvancedValueBinder.php'));
// Excel95用ライブラリ
App::import('Vendor', 'PHPExcel_Writer_Excel5', array('file'=>'phpexcel' . DS . 'PHPExcel' . DS . 'Writer' . DS . 'Excel5.php'));
App::import('Vendor', 'PHPExcel_Reader_Excel5', array('file'=>'phpexcel' . DS . 'PHPExcel' . DS . 'Reader' . DS . 'Excel5.php'));
今回はExcel95(.xls)で出力するのでExcel95用のライブラリを読み込んでます。
次にPHPExcelのオブジェクトを作成します。
//PHPExcelオブジェクトの作成
//新規の場合
//$PHPExcel = new PHPExcel();
//テンプレートの読み込み
$objReader = PHPExcel_IOFactory::createReader("Excel5");
//テンプレートファイルフルパス
$template = realpath(TMP);
$template .= DS . 'excel' . DS;
$template_path = $template . "template.xls";
$PHPExcel = $objReader->load($template_path);
PHPExcelのオブジェクトを作成する際に
事前に用意しておいたテンプレートファイル(template.xls)を読み込みます。
テンプレートを使わない場合は3行目でオブジェクトを作成します。
その際は5行目以降は削除してください。
次に、Excelのデータを入れるシートをアクティブにします。
//表紙への入力 //シートの設定 $PHPExcel->setActiveSheetIndex(0); //0はsheet1(一番左のシート) $sheet = $objPHPExcel->getActiveSheet();
そして、Excelのセルにデータを入れていきます。
データの入れ方は
$sheet->setCellValue('セル番号', '入れたいデータ');
(例)
$sheet->setCellValue('C5', $data['Model']['id']);
として、入力データを書いていきます。
Excelデータの保存と出力
入力データを作成できたら、保存と出力をします。
//保存ファイル名
$filename = "output.xls";
// 保存ファイルパス
$upload = realpath( TMP );
$upload .= DS . 'excel' . DS;
$path = $upload . $filename;
$objWriter = new PHPExcel_Writer_Excel5( $PHPExcel ); //2003形式で保存
$objWriter->save( $path );
// Excelファイルをクライアントに出力 ----------------------------
//保存をしてから出力
Configure::write('debug', 0); // debugコードを非表示
header("Content-disposition: attachment; filename={$filename}"); //ダウンロードさせるため
header("Content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; name={$filename}"); //Excel2007(xlsx)でダウンロード※xlsでも問題なし
$result = file_get_contents( $path ); // ダウンロードするデータの取得
print( $result ); // 出力
これでExcelファイルが出力されました。
PHPExcelはファイルをサーバー上に保存するので
保存先にテンプレートファイルが置いてあるフォルダを指定してます。
保存ファイル名で日本語を使うと文字化けするので
変数を使ってファイル名で日本語使いたいという場合は
$filename = "エクセル.xls"; //文字コード変換 $filename = mb_convert_encoding($filename, 'sjis', 'utf-8');
上記の様にして、文字コードを変えて下さい。
PHPExcelは出力に時間がかなりかかるとネットで書いてあったのですが
テンプレートファイル使ったからか、そんなに時間かからなかったです。
そこまで行数もなかったからかもしれないですけどね~。
(追記)
ファイルのダウンロードの仕方ですが
上記にも書きましたが、
ダウンロードする際はreadfile関数を使う方がよさそうなので
現在は
・・・略・・・
$objWriter = new PHPExcel_Writer_Excel5( $PHPExcel ); //2003形式で保存
$objWriter->save( $path );
// Excelファイルをクライアントに出力 ----------------------------
//保存をしてから出力
Configure::write('debug', 0); // debugコードを非表示
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment;filename="' . $filename . '"');
readfile($path);
上記のようにしてます。
