PHPExcelをCakePHPで使ってみる

| トラックバック(0)
 システムを作っていると、お客様からよく「このデータをExcelで使いたい」ということをお聞きします。
 大抵の場合CSV形式のファイルを出力して、それをExcelで読み込んで好きに加工して戴くのですが、やはりExcelの形式ではないので使い辛いと言われることがあります。
 そこで、Excelファイルを出力するようにしようということになり、PHPExcelというライブラリをCakePHPに組み込んで使うことにしました。

 出力するExcelのバージョンはExcel95(拡張子 .xls)とし、PHPExcelはVendorライクに使います。
 なるべくMVCモデルになるように、コントローラで必要なデータを取得して、ビューでファイル出力を行います。
 まず、PHPExcelライブラリ一式をVendor用のフォルダに配置します。

  \cakephp\app\vendors/phpexcel\PHPExcel.php
  \cakephp\app\vendors\phpexcel\PHPExcel\ (その他のファイル全部)

 コントローラで、PDF 出力ボタンを押したアクションを記述し、そこで必要なデータを取得・保存し、それ以外にシート名とファイル名を決めてビューに渡せるようにします。


class ExcelsController extends AppController {

	var $name = 'Excels';
	var $uses = array( 'Fruit' );
	var $layout = 'default';

	function fruits_view() {

		$this->layout = false;			// レイアウトは使わない

		// 送信データ
		$data = $this->Fruit->getFruitAll();
		$this->set( "data", $data );

		// シート名
		$this->set( "sheet_name", "Fruits" );

		// 保存ファイル名
		$filename = "fruits.xls";
		$this->set( "filename", $filename );
	}

 コントローラのアクションと同じ名前のビューを作ります。
 コントローラ名が excels_controller.php で、アクション名が fruits_view なので、ビューファイルは
\cakephp\app\views\excels\fruits_view.php
 です。

PHPExcelのライブラリを読み込みます。

// 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') );

 Excelのオブジェクトを生成し、最初のシートをアクティブにしてデータを出力します。
サンプルとしていろいろなメソッドを使ったコードを載せておきますので、詳しくはPHPExcelのマニュアルをご参照ください。
 但し、全部英語です。

	// Excelファイルの生成 ------------------------------------------

	// Create new PHPExcel object
	$objPHPExcel = new PHPExcel();

	// Set active sheet index to the first sheet, so Excel opens this as the first sheet
	$objPHPExcel->setActiveSheetIndex( 0 );
	$sheet = $objPHPExcel->getActiveSheet();

	// Rename sheet
	// シート名をつける
	$sheet->setTitle( $sheet_name );

		// デフォルトのフォント
	$sheet->getDefaultStyle()->getFont()->setName('MS Pゴシック');

	// デフォルトのフォントサイズ
	$sheet->getDefaultStyle()->getFont()->setSize(11);

	// デフォルトの列幅指定
	$sheet->getDefaultColumnDimension()->setWidth(12);

	// デフォルトの行の高さ指定
	$sheet->getDefaultRowDimension()->setRowHeight(18);

	// 列の幅指定
	$sheet->getColumnDimension( 'A' )->setWidth(12);
	$sheet->getColumnDimension( 'B' )->setWidth(30);
	$sheet->getColumnDimension( 'C' )->setWidth(12);

	// 列名
	$row_cnt = 1;
//	$sheet->setCellValueByColumnAndRow( 0, $row_cnt, "ID" );
	$cell_pos = 'A' . $row_cnt;
	// セルの値を入力
	$sheet->setCellValue( $cell_pos, "ID" );
	// 周りを罫線で囲む
	$sheet->getStyle( $cell_pos )->getBorders()->getAllBorders()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);
	// 文字色を指定(赤)
	$sheet->getStyle( $cell_pos )->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_RED);
	// ボールド指定
	$sheet->getStyle( $cell_pos )->getFont()->setBold(true);
	// フォントサイズの指定
	$sheet->getStyle( $cell_pos )->getFont()->setSize(15);
	// 背景色の指定(塗りつぶし)
	$sheet->getStyle( $cell_pos )->getFill()->setFillType( PHPExcel_Style_Fill::FILL_SOLID)->getStartColor()->setARGB('FF0000FF');
	// 縦方向の位置指定(中央)
	$sheet->getStyle( $cell_pos )->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);
	// 横方向の位置指定(中央)
	$sheet->getStyle( $cell_pos )->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);

