Skip to content

Instantly share code, notes, and snippets.

@sunvisor
Created November 14, 2011 07:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sunvisor/1363475 to your computer and use it in GitHub Desktop.
Save sunvisor/1363475 to your computer and use it in GitHub Desktop.
xFrameworkPX_Controller_Excel Class
<?php
/**
* xFrameworkPX_Controller_Excel Class File
*
* PHP versions 5
*
* @category xFrameworkPX
* @package xFrameworkPX_Controller
* @author NAKAMURA, Hisashi <hisashi@sunvisor.net>
*/
// {{{ xFrameworkPX_Controller_Excel
/**
* xFrameworkPX_Controller_Excel Class
*
* @category xFrameworkPX
* @package xFrameworkPX_Controller
* @author NAKAMURA, Hisashi <hisashi@sunvisor.net>
*/
class xFrameworkPX_Controller_Excel extends xFrameworkPX_Controller_Web
{
/**
* 設定情報
*
* Excel出力の設定情報連想配列
* 'type' : 出力タイプ(初期値 Excel5)
* 'filename' : 出力ファイル名指定しない場合はURLのファイル名になる
* 'template' : ワークブックのテンプレート名。空欄の場合はテンプレートを使わない
* @var array
*/
public $xlConfig = array();
// Excel ワークブックオブジェクト
protected $xlBook;
// {{{ __construct
/**
* コンストラクタ
*
* @param xFrameworkPX_Util_MixedCollection $conf 設定オブジェクト
* @return void
*/
public function __construct($conf)
{
// スーパークラスメソッドコール
parent::__construct($conf);
// Config の初期値設定
if( !isset($this->xlConfig['type']) ){
$this->xlConfig['type'] = 'Excel5';
}
if( isset($this->xlConfig['template']) ){
if( isset($conf->pxconf['EXCEL_TEMPLATE_DIR'])){
$path = $conf->pxconf['EXCEL_TEMPLATE_DIR'];
} elseif( isset($conf->pxconf['TEMPLATE_DIR'])){
$path = $conf->pxconf['TEMPLATE_DIR'];
} else {
$path = '../templates';
}
$this->xlConfig['template'] =
normalize_path($path . DS . $this->xlConfig['template']);
}
// PHPExcel ライブラリの読み込み
$this->requireLibrary('PHPExcel/Classes/PHPExcel.php');
$this->requireLibrary('PHPExcel/Classes/PHPExcel/IOFactory.php');
// $this->log->trace("Peak memory usage: " . (memory_get_peak_usage(true) / 1024 / 1024) . " MB");
// WorkBook インスタンスの生成
if( isset($this->xlConfig['template']) ){
//テンプレートを読み込んでインスタンス化
$reader = PHPExcel_IOFactory::createReader($this->xlConfig['type']);
$this->xlBook = $reader->load($this->xlConfig['template']);
} else {
$this->xlBook = new PHPExcel();
}
}
// }}}
// {{{ setUp
/**
* 開始イベントハンドラ
*
* @return bool サスペンドフラグ
*/
public function setUp()
{
}
// }}}
// {{{ tearDown
/**
* 終了イベントハンドラ
*
* @return bool サスペンドフラグ
*/
public function tearDown()
{
// ヘッダー送信
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Type: charset=utf8");
if( isset($this->xlConfig['filename'])) {
// IEの場合のファイル名文字化け対処
$ua = $_SERVER['HTTP_USER_AGENT'];
$filename = $this->xlConfig['filename'];
if (strstr($ua, "MSIE") && !strstr($ua, 'Opera')) {
$filename = mb_convert_encoding($filename, "CP932", "UTF-8");
$filename = str_replace('#', '%23', $filename);
}
header('Content-Disposition: attachment;filename="'.$filename.'"');
}
header("Content-Transfer-Encoding: binary ");
// Excelをクライアントに出力
$writer = PHPExcel_IOFactory::createWriter($this->xlBook, $this->xlConfig['type']);
$writer->save('php://output');
// 後始末
$this->xlBook->disconnectWorksheets();
unset($this->xlBook);
// スーパークラスメソッドコール
parent::tearDown();
}
// }}}
// {{{ addSheet
/**
* ワークシート追加
*
* @param string $title シートのタイトル
* @param string $template テンプレートファイル名
* @param integer $page テンプレートの参照するページ
*/
protected function addSheet($title, $template = null, $page = 0)
{
if( $template ){
// テンプレートを元に追加
$reader = PHPExcel_IOFactory::createReader($this->xlConfig['type']);
$tempBook = $reader->load($template);
$sheet = $tempBook->getSheet($page)->copy();
$tempBook->disconnectWorksheets();
unset($tempBook);
$this->xlBook->addExternalSheet($sheet, $this->xlBook->getSheetCount()+1);
} else {
$sheet = $this->xlBook->createSheet($this->xlBook->getSheetCount()+1);
if( isset($title) ){
$sheet->setTitle($title);
}
}
}
// }}}
/**
* 一行毎に塗り分ける
*
* @param PHPExcel_Worksheet $sheet
* @param integer $row1 左上のセルの行
* @param integer $col1 左上のセルの列
* @param integer $row2 右下のセルの行
* @param integer $col2 右下のセルの列
* @param string $color1 塗り分ける色1 Default:CCFFFF
* @param string $color2 塗り分ける色2 Default:FFFFFF
*/
/*protected function stripeRows($sheet, $row1, $col1, $row2, $col2, $color1 = 'CCFFFF', $color2 = 'FFFFFF')
{
$flag = true;
for( $r = $row1; $r <= $row1+1; $r++ ){
if( $flag ){
$color = $color1;
} else {
$color = $color2;
}
for( $c = $col1; $c <= $col2; $c++ ){
$this->setFillColor($sheet, $r, $c, $color);
}
$flag = !$flag;
}
}*/
/**
* セルの背景色をセットする
*
* @param PHPExcel_Worksheet $sheet
* @param integer $row
* @param integer $col
* @param string $color
* @param PHPExcel_Style_Fill $style
*/
protected function setFillColor($sheet, $row, $col, $color, $style = PHPExcel_Style_Fill::FILL_SOLID)
{
$fill = $sheet->getStyleByColumnAndRow($col, $row)->getFill();
$fill->setFillType(PHPExcel_Style_Fill::FILL_SOLID);
$fill->getStartColor()->setRGB($color);
}
/**
* セル範囲に罫線を引く
* @param PHPExcel_Worksheet $sheet
* @param integer $row1 左上のセルの行
* @param integer $col1 左上のセルの列
* @param integer $row2 右下のセルの行
* @param integer $col2 右下のセルの列
* @param PHPExcel_Style_Border $outerStyle 外枠のスタイル default=BORDER_THIN
* @param PHPExcel_Style_Border $innerStyle 内側のスタイル default=BORDER_MEDIUM
*/
/*protected function setBorderStyleBox(
$sheet, $row1, $col1, $row2, $col2,
$outerStyle = PHPExcel_Style_Border::BORDER_THIN,
$innerStyle = PHPExcel_Style_Border::BORDER_HAIR
)
{
for( $r = $row1; $r <= $row2; $r++ ){
for( $c = $col1; $c <= $col2; $c++ ){
$styles = array(
'top' => $innerStyle,
'left' => $innerStyle
);
if( $r == $row1 ) {
$styles['top'] = $outerStyle;
}
if( $c == $col1 ) {
$styles['left'] = $outerStyle;
}
if( $r == $row2 ) {
$styles['bottom'] = $outerStyle;
}
if( $c == $col2 ) {
$styles['right'] = $outerStyle;
}
$this->setBorderStyle($sheet, $r, $c, $styles);
}
}
}*/
/**
* セルの罫線を引く<br />
* $styles は線のスタイルを連想配列で指定<br />
* キーは top,bottom,left,right,all<br />
* @param PHPExcel_Worksheet $sheet
* @param integer $row
* @param integer $col
* @param array $styles
* 例) array('top' => PHPExcel_Style_Border::BORDER_THIN)
*/
protected function setBorderStyle($sheet, $row, $col, $styles)
{
$borders = $sheet->getStyleByColumnAndRow($col, $row)->getBorders();
if( isset( $styles['top'] ) ) {
$borders->getTop()->setBorderStyle($styles['top']);
}
if( isset( $styles['bottom'] ) ) {
$borders->getBottom()->setBorderStyle($styles['bottom']);
}
if( isset( $styles['left'] ) ) {
$borders->getLeft()->setBorderStyle($styles['left']);
}
if( isset( $styles['right'] ) ) {
$borders->getRight()->setBorderStyle($styles['right']);
}
if( isset( $styles['all'] ) ) {
$borders->getTop()->setBorderStyle($styles['all']);
$borders->getBottom()->setBorderStyle($styles['all']);
$borders->getLeft()->setBorderStyle($styles['all']);
$borders->getRight()->setBorderStyle($styles['all']);
}
}
/**
* 書式をコピーする
* @param PHPExcel_Worksheet $sheet
* @param integer $sourceRow コピー元のセルの行
* @param integer $sourceCol コピー元のセルの列
* @param integer $destRow コピー先のセルの行
* @param integer $destCol コピー先のセルの列
* @param integer $destRow2 コピー先のセルの行(範囲指定) Default:null
* @param integer $destCol2 コピー先のセルの列(範囲指定) Default:null
*/
protected function copyStyle($sheet, $sourceRow, $sourceCol, $destRow, $destCol, $destRow2=null, $destCol2=null)
{
$style = $sheet->getStyleByColumnAndRow($sourceCol, $sourceRow);
if( $destRow2 || $destCol2 ){
// コピー先を範囲指定
$range = $sheet->getCellByColumnAndRow($destCol, $destRow)->getCoordinate() . ':' .
$sheet->getCellByColumnAndRow($destCol2, $destRow2)->getCoordinate();
} else {
$range = $sheet->getCellByColumnAndRow($destCol, $destRow)->getCoordinate();
}
$this->log->trace("copyStyle Dest Range:" . $range);
$sheet->duplicateStyle( $style, $range );
}
/**
* セルにデータをセットする<br />
* データは一つでも配列でもOK。二次元まで。
* @param PHPExcel_Worksheet $sheet
* @param integer $row
* @param integer $col
* @param mixed $value
* @param array $cellstyles
*/
protected function setValue($sheet, $row, $col, $value, $cellstyles = null )
{
if( is_array($value) ){
$r = $row;
foreach ($value as $rowdata ){
$c = $col;
if( is_array($rowdata) ){
foreach ($rowdata as $colname=>$coldata){
if( $coldata ) {
if( $cellstyles && isset($cellstyles[$colname])){
// セルスタイルの設定
$sheet->setCellValueExplicitByColumnAndRow(
$c, $r, $coldata, $cellstyles[$colname]
);
} else {
$sheet->setCellValueByColumnAndRow(
$c, $r, $coldata
);
}
}
$c++;
}
} else {
$sheet->setCellValueByColumnAndRow($c, $r, $rowdata);
}
$r++;
}
} else {
$sheet->setCellValueByColumnAndRow($col, $row, $value);
}
}
}
// }}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment