スポンサードリンク

CakePHP
CakePHP

前回、ExcelReviserを使おうとしたのですが、

サーバーが64bitだったため使えず・・・

そのため、結構使われている

PHPExcelを設置しました。

スポンサードリンク

Excel出力の流れ

今回は「Excel作成」というボタンを押すと

事前に用意してあるテンプレートファイルに

DBからのデータを埋めていって

Excel95形式(.xls)でダウンロードするという流れです。

PHPExcelをダウンロード

まず、PHPExcelのサイトで

赤枠の「download」からダウンロードします。

※現時点ではバージョンは1.7.9です。

PHPExcel
PHPExcel

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

PHPExcelの中身
PHPExcelの中身

使うのは「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は出力に時間がかなりかかるとネットで書いてあったのですが

テンプレートファイル使ったからか、そんなに時間かからなかったです。

そこまで行数もなかったからかもしれないですけどね~。

(追記)
ファイルのダウンロードの仕方ですが

(PHP) ファイルダウンロードの仕方

上記にも書きましたが、

ダウンロードする際は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);

上記のようにしてます。

(参考)
PHPExcelをCakePHPで使ってみる

PHPExcel の使い方

PHPExcel Excelファイルの作成

ダウンロードするファイル名が文字化けする現象

スポンサードリンク