ラベル Excel の投稿を表示しています。 すべての投稿を表示
ラベル Excel の投稿を表示しています。 すべての投稿を表示

2012年4月25日水曜日

[PHP][Excel][PHPExcel] 作成したExcelをダウンロードする

PHPExcelで作成したExcelをダウンロードしたい時がある。
一旦適当なフォルダにExcelを作ってそれをダウンロードさせてもいいが、
フォルダにパーミッションを設定したりダウンロードし終わったExcelを削除したりと、
余計な手間が多い。

そういう時は直接Excelをダウンロードさせるといい。

//ClassesをおいたパスからPHPExcel.phpをインクルードする
require_once('Classes/PHPExcel.php');
//Excelのクラスを作る
$excel=new PHPExcel();
//アクティブなシートを取得する
$sheet=$excel->getActiveSheet();
//シートに名前をつける
$sheet->setTitle('test');
//A1参照で値を入れる
$sheet->setCellValue('A1','test');

//ヘッダを設定する
header('Content-Type: application/octet-stream');
//ダウンロードするときのファイル名を指定する
//.xlsx形式でDLするときは拡張子をxlsxに変えておく
header('Content-Disposition: attachment;filename="test.xls"');
//.xls形式で書き込むためのクラスを作る
//.xlsx形式を書き込む場合は'Excel5'の部分を'Excel2007'に変える →$writer=PHPExcel_IOFactory::createWriter($excel,'Excel2007');
$writer=PHPExcel_IOFactory::createWriter($excel,'Excel5');
//出力バッファへの書き込む
$writer->save('php://output');
exit;

こうすることによって、
一旦ファイルを作ったりすることなくダウンロードさせることが出来る。
なお
header('Content-Type: application/octet-stream')
の代わりに
header('Content-Type: application/vnd.ms-excel')
を指定することもあるが、ブラウザやバージョン、設定によって挙動が異なってしまうため、
あまりお勧めはしない。
ただ、あえてブラウザでExcelを開けるときは開きたいという場合は指定することもある。

2012年4月23日月曜日

[PHP][Excel][PHPExcel] ボーダーをまとめて設定する

PHPExcelの関連サイトを見ると一つのセルに対して上下左右のボーダーにつけるときに

//ClassesをおいたパスからPHPExcel.phpをインクルードする
require_once('Classes/PHPExcel.php');
//書き込むExcelのパス
define('EXCEL','data/test.xls');
//Excelのクラスを作る
$excel=new PHPExcel();
//アクティブなシートを取得する
$sheet=$excel->getActiveSheet();
//シートに名前をつける
$sheet->setTitle('border test');
//A1参照で値を入れる
$sheet->setCellValue('A1','test');
//セルの上に罫線を引く
$sheet->getStyle('A1')->getBorders()->getTop()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);
//セルの下に罫線を引く
$sheet->getStyle('A1')->getBorders()->getBottom()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);
//セルの左に罫線を引く
$sheet->getStyle('A1')->getBorders()->getLeft()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);
//セルの右に罫線を引く
$sheet->getStyle('A1')->getBorders()->getRight()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);
//.xls形式で書き込むためのクラスを作る
//.xlsx形式を書き込む場合は'Excel5'の部分を'Excel2007'に変える →$writer=PHPExcel_IOFactory::createWriter($excel,'Excel2007');
$writer=PHPExcel_IOFactory::createWriter($excel,'Excel5');
//ファイルに書き込む
$writer->save(EXCEL);

としていることが多い。
もちろんこれでも誤りではないし、きちんとボーダーは設定できるのだが、
いかんせんセル1つならまだしも数が多いと大変である。

実は

//ClassesをおいたパスからPHPExcel.phpをインクルードする
require_once('Classes/PHPExcel.php');
//書き込むExcelのパス
define('EXCEL','data/test.xls');
//Excelのクラスを作る
$excel=new PHPExcel();
//アクティブなシートを取得する
$sheet=$excel->getActiveSheet();
//シートに名前をつける
$sheet->setTitle('border test');
//A1参照で値を入れる
$sheet->setCellValue('A1','test');
//セルの上下左右全てに罫線を引く
$sheet->getStyle('A1')->getBorders()->getAllBorders()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);
//.xls形式で書き込むためのクラスを作る
//.xlsx形式を書き込む場合は'Excel5'の部分を'Excel2007'に変える →$writer=PHPExcel_IOFactory::createWriter($excel,'Excel2007');
$writer=PHPExcel_IOFactory::createWriter($excel,'Excel5');
//ファイルに書き込む
$writer->save(EXCEL);

とすることでまとめてボーダーを設定することが出来る。

覚えておいて損はないと思う。

2012年3月7日水曜日

[PHP][Excel][PHPExcel] セルに0埋め(0詰め)した値をセットする

PHPExcelにあるメソッドのsetCellValueやsetCellValueByColumnAndRowで0埋め(0詰め)で検索してきていた人がいたのでせっかくなのでコードを紹介してみる。

