-
今回は以下の記事で紹介したチャートに対して、各要素の色を設定する方法について説明します。 基本的にはエクセルで行うのと同じなのですが、系列ラベルの色を変更することで、チャートの各系列の領域の色設定が行えます。
PHP PhpSpreadsheet\Chart エクセルシート上に複数のチャートで異なるタイプのグラフ(Bar Chart:棒グラフ、Line Chart:線グラフ、Area Chart:面グラフ)を作成する方法について
しかし、上記の記事の中の「Line Chart:線グラフ」だけ残念ながら、線の色設定ができませんでした。
そのため、これを除いた3個のチャート「Bar Chart:棒グラフ」「Bar Chart:棒グラフ(積み上げ)」「Area Chart:面グラフ」の塗りつぶしの色設定について記します。
エクセルでは「Line Chart:線グラフ」でも線の色指定はできるのですが、このライブラリではできない様です。(私の調べ方が悪いのかもしれませんが...)
ここで、「系列ラベル」データの生成について説明します。
グラフの「系列ラベル」を PhpSpreadsheet\DataSeries クラスで生成しますが、 PhpSpreadsheet\Chart\DataSeries のクラス生成の引数の中で重要な「ラベル」の配列の要素のクラスである PhpSpreadsheet\Chart\DataSeriesValues のクラス生成の引数は以下の様に定義されています。PhpSpreadsheet\DataSeriesValues __construct( $dataType = self::DATASERIES_TYPE_NUMBER, // データ型の定数 $dataSource = null, // シリーズ(系列)データの位置指定 $formatCode = null, // フォーマットコード $pointCount = 0, // シリーズ(系列)データの個数 $dataValues = array(), // シリーズ(系列)データを直接指定 $marker = null, // ポイントマーカーの指定(文字列) $fillColor = null // 塗りつぶし色設定 )
最後の引数の $fillColor が PhpSpreadsheet\DataSeries クラスにおける色設定となります。
ここに今まで何も設定しなかったのでデフォルトの色がチャートに表示されましたが、 色コードを文字列で設定してやれば、各系列の色が変更できます。
色コードは「FF00AA」の様に16進数の表記で、左の2桁からRGBの指定を行います。
実際のソースは以下の様になります。<?php // ライブラリ読込 require '../vendor/autoload.php'; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Chart\Chart; use PhpOffice\PhpSpreadsheet\Chart\DataSeries; use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues; use PhpOffice\PhpSpreadsheet\Chart\PlotArea; use PhpOffice\PhpSpreadsheet\Chart\Title; use PhpOffice\PhpSpreadsheet\Chart\Legend; use PhpOffice\PhpSpreadsheet\IOFactory; // Spreadsheetオブジェクト生成 $objSpreadsheet = new Spreadsheet(); // ワークシートオブジェクト取得 $objWorksheet = $objSpreadsheet->getActiveSheet(); // チャート用テストデータ生成 $objWorksheet->fromArray( array( array('売上', '商品1', '商品2', '商品3'), array( 2016, 12, 18, 15), array( 2017, 15, 19, 10), array( 2018, 21, 23, 20), array( 2019, 18, 14, 12), array( 2020, 20, 21, 23), ) ); // 系列ラベルの指定(色指定) $arrDataSeriesLabels = array( new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING,'Worksheet!$B$1',NULL,1,[],NULL,"ff0000"), //商品1 new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING,'Worksheet!$C$1',NULL,1,[],NULL,"00ff00"), //商品2 new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING,'Worksheet!$D$1',NULL,1,[],NULL,"0000ff"), //商品3 ); // X軸ラベルの指定 $arrCategorysDataSeries = array( new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$6', NULL, 5), //2016 to 2020 ); // 描画データの指定 $arrDataSeriesValues = array( new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$6', NULL, 5), //商品1 new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$6', NULL, 5), //商品2 new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$6', NULL, 5), //商品3 ); //===================== // Bar Chart //===================== // チャート・データシリーズの生成 $objSeries1 = new DataSeries( DataSeries::TYPE_BARCHART, // plotType DataSeries::GROUPING_STANDARD, // plotGrouping range(0, count($arrDataSeriesValues) - 1), // plotOrder $arrDataSeriesLabels, // plotLabel $arrCategorysDataSeries, // plotCategory $arrDataSeriesValues // plotValues ); // プロットエリアにチャート・データシリーズに設定 $objPlotArea1 = new PlotArea(NULL, array($objSeries1)); // レジェンド生成(各折れ線の説明を行う) $objLegend1 = new Legend(Legend::POSITION_TOPRIGHT, NULL, false); // チャート・タイトル生成 $objTitle1 = new Title('売上データ:Bar Chart'); // チャート生成 $objChart1 = new Chart( 'chart1', // name $objTitle1, // title $objLegend1, // legend $objPlotArea1, // plotArea TRUE, // plotVisibleOnly 0, // displayBlanksAs NULL, // xAxisLabel NULL // yAxisLabel ); // ワークシート内のチャート位置設定 $objChart1->setTopLeftPosition('A8'); // 左上 $objChart1->setBottomRightPosition('G20'); // 右下 // ワークシートにチャート追加 $objWorksheet->addChart($objChart1); //===================== // Bar Chart:STACKED //===================== // チャート・データシリーズの生成 $objSeries2 = new DataSeries( DataSeries::TYPE_BARCHART, // plotType DataSeries::GROUPING_PERCENT_STACKED, // plotGrouping range(0, count($arrDataSeriesValues) - 1), // plotOrder $arrDataSeriesLabels, // plotLabel $arrCategorysDataSeries, // plotCategory $arrDataSeriesValues // plotValues ); // プロットエリアにチャート・データシリーズに設定 $objPlotArea2 = new PlotArea(NULL, array($objSeries2)); // レジェンド生成(各折れ線の説明を行う) $objLegend2 = new Legend(Legend::POSITION_TOPRIGHT, NULL, false); // チャート・タイトル生成 $objTitle2 = new Title('売上データ:Bar Chart:STACKED'); // チャート生成 $objChart2 = new Chart( 'chart2', // name $objTitle2, // title $objLegend2, // legend $objPlotArea2, // plotArea TRUE, // plotVisibleOnly 0, // displayBlanksAs NULL, // xAxisLabel NULL // yAxisLabel ); // ワークシート内のチャート位置設定 $objChart2->setTopLeftPosition('H8'); // 左上 $objChart2->setBottomRightPosition('N20'); // 右下 // ワークシートにチャート追加 $objWorksheet->addChart($objChart2); /* //===================== // Line Chart //===================== // チャート・データシリーズの生成 $objSeries3 = new DataSeries( DataSeries::TYPE_LINECHART, // plotType DataSeries::GROUPING_STANDARD, // plotGrouping range(0, count($arrDataSeriesValues) - 1), // plotOrder $arrDataSeriesLabels, // plotLabel $arrCategorysDataSeries, // plotCategory $arrDataSeriesValues // plotValues ); // プロットエリアにチャート・データシリーズに設定 $objPlotArea3 = new PlotArea(NULL, array($objSeries3)); // レジェンド生成(各折れ線の説明を行う) $objLegend3 = new Legend(Legend::POSITION_TOPRIGHT, NULL, false); // チャート・タイトル生成 $objTitle3 = new Title('売上データ:Line Chart'); // チャート生成 $objChart3 = new Chart( 'chart3', // name $objTitle3, // title $objLegend3, // legend $objPlotArea3, // plotArea TRUE, // plotVisibleOnly 0, // displayBlanksAs NULL, // xAxisLabel NULL // yAxisLabel ); // ワークシート内のチャート位置設定 $objChart3->setTopLeftPosition('A21'); // 左上 $objChart3->setBottomRightPosition('G33'); // 右下 // ワークシートにチャート追加 $objWorksheet->addChart($objChart3); */ //===================== // Area Chart //===================== // チャート・データシリーズの生成 $objSeries4 = new DataSeries( DataSeries::TYPE_AREACHART, // plotType DataSeries::GROUPING_PERCENT_STACKED, // plotGrouping range(0, count($arrDataSeriesValues) - 1), // plotOrder $arrDataSeriesLabels, // plotLabel $arrCategorysDataSeries, // plotCategory $arrDataSeriesValues // plotValues ); // プロットエリアにチャート・データシリーズに設定 $objPlotArea4 = new PlotArea(NULL, array($objSeries4)); // レジェンド生成(各折れ線の説明を行う) $objLegend4 = new Legend(Legend::POSITION_TOPRIGHT, NULL, false); // チャート・タイトル生成 $objTitle4 = new Title('売上データ:Area Chart'); // チャート生成 $objChart4 = new Chart( 'chart4', // name $objTitle4, // title $objLegend4, // legend $objPlotArea4, // plotArea TRUE, // plotVisibleOnly 0, // displayBlanksAs NULL, // xAxisLabel NULL // yAxisLabel ); // ワークシート内のチャート位置設定 $objChart4->setTopLeftPosition('H21'); // 左上 $objChart4->setBottomRightPosition('N33'); // 右下 // ワークシートにチャート追加 $objWorksheet->addChart($objChart4); // [test-g-5-1.xlsx]:Excel2007形式で保存する $objWriter = IOFactory::createWriter($objSpreadsheet, 'Xlsx'); $objWriter->setIncludeCharts(TRUE); $objWriter->save('test-g-5-1c.xlsx'); exit(); ?>出力されたエクセルファイルを見てみると以下の様になります。
以前の色指定が無い場合は、以下の様にデフォルトの色が設定されています。
PR -
今回はPHPのプログラムをWindowsでのバッチ処理で実行する時の、実行結果による制御について説明します。
通常、PHPのプログラムを途中終了させるには exit() 関数を用います。この関数ですが、PHPの公式サイトによれば以下の様に定義されています。// exitの引数が文字列の場合 exit ([ string $status ] ) : void // exitの引数が数値の場合 exit ( int $status ) : void
【PHP公式マニュアルより】 status が文字列の場合は、この関数は終了直前に status を表示します。 status が int の場合は その値が終了ステータスとして使われ、表示はされません。 終了ステータスは 0 から 254 までの値でなければなりません。 終了ステータス 255 は PHP に予約されており、使用してはいけません。 ステータス 0 は、 プログラムを正常終了させる際に使用します。
普通、終了させる場合には exit() と引数が無い状態で使いますが exit(0) とか exit(1) とすることで、 PHPプログラムの終了ステータスを呼出し元に返せる様です。■exit() の使用例
コマンドプロンプトでのプログラムの実行を想定し引数が指定されていれば正常とし、未指定であればエラーとするプログラムを以下に示します。 $argv 変数のインデックス「1」が宣言されていれば正常を表示し exit(0) を行い、未宣言であればエラーを表示し exit(1) を行います。
<?php // ソースファイル[exit1.php] if (isset($argv[1]) == true) { // 引数$argv[1]が指定された場合、正常終了 echo mb_convert_encoding("正常終了", "SJIS", "UTF-8"); exit(0); } else { // 引数$argv[1]が未指定の場合、エラー終了 echo mb_convert_encoding("エラー終了", "SJIS", "UTF-8"); exit(1); } ?>
私の環境ではWindowsの xampp でPHPを導入し、DOSのコマンドプロンプトからの実行を行っています。 始めの実行は引数無しで行い、「エラー終了」が表示されます。その後、引数を指定した実行で「正常終了」が表示されます。
C:\>C:\xampp\php\php.exe C:\xampp\htdocs\_test\exit1.php エラー終了 C:\>C:\xampp\php\php.exe C:\xampp\htdocs\_test\exit1.php 111 正常終了 C:\>
このままでは exit() で返される値が分からないので、バッチファイルでプログラムを起動する様にします。
■バッチ での使用例
それでは上記のプログラムを表示部分を省いて終了コードのみを返す様にします。(ファイル名を「exit2.php」に変更)
<?php // ソースファイル[exit2.php] if (isset($argv[1]) == true) { // 引数$argv[1]が指定された場合、正常終了 exit(0); } else { // 引数$argv[1]が未指定の場合、エラー終了 exit(1); } ?>これをバッチで実行するファイルを以下に示します。(ファイル名を「exit1.bat」とする)
C:\xampp\php\php.exe C:\xampp\htdocs\_test\exit2.php 111 @echo off if %errorlevel% == 0 ( echo "正常" ) else ( echo "エラー" ) @echo on C:\xampp\php\php.exe C:\xampp\htdocs\_test\exit2.php @echo off if %errorlevel% == 0 ( echo "正常" ) else ( echo "エラー" )
バッチでは errorlevel 変数にプログラムの終了コードが返されますので、その値を判定し処理を制御します。
バッチファイルの実行は以下の様になります。(フォルダを「C:\xampp\htdocs\_test」に移動して実行)C:\xampp\htdocs\_test>exit1.bat C:\xampp\htdocs\_test>C:\xampp\php\php.exe C:\xampp\htdocs\_test\exit2.php 111 "正常" C:\xampp\htdocs\_test>C:\xampp\php\php.exe C:\xampp\htdocs\_test\exit2.php "エラー" C:\xampp\htdocs\_test>
PHPプログラムの中でいろんなレベルの異常終了が在ると思いますので、それぞれの終了コードを決めてバッチ側で各種の処理を行うことが可能になります。
■バッチ に関連してプログラムの CLI 及び ブラウザ 実行について
上記まではPHPスクリプトのコマンドラインでの実行、つまり CLI での実行を行いました。 (CLI とは Command Line Interface 略称なのでコマンドライン実行のことなのですが)
プログラムが CLI からの実行なのかそれとも ブラウザ からの実行なのかで処理を分けたい場合があると思います。
そのためどこからの呼出なのかを判定できる関数として php_sapi_name() があります。
php_sapi_name() はウェブサーバーと PHP の間のインターフェイスの型を返します。
("apache", "apache2handler", "cgi-fcgi", "cli", "cli-server" ,...)
そこで何かの表示を行う場合、この関数の返す値により、コマンドライン実行であれば表示文字列を「Shift-JIS」変換し、そうでなければそのまま出力する様にします。<?php // ソースファイル[exit3.php] (ソースの文字コードは「UTF-8」で登録) $str = "出力する文字列例です。"."\n"; if (php_sapi_name() == "cli") { // コマンドライン実行の場合 Shift-JIS変換 $str mb_convert_encoding($str, "SJIS", "UTF-8"); } echo $str; ?>これをコマンドライン実行すると以下の様になります。
C:\xampp\htdocs\_test>C:\xampp\php\php.exe C:\xampp\htdocs\_test\exit3.php 出力する文字列例です。 C:\xampp\htdocs\_test>
尚、ブラウザで実行させても以下の表示になります。
出力する文字列例です。
-
今回はPHPのプログラムではそこまで使用頻度が多くは無いのですが、コマンドラインからPHPプログラムを実行する時に 指定された 引数 を取得する方法について説明したいと思います。
プログラムの引数を取得するにはPHPが設定した $argv という配列変数を参照します。
$argv と対になる変数として $argc がありますが、これは $argv の配列の個数が入っています。
(C言語を使ったことがれば、すぐに分かると思いますが、機能的にはほぼ同じものと考えられます。 $argc は $argv の count() を取れば分かるのですが…)■$argv の使用例
プログラムの中では $argv 変数を直接参照すればよく、以下のソースは var_dump により内容を表示させています。 取敢えず $argc 変数も表示しています。
<?php // $argvの内容表示 var_dump($argv); // $argcの内容表示 var_dump($argc); ?>
私の環境ではWindowsの xampp でPHPを導入し、DOSのコマンドプロンプトからの実行を行っています。 実行結果は以下の様に表示されます。
$argv の先頭のデータ([0]番目)は実行したプログラムのファイル名がフルパスで入っていて、 [1]番目のデータに最初の引数の文字列が、[2]番目のデータに2番目の引数の文字列が入っています。C:\>C:\xampp\php\php.exe C:\xampp\htdocs\_test\argv1.php aaaaaa bbbbbb array(3) { [0]=> string(31) "C:\xampp\htdocs\_test\argv1.php" [1]=> string(6) "aaaaaa" [2]=> string(6) "bbbbbb" } int(3)■$argv の使用例その2
それでは $argv の内容をプログラム的に使用してみます。
以下の例は $argv の内容をそのまま表示する反復処理です。
<?php // $argvの引数部分の内容表示 for ($i = 1; $i <= ($argc - 1); $i++) { echo "{$i}番目のコマンドライン引数:".$argv[$i]."\n"; } ?>これを実行すると以下の様に表示されます。見事に文字化けしています。
それもそのはずで、プログラムソースは UTF-8 で保存されていますが、WindowsのDOSプロンプトで実行しているためです。 Windowsでは Shift-JIS コードで出力しないと正常に表示されません。C:\>C:\xampp\php\php.exe C:\xampp\htdocs\_test\argv2.php aaaaaa bbbbbb 1逡ェ逶ョ縺ョ繧ウ繝槭Φ繝峨Λ繧、繝ウ蠑墓焚・啾aaaaa 2逡ェ逶ョ縺ョ繧ウ繝槭Φ繝峨Λ繧、繝ウ蠑墓焚・喘bbbbb
これを解消するには、表示文字列を Shift-JIS に変換する必要があります。そこで、以下の様になります。<?php // $argvの引数部分の内容表示 for ($i = 1; $i <= ($argc - 1); $i++) { // UTF-8 での文字列 $str = "{$i}番目のコマンドライン引数:".$argv[$i]."\n"; // Shift-JIS に変換して表示 echo mb_convert_encoding($str, "SJIS", "UTF-8"); } ?>これを実行すると以下の様に表示され文字化けは解消されています。
プログラムがコマンドラインからのみの実行ならばこれでもいいのですが、もしブラウザからの実行と、コマンドラインからの実行の 両方に対応するには、すこし細工が必要になってきます。
ブラウザは UTF-8 のソースを実行する為に、C:\>C:\xampp\php\php.exe C:\xampp\htdocs\_test\argv3.php aaaaaa bbbbbb 1番目のコマンドライン引数:aaaaaa 2番目のコマンドライン引数:bbbbbb
尚、この $argv ですがコマンドラインから実行した時のみ存在する変数で、ブラウザからの実行ではエラーになります。http://localhost/_test/argv1.php
上のアドレスをブラウザから指定すると、以下のエラーが表示されます。
Notice: Undefined variable: argv in C:\xampp\htdocs\_test\argv1.php on line 3 NULL Notice: Undefined variable: argc in C:\xampp\htdocs\_test\argv1.php on line 5 NULL
-
今回は1個のチャート上に「Bar Chart:棒グラフ」を描画しますが、その時の軸の値の表示の書式を設定する方法を説明したいと思います。
おおまかな手順としては、軸オブジェクトクラス PHPExcel_Chart_Axis を生成し setAxisNumberProperties メソッドで書式を文字列で設定し、 軸オブジェクトをチャート生成時に軸の設定値に渡します。
元となるソースは以下の記事を引用しています。
⇒PHP PHPExcel_Chart ワークシート上にチャート(Bar Chart:棒グラフ)を作成する方法について
■チャートの軸の値の書式を設定
<?php // ライブラリ読込 require_once './PHPExcel-1.8/Classes/PHPExcel.php'; // PHPExcelオブジェクト作成 $objPHPExcel = new PHPExcel(); // ワークシートオブジェクト取得 $objWorksheet = $objPHPExcel->getActiveSheet(); // チャート用テストデータ生成 $objWorksheet->fromArray( array( array('年' , '商品売上'), array( 2016, 1200000), array( 2017, 850000), array( 2018, 710000), array( 2019, 1800000), array( 2020, 900000), ) ); // 系列ラベルの指定 $arrDataSeriesLabels1 = array( new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), //商品売上 ); // X軸ラベルの指定 $arrCategorysDataSeries = array( new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$6', NULL, 5), //2016 to 2020 ); // 商品1:描画データの指定 $arrDataSeriesValues1 = array( new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$6', NULL, 5), //商品1 ); // 商品1:チャート・データシリーズの生成 $objSeries1 = new PHPExcel_Chart_DataSeries( PHPExcel_Chart_DataSeries::TYPE_BARCHART, // plotType PHPExcel_Chart_DataSeries::GROUPING_STANDARD, // plotGrouping range(0, count($arrDataSeriesValues1) - 1), // plotOrder $arrDataSeriesLabels1, // plotLabel $arrCategorysDataSeries, // plotCategory $arrDataSeriesValues1 // plotValues ); // プロットエリアにチャート・データシリーズに設定 $objPlotArea = new PHPExcel_Chart_PlotArea(NULL, array($objSeries1)); // レジェンド生成 $objLegend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_TOPRIGHT, NULL, false); // チャート・タイトル生成 $objTitle = new PHPExcel_Chart_Title('Axis-Test'); // 軸オブジェクト $xAxis = new PHPExcel_Chart_Axis(); // 軸の値の書式(1000以下を省略) $xAxis->setAxisNumberProperties("#,##0,"); // チャート生成 $objChart = new PHPExcel_Chart( 'chart1', // name $objTitle, // title $objLegend, // legend $objPlotArea, // plotArea TRUE, // plotVisibleOnly 0, // displayBlanksAs NULL, // xAxisLabel NULL, // yAxisLabel $xAxis, // xAxis NULL // yAxis ); // ワークシート内のチャート位置設定 $objChart->setTopLeftPosition('A8'); // 左上 $objChart->setBottomRightPosition('G20'); // 右下 // ワークシートにチャート追加 $objWorksheet->addChart($objChart); // [test-g-4-1.xlsx]:Excel2007形式で保存する $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, "Excel2007"); $objWriter->setIncludeCharts(TRUE); $objWriter->save('test-g-8-1.xlsx'); exit(); ?>出力されたエクセルファイル[test-g-8-1.xlsx]を見てみると以下の様になります。
この例では軸の値表示で1000以下の値を省略しています。
尚、チャート生成の new PHPExcel_Chart の xAxis にあたるところに軸オブジェクトを設定しています。 チャートの表示からすれば yAxis なのかなと思ったのですが、逆の様です。 (このあたりははっきりしないのですが、商品1の売上値は横方向に在るためそれで xAxis でしょうか? 後に解明できた時には記事を修正します。)
-
今回は PHPExcel でセルの中にフォントサイズが異なる文字列を設定する方法を説明したいと思います。
今まではセルに対して文字列をそのまま設定すれば、フォントサイズはデフォルトのままで設定できました。
セルに設定する値を文字列では無く、リッチテキストクラス「PHPExcel_RichText」を使うことで、 設定する文字列にフォントなどの指定ができます。<?php // ライブラリ読込 require_once './PHPExcel-1.8/Classes/PHPExcel.php'; // PHPExcelオブジェクト作成 $objBook = new PHPExcel(); // シート設定 $objSheet = $objBook->getActiveSheet(); // リッチテキストで前半はサイズ12で、後半はサイズ20で設定 $objRichText = new PHPExcel_RichText(); // リッチテキストに文字列設定 $objTextElm = $objRichText->createTextRun("サイズ12"); // フォントサイズ12設定 $objTextElm->getFont()->setSize(12); // リッチテキストに文字列追加設定 $objTextElm = $objRichText->createTextRun("サイズ20"); // フォントサイズ20設定 $objTextElm->getFont()->setSize(20); // [A1]セルに設定 $objSheet->getCell('A1')->setValue($objRichText); // ブラウザへの指定 $objWriter = PHPExcel_IOFactory::createWriter($objBook, "Excel2007"); $objWriter->save('test11-1.xlsx'); exit(); ?>出力されたエクセルファイルを見てみると以下の様になります。
”サイズ12”の文字列はサイズ12で、”サイズ20”の文字列はサイズ20で設定されている様子がわかります。