[2022/10/28] PHP PhpSpreadsheet エクセルのワークシートのセルに日付型データの設定と、日付スタイル設定について(PHPToExcel, setFormatCode) (No.288)
[2022/10/27] PHP PhpSpreadsheet エクセルのワークシートの複数セルのスタイル設定について(applyFromArray, duplicateStyle) (No.287)
[2022/10/26] PHP クラス(class)のオーバーライドの使い方について・その4(プロパティ) (No.286)
[2021/07/29] PHP 標準関数その4・文字列の分割(explode)で空文字列を処理して再認識した件について (No.278)
[2020/12/21] PHP PhpSpreadsheet エクセルのワークシートのセルの罫線はスタイルオブジェクトの applyFromArray でも行える (No.252)
-
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
-
今回は小ネタですが、セルに PHP のUNIT-TIMEデータを日付型データとして設定し、日付の書式で表示させる方法について説明したいと思います。■「PHPToExcel」を使ったセルへの日付型データの設定
セルに日付型データを設定するには Date クラスの PHPToExcel メソッドで PHP の日付データ(UNIX-TIME) をエクセルの date/time 値に変換したものを設定します。 PHPToExcel メソッドは static な関数なので Date::PHPToExcel と直接書くことができます。
以下に簡単な例を示します。 [A2] セルに現在時刻を設定し、そのセルの書式スタイルを日付表示の設定で行っています。
<?php // ライブラリ読込 require '../vendor/autoload.php'; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; use PhpOffice\PhpSpreadsheet\Shared\Date; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; // Spreadsheetオブジェクト生成 $objSpreadsheet = new Spreadsheet(); // ワークシートオブジェクト $objSheet = $objSpreadsheet->getActiveSheet(); // セルにシステム時刻(Unix Time)を設定 $objSheet->setCellValue('A2', Date::PHPToExcel(time())); // スタイルオブジェクト取得([A2]セル) $objStyle = $objSheet->getStyle('A2')->getNumberFormat()->setFormatCode('yyyy"年"m"月"d"日";@'); // [test6-a2.xlsx]:Excel2007形式で保存する $objWriter = new Xlsx($objSpreadsheet); $objWriter->save('test6-a2.xlsx'); exit(); ?>
出力されたエクセルファイルを見てみると以下の様になります。[A]列の幅は便宜上広くして表示しました。
PR -
エクセルのワークシートのセルにスタイルを設定する説明は以下の記事で行いましたが、今回は複数セルに対するスタイル設定について説明したいと思います。
PHP PhpSpreadsheet エクセルのワークシートのセルのスタイル設定について
■「applyFromArray」を使ったセルのスタイル設定
ワークシートオブジェクト から取得した スタイルオブジェクト の applyFromArray() メソッドで設定するスタイルを array() で与えることが出来ます。
以下に簡単な例を示します。 [A1:D3] のセル範囲の周りに赤色のボーダーで囲む設定を行っています。
<?php // ライブラリ読込 require '../vendor/autoload.php'; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Style\Style; use PhpOffice\PhpSpreadsheet\Style\Border; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; // Spreadsheetオブジェクト生成 $objSpreadsheet = new Spreadsheet(); // ワークシートオブジェクト $objSheet = $objSpreadsheet->getActiveSheet(); // スタイル設定値array $styleArray = [ 'borders' => [ 'outline' => [ 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THICK, 'color' => ['argb' => 'FFFF0000'], ], ], ]; // [A1:D3]のスタイル設定 $objSheet->getStyle('A1:D3')->applyFromArray($styleArray); // [test6-a0.xlsx]:Excel2007形式で保存する $objWriter = new Xlsx($objSpreadsheet); $objWriter->save('test6-a0.xlsx'); exit(); ?>
出力されたエクセルファイルを見てみると以下の様になります。
■「applyFromArray」と「duplicateStyle」を使ったセルのスタイル設定
上記は スタイルオブジェクト の applyFromArray() メソッドでスタイルを設定する処理でしたが、 指定したセル範囲を一つのセルと考えてのスタイルを設定していました。
今度は、指定したセル範囲の全てのセルに対して同じスタイルを設定する方法を示します。
以下の例は スタイルクラス:Style() を生成しその スタイルオブジェクト に applyFromArray() メソッドでスタイルを設定しておきます。
この スタイルオブジェクト を ワークシートオブジェクト の duplicateStyle() メソッドで指定範囲の各セルへのスタイル設定が一括で行えます。
各セルには「文字フォント」「アライメント(水平位置)」「ボーダー(全周枠)」「書式設定(数値)」「ぬりつぶし(色)」のスタイルを設定します。
<?php // ライブラリ読込 require '../vendor/autoload.php'; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Style\Style; use PhpOffice\PhpSpreadsheet\Style\Alignment; use PhpOffice\PhpSpreadsheet\Style\Border; use PhpOffice\PhpSpreadsheet\Style\Fill; use PhpOffice\PhpSpreadsheet\Style\Font; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; // Spreadsheetオブジェクト生成 $objSpreadsheet = new Spreadsheet(); // ワークシートオブジェクト $objSheet = $objSpreadsheet->getActiveSheet(); // 配列データ $arrData = array( array(100, -1100, 12000, 130000), // マイナス値もいれる array(200, 2100, 22000, -230000), array(300, 3100, -32000, 330000), ); // [A1:D3]セルに配列データ設定 $objSheet->fromArray( $arrData, // 配列データ NULL, // 配列データの中でセルに設定しないNULL値の指定 'A1' // 左上座標(デフォルト:"A1") ); // 全部のスタイルの定義 $objStyle = new Style(); $objStyle->applyFromArray( array( 'font' => array( 'name' => 'Arial', 'bold' => TRUE, 'italic' => FALSE, 'underline' => Font::UNDERLINE_DOUBLE, 'strikethrough' => FALSE, ), 'alignment' => array( 'horizontal' => Alignment::HORIZONTAL_RIGHT ), 'borders' => array( 'top' => array( 'borderStyle' => Border::BORDER_THIN, ), 'bottom' => array( 'borderStyle' => Border::BORDER_THIN, ), 'left' => array( 'borderStyle' => Border::BORDER_THIN, ), 'right' => array( 'borderStyle' => Border::BORDER_THIN, ) ), 'numberFormat' => array( 'formatCode' => '#,##0;[Red]#,##0', // マイナスは赤色 ), 'fill' => array( 'fillType' => Fill::FILL_SOLID, 'startColor' => array( 'argb' => '00FFFF80' ) ) ) ); // セル範囲指定でのスタイル設定 $objSheet->duplicateStyle($objStyle, 'A1:D3'); // [test6-a1.xlsx]:Excel2007形式で保存する $objWriter = new Xlsx($objSpreadsheet); $objWriter->save('test6-a1.xlsx'); exit(); ?>
出力されたエクセルファイルを見てみると以下の様になります。
-
以下の記事で、クラス(class)の使い方について説明しましたが、その時は親クラスのメソッドを、 子クラスで同じメソッド名で宣言することでオーバーライドができることを記しました。
⇒PHP クラス(class)の使い方について
クラスは関数だけではなく、プロパティ(変数と言ってもいいと思います)もオーバーライドが使えます。
親クラスで public で宣言されたプロパティを、子クラスで同じ名前で public で宣言すればオーバーライドしたことになります。 取敢えず、簡単な例を以下に示します。<?php // 継承の基となる親クラス class cParent { // プロパティ public $param; // コンストラクタ public function __construct() { $this->param = "cParent_param"; } // テスト関数 public function func() { echo $this->param."
\n"; } } // [cParent]から派生した子クラス class cChild extends cParent { // オーバーライド・プロパティ public $param; // コンストラクタ public function __construct() { $this->param = "cChild_param"; } } // [cParent]クラスの生成 $insParent = new cParent(); // テスト関数の実行 $insParent->func(); // [cChild]クラスの生成 $insChild = new cChild(); // テスト関数の実行 $insChild->func(); ?>
親クラスに「param」のプロパティを宣言し、コンストラクタの中でそのプロパティを初期化しています。 また、関数「func()」の中ではそのプロパティを出力しています。
そこで、この親クラスから派生した子クラスに「param」というプロパティをオーバーライド宣言しています。
これらのクラスを実行してするため、親クラスを生成し「func()」を実行し、子クラスを生成し「func()」を実行しています。
これを実行するとブラウザに以下の様に表示されます。cParent_param cChild_param
子クラスを生成し「func()」を実行した場合は、親クラスの「func()」が実行され、 「func()」の中で参照されている「param」は子クラスのプロパティとなります。 オーバーライドの結果が出ていると思います。
このことから、子クラスで宣言されたプロパティを使って、親クラスの関数に違った動作を行わせることが出来ると思います。
-
文字列の分割を行う関数の説明は以下の記事で行いましたが、今回は少し気になった件に付いて記します。
⇒PHP 標準関数その1・文字列の分割・結合を行う関数(explode, implode)について
■一般的なexplode関数の使い方
先ずは explode 関数の一般的な使い方ですが、以下の様なソースを作成します。
<?php /* f1-explode.php */ // 分割する文字列 $str = "東京,名古屋,京都,大阪"; // 分割処理 $arr = explode(",", $str); // 配列の内容表示 echo "<pre>"; var_dump($arr); echo "</pre>"; ?>
これをブラウザで実行すると以下の表示になります。
array(4) { [0]=> string(6) "東京" [1]=> string(9) "名古屋" [2]=> string(6) "京都" [3]=> string(6) "大阪" }
変数「$arr」に指標「0」から順にカンマで分割された文字列が設定されています。
これ自体は特に問題は無いのですが explode 関数に渡す文字列が null または 空文字列(長さが 0 の文字列) の場合は どうなるのでしょうか。
■nullをexplode関数で分解処理
それでは早速やってみます。上記のソースの文字列を null に変えます。
<?php $str = null; // 分割処理 $arr = explode(",", $str); // 配列の内容表示 echo "<pre>"; var_dump($arr); echo "</pre>"; ?>
これをWindowsコマンドプロンプトで実行すると以下の表示になります。
array(1) { [0]=> string(0) "" }
KEYが「0」で内容が空文字列の要素が「1件」の配列が返されます。
なお null の部分を空文字列に変更しても同様の結果となります。<?php $str = ""; // 分割処理 $arr = explode(",", $str); // 配列の内容表示 echo "<pre>"; var_dump($arr); echo "</pre>"; ?>
この結果から文字列に何かのデータが設定されていて、それを分解して使う場合、 null または 空文字列 だと1件の文字列が在ることになってしまいます。
もし、それでもいいのならば問題にはならないのですが、 不都合であれば、分解処理の前に対象文字列を null または 空文字列 の判定を行って 別処理を行う必要があります。
-
セルの罫線を設定する処理で以下の様なスクリプトで行っていましたが、少し処理が冗長な感じがします。<?php // ライブラリ読込 require '../vendor/autoload.php'; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Style; use PhpOffice\PhpSpreadsheet\Style\Border; use PhpOffice\PhpSpreadsheet\Style\Color; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; // Spreadsheetオブジェクト生成 $objSpreadsheet = new Spreadsheet(); // ワークシートオブジェクト $objSheet = $objSpreadsheet->getActiveSheet(); // スタイルオブジェクト取得([B2:D4]セル) $objStyle = $objSheet->getStyle('B2:D4'); // ボーダーオブジェクト取得([B2]セル) $objBorders = $objStyle->getBorders(); // ボーダー全て(Top, Bottom, Left, Right)を「細い線:BORDER_THICK」に設定 $objBorders->getTop()->setBorderStyle(Border::BORDER_THICK); $objBorders->getTop()->setColor(new Color(Color::COLOR_RED)); // 例として色設定 $objBorders->getBottom()->setBorderStyle(Border::BORDER_THICK); $objBorders->getLeft()->setBorderStyle(Border::BORDER_THICK); $objBorders->getRight()->setBorderStyle(Border::BORDER_THICK); // [test12-1.xlsx]:Excel2007形式で保存する $objWriter = new Xlsx($objSpreadsheet); $objWriter->save('test12-1.xlsx'); exit(); ?>
出力されたエクセルファイルを見てみると以下の様になります。
この冗長な処理の部分を、スタイルオブジェクトの applyFromArray() メソッドを使用することで 一括で処理できる様です。
このメソッドの引数は配列データですが、以下の様な指定をします。
PHPExcel ライブラリと較べて少し変わった部分があります。 'border' という配列KEYが 'borderStyle' に変わったので注意が必要です。array( 'borders' => array( 'top' => array( 'borderStyle' => Border::BORDER_THIN // ボーダーの定数 ,['color' => array( 'rgb' => 'xxxxxx' ) ] // 色は未指定はデフォルト(黒) ), 'bottom' => array( 'borderStyle' => Border::BORDER_THIN ,['color' => array( 'rgb' => 'xxxxxx' ) ] ), 'left' => array( 'borderStyle' => Border::BORDER_THIN ,['color' => array( 'rgb' => 'xxxxxx' ) ] ), 'right' => array( 'borderStyle' => Border::BORDER_THIN ,['color' => array( 'rgb' => 'xxxxxx' ) ] ), ) )
それではこのメソッドを使って罫線を出力してみます。
<?php // ライブラリ読込 require '../vendor/autoload.php'; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Style; use PhpOffice\PhpSpreadsheet\Style\Border; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; // Spreadsheetオブジェクト生成 $objSpreadsheet = new Spreadsheet(); // ワークシートオブジェクト $objSheet = $objSpreadsheet->getActiveSheet(); // スタイルオブジェクト取得([B2:D4]セル) $objStyle = $objSheet->getStyle('B2:D4'); // $arrStyle = array( 'borders' => array( 'top' => array( 'borderStyle' => Border::BORDER_THICK, 'color' => array( 'rgb' => 'ff0000' ) ), 'right' => array( 'borderStyle' => Border::BORDER_THICK, 'color' => array( 'rgb' => '00ff00' ) ), 'left' => array( 'borderStyle' => Border::BORDER_THICK, 'color' => array( 'rgb' => '0000ff' ) ), 'bottom' => array( 'borderStyle' => Border::BORDER_THICK, 'color' => array( 'rgb' => 'ff00ff' ) ) ) ); // セルの罫線スタイル設定 $objStyle->applyFromArray($arrStyle); // [test12-2.xlsx]:Excel2007形式で保存する $objWriter = new Xlsx($objSpreadsheet); $objWriter->save('test12-2.xlsx'); exit(); ?>
出力されたエクセルファイルを見てみると以下の様になります。
尚 applyFromArray() の配列引数の中で、'top' 'right' 'left' 'bottom' が同一の指定であれば 'allBorders' と指定することもできます。
PHPExcel ライブラリでは 'allborders' という配列KEYだったのですが 'allBorders' に変わったので注意が必要です。 (単語の意味が変わるところで大文字化?)<?php // ライブラリ読込 require '../vendor/autoload.php'; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Style; use PhpOffice\PhpSpreadsheet\Style\Border; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; // Spreadsheetオブジェクト生成 $objSpreadsheet = new Spreadsheet(); // ワークシートオブジェクト $objSheet = $objSpreadsheet->getActiveSheet(); // スタイルオブジェクト取得([B2:D4]セル) $objStyle = $objSheet->getStyle('B2:D4'); // $arrStyle = array( 'borders' => array( 'allBorders' => array( 'borderStyle' => Border::BORDER_THICK, 'color' => array( 'rgb' => 'ff0000' ) ) ) ); // セルの罫線スタイル設定 $objStyle->applyFromArray($arrStyle); // [test12-3.xlsx]:Excel2007形式で保存する $objWriter = new Xlsx($objSpreadsheet); $objWriter->save('test12-3.xlsx'); exit(); exit(); ?>
出力されたエクセルファイルを見てみると以下の様になります。指定セルが全て同じ罫線の状態になります。