ちなみに普通にアプリケーションのExcelでもセルの書式設定から表示形式を文字列にしないと、「01」などと入力しても「1」に勝手に書き換えられてしまう。

PHPExcelも考え方は同じでセルの表示形式を文字列にしつつ値を入れるという方法になる。

//ClassesをおいたパスからPHPExcel.phpをインクルードする
require_once('Classes/PHPExcel.php');
//書き込むExcelのパス
define('EXCEL','data/test.xls');

//Excelのクラスを作る
$excel=new PHPExcel();
//アクティブなシートを取得する
$sheet=$excel->getActiveSheet();
//シートに名前をつける
$sheet->setTitle('sheet title');
//R1C1参照で値を入れる
$sheet->setCellValueExplicitByColumnAndRow(0,1,'01',PHPExcel_Cell_DataType::TYPE_STRING);
//A1参照で値を入れる
$sheet->setCellValueExplicit('A2','01',PHPExcel_Cell_DataType::TYPE_STRING);
//.xls形式で書き込むためのクラスを作る
//.xlsx形式を書き込む場合は'Excel5'の部分を'Excel2007'に変える →$writer=PHPExcel_IOFactory::createWriter($excel,'Excel2007');
$writer=PHPExcel_IOFactory::createWriter($excel,'Excel5');
//ファイルに書き込む
$writer->save(EXCEL);

とすることによって

ABC
101
2002
3

のようなデータを書き込むことが可能になる。

2012年3月6日火曜日

[PHP][Excel][PHPExcel] PHPExcelのgetNestingLevelエラー問題

PHPExcelを使ってExcelを読み込みたい時がある。
しかし、一定の条件によって
Fatal error: Call to a member function getNestingLevel() on a non-object in ~~~パス/Classes/PHPExcel/Reader/Excel5.php on line 842 
というエラーが表示され、先に進まないことがある。

どうも、これ自体はPHPExcelのバグのようでまだ修正されてないようだ。
ただ、パッチを作ってくれている人がいるようで、そのパッチを当てれば動くようになる。

PHPExcel - Patches

上記サイトのID:9136のところにそのパッチのダウンロードリンクがある。
そのパッチをExcel5.phpに当ててやれば、getNestingLevel問題は解決する。

[PHP][Excel][PHPExcel] PHPExcelの導入2

前回はPHPExcelからデータを読み込む方法をやったので、
今回はExcelにデータを書き込む方法をやってみる。
まずは単純なデータの書き込み。

//ClassesをおいたパスからPHPExcel.phpをインクルードする
require_once('Classes/PHPExcel.php');
//書き込むExcelのパス
define('EXCEL','data/test.xls');

//Excelのクラスを作る
$excel=new PHPExcel();
//アクティブなシートを取得する
$sheet=$excel->getActiveSheet();
//シートに名前をつける
$sheet->setTitle('sheet title');
//R1C1参照で値を入れる
$sheet->setCellValueByColumnAndRow(0,1,'test');
//A1参照で値を入れる
$sheet->setCellValue('B1','test2');
//数字を入れる
$sheet->setCellValue('A2','3');
//計算式を入れる
$sheet->setCellValue('B2','=A2*3');
//.xls形式で書き込むためのクラスを作る
//.xlsx形式を書き込む場合は'Excel5'の部分を'Excel2007'に変える →$writer=PHPExcel_IOFactory::createWriter($excel,'Excel2007');
$writer=PHPExcel_IOFactory::createWriter($excel,'Excel5');
//ファイルに書き込む
$writer->save(EXCEL);

とすると

ABC
1testtest2
239
3

というExcelファイルが作られる。

またスタイルの設定なども変えることが可能。

//ClassesをおいたパスからPHPExcel.phpをインクルードする
require_once('Classes/PHPExcel.php');
//書き込むExcelのパス
define('EXCEL','data/test.xls');

//Excelのクラスを作る
$excel=new PHPExcel();
//アクティブなシートを取得する
$sheet=$excel->getActiveSheet();
//シートに名前をつける
$sheet->setTitle('sheet title');
//A1参照で値を入れる
$sheet->setCellValue('A1','test1');
//フォントサイズ
$sheet->getDefaultStyle()->getFont()->setSize(10);
//フォント
$sheet->getDefaultStyle()->getFont()->setName('メイリオ');
//セルの下に罫線を引く
$sheet->getStyle('A1')->getBorders()->getBottom()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);
//センター寄せ
$sheet->getStyle('A1')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
//文字色
$sheet->getStyle('A1')->getFont()->getColor()->setARGB('FFFF3333');
//背景色
$sheet->getStyleByColumnAndRow(0,1)->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID);
$sheet->getStyleByColumnAndRow(0,1)->getFill()->getStartColor()->setARGB('FFCCCCFF');

//.xls形式で書き込むためのクラスを作る
//.xlsx形式を書き込む場合は'Excel5'の部分を'Excel2007'に変える →$writer=PHPExcel_IOFactory::createWriter($excel,'Excel2007');
$writer=PHPExcel_IOFactory::createWriter($excel,'Excel5');
//ファイルに書き込む
$writer->save(EXCEL);

