PHP からエクセルフォーマットのファイルを扱えるようにするための PHPExcel を使ってみました。備忘録としてその手順を記録しておきます。

まず、PHPExcel の最新版をダウンロードサイトから選択してダウンロードします。2016/Jan/10 時点での最新版のバージョンは 1.8.0 でした。以下、このバージョンを使う前提で紹介します:
2016011001


ダウンロードしたファイル(PHPExcel_1.8.0_doc.zip)を適当なフォルダに展開します。ファイル内にはドキュメントなども含まれていますが、実際に PHP から利用する際に必要なファイルは全て Classes フォルダ内にあるので、実環境ではこのフォルダ以下のファイルだけがあれば一応動きます:
2016011002


次に実際にアクセスする先のエクセルファイルを用意します。今回は Excel97-2003 フォーマット(拡張子 .xls)の、このようなブックファイル(Book1.xls)を用意しました。同じもので良ければこちらこちらからダウンロードしてください。なお PHPExcel 自体は Excel 2007 フォーマット(拡張子 .xlsx)を扱うことも可能です。今回はどちらのファイルにも対応させてみます:
2016011003


なお、今回用意したブックファイルは上記のようにシートが3枚あり、そのうちの1枚目のシートに表が作られています。また表内では日本語が使われていたり、セルの色属性や計算式などの機能も使われています。

ではこの Book1.xls を PHPExcel で読み込んでみましょう。以下の様な PHP ファイルを用意します:
<?php
//. PHPExcel ライブラリの読み込み
include_once( dirname( __FILE__ ) . '/Classes/PHPExcel.php' );
include_once( dirname( __FILE__ ) . '/Classes/PHPExcel/IOFactory.php' );

//. endsWith 関数の定義
function endsWith( $str, $suffix ){
  $len = strlen( $suffix );
  return $len == 0 || substr( $str, strlen( $str ) - $len, $len ) === $suffix;
}

//. 対象ファイル名
$excelfilename = 'Book1.xls';
$excelfilepath = dirname( __FILE__ ) . '/' . $excelfilename;

//. ファイル拡張子によってリーダーインスタンスを変える
$reader = null;
if( endsWith( $excelfilename, 'xls' ) ){
  $reader = PHPExcel_IOFactory::createReader( 'Excel5' );
}else if( endsWith( $excelfilename, 'xlsx' ) ){
  $reader = PHPExcel_IOFactory::createReader( 'Excel2007' );
}

if( $reader ){
  //. エクセルファイルを読み込む
  $excel = $reader->load( $excelfilepath );
  echo $excel->getSheetCount(); //. シート数を取得
  echo "<br/>";

  //. Formulaを計算する指定でアクティブシートの内容を取得する
  $obj1 = $excel->getActiveSheet()->toArray( null, true, true, true );
  var_dump($obj1);
  echo "<br/>";

  //. Formulaを計算しない(式を式のままにする)指定でアクティブシートの内容を取得する
  $obj2 = $excel->getActiveSheet()->toArray( null, false, true, true );
  var_dump($obj2);
  echo "<br/>";
}else{
  echo "No reader.";
}
?>

そして、この PHP ファイルを HTTP のドキュメントルート以下に用意し、更に同じフォルダにエクセルファイル(Book1.xls)と PHPExcel ライブラリの Classes フォルダを用意した上で、この PHP ファイルにブラウザからアクセスするとこんな結果になりました:
2016011004


この結果を見やすく整形するとこんな感じ↓です:
3

array(6) {
 [1]=> array(4) {
  ["A"]=> string(1) "A"
  ["B"]=> string(1) "B"
  ["C"]=> string(3) "計"
  ["D"]=> string(6) "平均"
 }
 [2]=> array(4) {
  ["A"]=> float(1)
  ["B"]=> float(20)
  ["C"]=> float(21)
  ["D"]=> float(10.5)
 }
 [3]=> array(4) {
  ["A"]=> float(3)
  ["B"]=> float(31)
  ["C"]=> float(34)
  ["D"]=> float(17)
 }
 [4]=> array(4) {
  ["A"]=> float(2)
  ["B"]=> float(44)
  ["C"]=> float(46)
  ["D"]=> float(23)
 }
 [5]=> array(4) {
  ["A"]=> float(5)
  ["B"]=> float(2)
  ["C"]=> float(7)
  ["D"]=> float(3.5)
 }
 [6]=> array(4) {
  ["A"]=> float(11)
  ["B"]=> float(97)
  ["C"]=> float(108)
  ["D"]=> float(54)
 } 
} 

array(6) {
 [1]=> array(4) {
  ["A"]=> string(1) "A"
  ["B"]=> string(1) "B"
  ["C"]=> string(3) "計"
  ["D"]=> string(6) "平均"
 }
 [2]=> array(4) {
  ["A"]=> float(1)
  ["B"]=> float(20)
  ["C"]=> string(6) "=A2+B2"
  ["D"]=> string(5) "=C2/2"
 }
 [3]=> array(4) {
  ["A"]=> float(3)
  ["B"]=> float(31)
  ["C"]=> string(6) "=A3+B3"
  ["D"]=> string(5) "=C3/2"
 }
 [4]=> array(4) {
  ["A"]=> float(2)
  ["B"]=> float(44)
  ["C"]=> string(6) "=A4+B4"
  ["D"]=> string(5) "=C4/2"
 }
 [5]=> array(4) {
  ["A"]=> float(5)
  ["B"]=> float(2)
  ["C"]=> string(6) "=A5+B5"
  ["D"]=> string(5) "=C5/2"
 }
 [6]=> array(4) {
  ["A"]=> string(11) "=SUM(A2:A5)"
  ["B"]=> string(11) "=SUM(B2:B5)"
  ["C"]=> string(11) "=SUM(C2:C5)"
  ["D"]=> string(5) "=C6/2"
 } 
} 

1行目の「3」はシート数なので、これは正しく取得できていることがわかります。

2行目から始まるブロックは1枚目のシートの中身を「Formula を計算して」取得したものです。つまり計算式が定義されていた場合はその計算結果が取得できていることになるのですが、例えば C2 セルは A2 と B2 の和(=A2+B2)が定義されていましたが、正しく計算結果が取得できていることがわかります。

またその下には1枚目のシートの中身を「Formula をそのまま」取得したものが出力されています。C2 セルの内容が "=A2+B2" となっていることが確認でき、これも期待通りに動いていたことが確認できました。


PHPExcel はファイルの読み込みだけでなく、Excel ファイルとして出力することも出来て、(CSV や TSV ではない)エクセル連携をする際に便利に使えそうなライブラリです。