QUOIT Blog

PHPExcelのラッパークラスを書き変えてみた

この記事は6年以上前の記事です。情報が古い場合がありますのでお気を付け下さい。

以前書いた「今度はPHPExcelを使ってみた」という記事の中で紹介した「PHPExcelで.xls形式のファイルを扱う | バシャログ。」というエントリで、PHPExcelのラッパークラスの例が書いてあります。
その例を元にラッパークラスを改変して使ってみているのですが、ちょっと自分としては使いづらいところがあったので手を加えてみました。

前提として、エクセルの読み込みのみを行なうクラスを作成することとします。
書き込みも必要な場合は元記事から適宜書き換えるといいです。自分で^q^

class ExcelObj {
    
	function __construct(){
		require_once(CORE_DIR.'Util/Excel/Classes/PHPExcel.php');
		require_once(CORE_DIR.'Util/Excel/Classes/PHPExcel/IOFactory.php');
	}

	function readXls($filepath, $sheetIndex = null){

		$objReader = PHPExcel_IOFactory::createReader('Excel5');
		$objPHPExcel = $objReader->load($filepath);

		$sheets = array();
		$data = array();

		if(is_null($sheetIndex)){
			$sheets = $objPHPExcel->getAllSheets();
		}elseif(is_array($sheetIndex)){
			foreach($sheetIndex as $idx){
				$sheets[$idx] = $objPHPExcel->getSheet($idx);
			}
		}elseif(is_int($sheetIndex)){
			$sheets[$sheetIndex]=$objPHPExcel->getSheet($sheetIndex);
		}

		if(empty($sheets)) return $data;

		foreach ($sheets as $s => $v) {# sheet
			# Sheet name
			$sheetTitle = $v->getTitle();
			$data[$sheetTitle]=array();

			# get max row & col
			$rowMax = $v->getHighestRow();

			$colMaxStr = $v->getHighestColumn();
			$colMax = PHPExcel_Cell::columnIndexFromString($colMaxStr);

			# get text data par 1 cell
			$sheetData = array();
			for($r=1; $r<=$rowMax; $r++){# row
				for($c=0; $c<=$colMax; $c++){# col
					$objCell = $v->getCellByColumnAndRow($c, $r);
					$sheetData[$r][$c]= $this->_getText($objCell);
				}
			}
			$data[$sheetTitle] = $sheetData;
		}
		return $data;
	}
	function _getText($objCell = null){
		if(is_null($objCell)) return false;

		$txtCell = "";
		$valueCell = $objCell->getValue();

		if(is_object($valueCell)){
			$txtParts = array();
			foreach($valueCell->getRichTextElements() as $v){
				$txtParts[] = $v->getText();
			}
			$txtCell = implode("", $txtParts);
		}else{
			if(!empty($valueCell)) $txtCell = $valueCell;
		}

		return $txtCell;
	}
}

まさかこれをコピペして動かねえええ!という人はいないと思いますが、定数「CORE_DIR」は適宜書き換えてくださいねw

変更点は以下。

1) 省略できそうな変数を省略した
  →正直どうでもいい

2) メソッドの引数を減らした
  →シートの一部分を取得することはなさそうだったので

3) 取得した後の連想配列を以下のように変更
【変更前】

array(3) {
  [0]=>
  array(2) {
    ["title"]=>
    string(4) "hoge"
    ["data"]=>
    array(10) {
      [1]=>
      array(10) {
        [0]=>
        string(6) "name"
        [1]=>
        string(4) "namef"
        ...(以下略

【変更後】

array(3) {
  ["hoge"]=>
  array(10) {
    [1]=>
      array(10) {
        [0]=>
        string(6) "name"
        [1]=>
        string(4) "namef"
        ...(以下略

何が変わったかというと、以前の形だとシートのキーは数値、シート名が「title」というキーで入ってきてたのを、そもそもシートのキーが名前でいいじゃん、と。

何故こうしたかというと、変更前のコードは返ってきたデータをforeachとかで回す時に、元々のエクセルデータのシートの順番に依存してしまうという弱点がある。
せっかく取得したのに、何番目にどのシートのデータがあるか分からない。

変更後のデータなら、シート名がキーになっているので、キーを指定すれば目的のデータが取得できるというわけだ。

シート名が日本語だった場合も、文字コードに気をつければ読み込めるはず。
(一応僕の環境ではUTF8に統一して読み込めました)

以上です。

3 comments for “PHPExcelのラッパークラスを書き変えてみた

  1. 2011年2月3日 at 9:42 PM

    >> せっかく取得したのに、何番目にどのシートのデータがあるか分からない。
    The latest SVN code for PHPExcel provides a listWorksheetNames() method for the Reader classes that can be used to retrieve an ordered array of the worksheet names…. before reading the workbook itself, and can be useful when used with the setLoadSheetsOnly() method of the Writer

  2. yakumo
    2011年2月3日 at 9:52 PM

    Dear Mark
    Thanks for useful information! This is a very nice method!
    I didn’t know the latest code..I’ll check it! :)