ABC
1test
2
3

という結果になる。

2012年3月2日金曜日

[PHP][Excel][PHPExcel] PHPExcelの導入

PHPからExcelを扱うというのは、意外と顧客からの要望に上がることが多い。

また、仕様書やデータ定義、DB定義などもExcelで書かれていると、
簡単にコピペでプログラムに持ってくることはできない。
だからといっていちいち手作業でDB定義書からCREATE文を作るなどというのも結構手間だ。
そういう時にPHPからExcelを読み取って、自動的にCREATE文を作るなりすると効率がいい。

まずは、PHPExcelの本家サイトからライブラリを落としてこよう。
落としてきたZIPを解凍すると、中にClassesフォルダがある。
この中に必要なクラスが定義されているファイルが入っているので、
これを必要な場所にフォルダごとおいておこう。

後はコードを書くだけ。
試しにExcel内の最初のシートの中身を配列に代入するプログラムを書いてみる。

ABC
1123
2456
3789

上記のような構造のExcelファイルを読み込むとする。

//ClassesをおいたパスからPHPExcel.phpをインクルードする
require_once('Classes/PHPExcel.php');
//読み込むExcelのパス
define('EXCEL','data/test.xls');

//.xls形式を読むという設定でクラスと作る
//.xlsx形式を読み込む場合は'Excel5'の部分を'Excel2007'に変える →$reader=PHPExcel_IOFactory::createReader('Excel2007');
$reader=PHPExcel_IOFactory::createReader('Excel5');
//読み込むExcelのパスを指定する
$excel=$reader->load(EXCEL);
//最初のシートを選ぶ
$sheet=$excel->setActiveSheetIndex(0);

$data=array();
//行イテレータ取得
foreach($sheet->getRowIterator() as $row)
{
    $tmp=array();
    //列イテレータ取得
    foreach($row->getCellIterator() as $cell)
    {
        //セルの値取得
        $tmp[]=$cell->getValue();
    }
    $data[]=$tmp;
}

//整形して出力
echo '<pre><code>';
var_dump($data);
echo '</code></pre>';

出力結果はこんな感じになる。
array(3) {
  [0]=>
  array(3) {
    [0]=>
    float(1)
    [1]=>
    float(2)
    [2]=>
    float(3)
  }
  [1]=>
  array(3) {
    [0]=>
    float(4)
    [1]=>
    float(5)
    [2]=>
    float(6)
  }
  [2]=>
  array(3) {
    [0]=>
    float(7)
    [1]=>
    float(8)
    [2]=>
    float(9)
  }
}

しかし、このままのソースだと例えば

ABC
113
25
378

のような虫食い状態のデータの時に下記のような結果になる。

array(3) {
  [0]=>
  array(2) {
    [0]=>
    float(1)
    [1]=>
    float(3)
  }
  [1]=>
  array(1) {
    [0]=>
    float(5)
  }
  [2]=>
  array(2) {
    [0]=>
    float(7)
    [1]=>
    float(8)
  }
}

上記プログラムだと空の場合は読み飛ばしてしまうため、
配列の添字が詰められてしまう。
データが開いてる時は配列も開けておきたい場合は

//ClassesをおいたパスからPHPExcel.phpをインクルードする
require_once('Classes/PHPExcel.php');
//読み込むExcelのパス
define('EXCEL','data/test.xls');

//.xls形式を読むという設定でクラスと作る
//.xlsx形式を読み込む場合は'Excel5'の部分を'Excel2007'に変える →$reader=PHPExcel_IOFactory::createReader('Excel2007');
$reader=PHPExcel_IOFactory::createReader('Excel5');
//読み込むExcelのパスを指定する
$excel=$reader->load(EXCEL);
//最初のシートを選ぶ
$sheet=$excel->setActiveSheetIndex(0);

$data=array();
//列の最大値を取得
for($i=1;$i<=$sheet->getHighestRow();$i++)
{
    $tmp=array();
    //行の最大値を取得
    //A、B、Cの文字列形式で帰ってくるので数字に変換する
    $max_column=PHPExcel_Cell::columnIndexFromString($sheet->getHighestColumn());
    for($j=0;$j<$max_column;$j++)
    {
        //列のインデックスと、行のインデックスからセルの値を取得
        $tmp[]=$sheet->getCellByColumnAndRow($j,$i)->getValue();
    }
    $data[]=$tmp;
}

//整形して出力
echo '<pre><code>';
var_dump($data);
echo '</code></pre>';

とすると出力結果は

array(3) {
  [0]=>
  array(3) {
    [0]=>
    float(1)
    [1]=>
    NULL
    [2]=>
    float(3)
  }
  [1]=>
  array(3) {
    [0]=>
    NULL
    [1]=>
    float(5)
    [2]=>
    NULL
  }
  [2]=>
  array(3) {
    [0]=>
    float(7)
    [1]=>
    float(8)
    [2]=>
    NULL
  }
}

となる。

次へ