//	$sheet->setCellValueByColumnAndRow( 1, $row_cnt, "名前" );
	$cell_pos = 'B' . $row_cnt;
	$sheet->setCellValue( $cell_pos, "名前" );
	$sheet->getStyle( $cell_pos )->getBorders()->getAllBorders()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);
	$sheet->getStyle( $cell_pos )->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_BLUE);
	$sheet->getStyle( $cell_pos )->getFont()->setBold(true);
	$sheet->getStyle( $cell_pos )->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT);

	$cell_pos = 'C' . $row_cnt;
	$sheet->setCellValue( $cell_pos, "数量" );
	$sheet->getStyle( $cell_pos )->getBorders()->getAllBorders()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);
	$sheet->getStyle( $cell_pos )->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_GREEN);
	$sheet->getStyle( $cell_pos )->getFont()->setBold(true);
	$sheet->getStyle( $cell_pos )->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);

	// PHPの日時出力
	$cell_pos = 'E' . $row_cnt;
	$time = time();					// 現在日時(Unix Timestamp)
	$sheet->setCellValue( $cell_pos, PHPExcel_Shared_Date::PHPToExcel( $time ) );
	$sheet->getStyle( $cell_pos )->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);

	// DBから取ってきたような日付の文字列(年月日のみ)
	$cell_pos = 'E2';
	PHPExcel_Cell::setValueBinder( new PHPExcel_Cell_AdvancedValueBinder() );
	$sheet->setCellValue( $cell_pos, '2010/5/10' );
	$sheet->getStyle( $cell_pos )->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);

	// 行の高さを指定
	$sheet->getRowDimension( $row_cnt )->setRowHeight( 50 );

	// データ
	$row_cnt = 2;
	foreach( $data as $id => $name ){

		// 行の高さ指定
		$sheet->getRowDimension( $row_cnt )->setRowHeight( 20 );

		// ID
		$cell_pos = 'A' . $row_cnt;
		$sheet->setCellValue( $cell_pos, $id );
		$sheet->getStyle( $cell_pos )->getBorders()->getAllBorders()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);
		$sheet->getStyle( $cell_pos )->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
/*
		// セルを( x, y )で指定した場合の例は下記
		$sheet->setCellValueByColumnAndRow( 0, $row_cnt, $id );
		$sheet->getStyleByColumnAndRow( 0, $row_cnt )->getBorders()->getAllBorders()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);
		$sheet->getStyleByColumnAndRow( 0, $row_cnt )->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
*/

		// 名前
		$cell_pos = 'B' . $row_cnt;
		$sheet->setCellValue( $cell_pos, $name );
		$sheet->getStyle( $cell_pos )->getBorders()->getAllBorders()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);

		// 数量
		$cell_pos = 'C' . $row_cnt;
		$sheet->setCellValue( $cell_pos, 1000 );
		$sheet->getStyle( $cell_pos )->getBorders()->getAllBorders()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);
		// 数字のフォーマット指定
		if( $row_cnt % 2 == 0 ){
			// カンマ区切り
			$sheet->getStyle( $cell_pos )->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED1);
		} else {
			// 小数点以下の桁数指定
			$sheet->getStyle( $cell_pos )->getNumberFormat()->setFormatCode( "#,##0.00" );
		}
		$row_cnt++;
	}

	// 全体を太い線で囲む
	$start_cell = "A1";
	$end_cell = "C" . ($row_cnt-1);
	$cell_range = "{$start_cell}:{$end_cell}";			// セルの範囲指定
	$sheet->getStyle( $cell_range )->getBorders()->getOutline()->setBorderStyle(PHPExcel_Style_Border::BORDER_MEDIUM);

 ファイルを一時フォルダに出力し、内容をクライアントに送信します。

	// Excelファイルの保存 ------------------------------------------

	// 保存ファイルフルパス
	$uploadDir = realpath( TMP );
	$uploadDir .= DS . 'excels' . DS;
	$path = $uploadDir . $filename;

	$objWriter = new PHPExcel_Writer_Excel5( $objPHPExcel );
	$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}");

	$result = file_get_contents( $path );	// ダウンロードするデータの取得
	print( $result ); 						// 出力

 これで、「Excel出力」ボタンを押して、ブラウザの別タブ(または別ウィンドウ)で生成したExcelファイルが開くようになります。

トラックバック(0)

このブログ記事を参照しているブログ一覧: PHPExcelをCakePHPで使ってみる

このブログ記事に対するトラックバックURL: http://www.okushin.co.jp/mt_co_jp/mt-tb.cgi/84