忍者ブログ

VB.NET-TIPS などプログラミングについて

VB.NETのTIPS(小技集)を中心に、Javascript、PHP その他のプログラミングについて少し役に立つ情報を発信します。いわゆる個人的な忘備録ですが、みなさんのお役に立てれば幸いです。

PHP PHPExcel ワークシート上にチャート(グラフ)を作成する方法について(PHPExcel_Chart)


今回は PHPExcel で行う「チャート」の作成方法について説明したいと思います。




■簡単なチャートを作成する(1個の折れ線グラフ)

簡単なチャートを作成する例として、1個の商品の各年の売り上げの推移を折れ線グラフとして作成してみます。
(テストデータとしては以下の様なデータです)


PHPExcel_Chart を使ったチャートの作成手順は以下の様になります。

  • PHPExcel_Chart_DataSeries クラスでチャート・データシリーズの生成。
    (この前に PHPExcel_Chart_DataSeriesクラスで「描画データ」「X軸ラベル」等を生成し、指定する)
  • PHPExcel_Chart_PlotAreaクラスでプロットエリアにチャート・データシリーズを設定し、生成。
  • プロットエリアを指定し PHPExcel_Chartクラスでチャート生成。
  • ワークシートにチャート追加。
  • ワークブック登録クラス PHPExcel_Writer_IWritersetIncludeCharts() メソッドでチャートを含むことを設定。

この手順に従って、以下の様なソースになります。

<?php
// ライブラリ読込
require_once './PHPExcel-1.8/Classes/PHPExcel.php';
// PHPExcelオブジェクト作成
$objPHPExcel = new PHPExcel();
// ワークシートオブジェクト取得
$objWorksheet = $objPHPExcel->getActiveSheet();
//  チャート用テストデータ生成
$objWorksheet->fromArray(
	array(
		array('売上' , 2016, 2017, 2018, 2019, 2020),
		array('商品1',   12,   15,   21,   18,   20),
	)
);

//  X軸ラベルの指定
$arrCategorysDataSeries = array(
	new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1:$F$1', NULL, 5),	//	2016 to 2020
);
//  描画データの指定
$arrDataSeriesValues = array(
	new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$F$2', NULL, 5),
);
//	チャート・データシリーズの生成
$objSeries = new PHPExcel_Chart_DataSeries(
	PHPExcel_Chart_DataSeries::TYPE_LINECHART,  // plotType
    NULL,                                       // plotGrouping
	range(0, count($arrDataSeriesValues) - 1),  // plotOrder
	NULL,                                       // plotLabel
	$arrCategorysDataSeries,                    // plotCategory
	$arrDataSeriesValues                        // plotValues
);

//	プロットエリアにチャート・データシリーズに設定
$objPlotArea = new PHPExcel_Chart_PlotArea(NULL, array($objSeries));

//  チャート・タイトル生成
$objTitle = new PHPExcel_Chart_Title('売上データ');
//	チャート生成
$objChart = new PHPExcel_Chart(
	'chart1',       // name
	$objTitle,      // title
	NULL,           // legend
	$objPlotArea,   // plotArea
	TRUE,           // plotVisibleOnly
	0,              // displayBlanksAs
	NULL,           // xAxisLabel
	NULL		    // yAxisLabel
);
//	ワークシート内のチャート位置設定
$objChart->setTopLeftPosition('A6');        // 左上
$objChart->setBottomRightPosition('G18');   // 右下

//	ワークシートにチャート追加
$objWorksheet->addChart($objChart);

// [test-g-1.xlsx]:Excel2007形式で保存する
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, "Excel2007");
$objWriter->setIncludeCharts(TRUE);
$objWriter->save('test-g-1.xlsx');
exit();
?>

このプログラムで必須のクラスの説明を以下に記します。

PHPExcel_Chart_DataSeries のクラス生成の引数は以下の様に定義されています。

PHPExcel_Chart_DataSeries __construct(
    [ $plotType = null        ],    // チャートタイプの定数
    [ $plotGrouping = null    ],    // グルーピング定数
    [ $plotOrder = array()	  ],   // 描画データの指標の配列 array(0, 1, 2 ...)
    [ $plotLabel = array()	  ],   // ラベル用配列     (PHPExcel_Chart_DataSeriesValues クラスの配列)
    [ $plotCategory = array() ],   // X軸ラベル用配列  (PHPExcel_Chart_DataSeriesValues クラスの配列)
    [ $plotValues = array()	  ],   // 描画データ用配列 (PHPExcel_Chart_DataSeriesValues クラスの配列)
    [ $plotDirection = null   ],    // 描画方向定数 (内部的デフォルト:DIRECTION_COL)
    [ $smoothLine = null      ],    // スムージング指定(折れ線グラフまたは散布図)
    [ $plotStyle = null       ]     // 描画スタイル定数
)

//  各定数の定義は以下の通り

//	チャートタイプ定数の定義
const TYPE_BARCHART        = 'barChart';
const TYPE_BARCHART_3D     = 'bar3DChart';
const TYPE_LINECHART       = 'lineChart';
const TYPE_LINECHART_3D    = 'line3DChart';
const TYPE_AREACHART       = 'areaChart';
const TYPE_AREACHART_3D    = 'area3DChart';
const TYPE_PIECHART        = 'pieChart';
const TYPE_PIECHART_3D     = 'pie3DChart';
const TYPE_DOUGHTNUTCHART  = 'doughnutChart';
const TYPE_DONUTCHART      = 'doughnutChart';
const TYPE_SCATTERCHART    = 'scatterChart';
const TYPE_SURFACECHART    = 'surfaceChart';
const TYPE_SURFACECHART_3D = 'surface3DChart';
const TYPE_RADARCHART      = 'radarChart';
const TYPE_BUBBLECHART     = 'bubbleChart';
const TYPE_STOCKCHART      = 'stockChart';
const TYPE_CANDLECHART     = 'stockChart';

//	グルーピング定数の定義
const GROUPING_CLUSTERED       = 'clustered';
const GROUPING_STACKED         = 'stacked';
const GROUPING_PERCENT_STACKED = 'percentStacked';
const GROUPING_STANDARD        = 'standard';

//	描画方向定数の定義
const DIRECTION_BAR        = 'bar';
const DIRECTION_HORIZONTAL = 'bar';
const DIRECTION_COL        = 'col';
const DIRECTION_COLUMN     = 'col';
const DIRECTION_VERTICAL   = 'col';

//	描画スタイル定数の定義
const STYLE_LINEMARKER   = 'lineMarker';
const STYLE_SMOOTHMARKER = 'smoothMarker';
const STYLE_MARKER       = 'marker';
const STYLE_FILLED       = 'filled';


PHPExcel_Chart_DataSeries のクラス生成の引数の中で重要な 「ラベル」「X軸ラベル」「描画データ」の配列の要素のクラスである PHPExcel_Chart_DataSeriesValues のクラス生成の引数は以下の様に定義されています。

PHPExcel_Chart_DataSeries __construct(
	$dataType = self::DATASERIES_TYPE_NUMBER, 	// データ型の定数
	$dataSource = null, 	// シリーズ(系列)データの位置指定
	$formatCode = null, 	// フォーマットコード
	$pointCount = 0, 		// シリーズ(系列)データの個数
	$dataValues = array(), // シリーズ(系列)データを直接指定
	$marker = null			// ポイントマーカーの指定(文字列)
)

//	データ型定数の定義
const DATASERIES_TYPE_STRING    = 'String';
const DATASERIES_TYPE_NUMBER    = 'Number';

シリーズ(系列)データの位置指定はエクセルでのセル範囲(絶対位置:列と行の指定の前に「$」を指定)で指定します。

ポイントマーカーの指定はマーカーの種類を文字列で指定します。以下はマーカーを指定した例を示します。

$arrDataSeriesValues = array(
 new PHPExcel_Chart_DataSeriesValues('Number','Worksheet!$B$2:$F$2',NULL,5,array(),"triangle"),//三角形
 new PHPExcel_Chart_DataSeriesValues('Number','Worksheet!$B$2:$F$2',NULL,5,array(),"circle"),  //円形
 new PHPExcel_Chart_DataSeriesValues('Number','Worksheet!$B$2:$F$2',NULL,5,array(),"diamond"), //ひし形
 new PHPExcel_Chart_DataSeriesValues('Number','Worksheet!$B$2:$F$2',NULL,5,array(),"square"),  //四角形
 new PHPExcel_Chart_DataSeriesValues('Number','Worksheet!$B$2:$F$2',NULL,5,array(),"star"),    //アスタリスク
 new PHPExcel_Chart_DataSeriesValues('Number','Worksheet!$B$2:$F$2',NULL,5,array(),"plus"),    //十字
 new PHPExcel_Chart_DataSeriesValues('Number','Worksheet!$B$2:$F$2',NULL,5,array(),"none"),    //マーカ無
 new PHPExcel_Chart_DataSeriesValues('Number','Worksheet!$B$2:$F$2',NULL,5,array(),"dash"),    //長い横棒
 new PHPExcel_Chart_DataSeriesValues('Number','Worksheet!$B$2:$F$2',NULL,5,array(),"dot"),     //短い横棒
 new PHPExcel_Chart_DataSeriesValues('Number','Worksheet!$B$2:$F$2',NULL,5,array(),"x"),       //×印
);

マーカーの指定を行うとサイズはライブラリの仕様でデフォルトで「3」になります。
もし、この「3」を変更したい場合には、ライブラリの「Classes/PHPExcel/Writer/Excel2007/Chart.php」の中を修正する必要があります。

出力されたエクセルファイルを見てみると以下の様になります。




■複数の折れ線グラフをチャートに表示

複数の折れ線グラフをチャートに表示するには上のデータに「商品2」「商品3」を追加します。
追加されたデータを描画データの指定で PHPExcel_Chart_DataSeriesValues クラス生成を追加します。

<?php
// ライブラリ読込
require_once './PHPExcel-1.8/Classes/PHPExcel.php';
// PHPExcelオブジェクト作成
$objPHPExcel = new PHPExcel();
// ワークシートオブジェクト取得
$objWorksheet = $objPHPExcel->getActiveSheet();
//  チャート用テストデータ生成
$objWorksheet->fromArray(
	array(
		array('売上' , 2016, 2017, 2018, 2019, 2020),
		array('商品1',   12,   15,   21,   18,   20),
		array('商品2',   18,   19,   23,   14,   21),   //追加
		array('商品3',   15,   10,   20,   12,   23),   //追加
	)
);

//  X軸ラベルの指定
$arrCategorysDataSeries = array(
	new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1:$F$1', NULL, 5),	//	2016 to 2020
);
//  描画データの指定
$arrDataSeriesValues = array(
	new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$F$2', NULL, 5),  //商品1
	new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$3:$F$3', NULL, 5),  //商品2 追加
	new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$4:$F$4', NULL, 5),  //商品3 追加
);
//	チャート・データシリーズの生成
$objSeries = new PHPExcel_Chart_DataSeries(
	PHPExcel_Chart_DataSeries::TYPE_LINECHART,      // plotType
    NULL,                                           // plotGrouping(PHPExcel_Chart_DataSeries::GROUPING_STANDARD)
	range(0, count($arrDataSeriesValues) - 1),      // plotOrder
	NULL,                                           // plotLabel
	$arrCategorysDataSeries,                        // plotCategory
	$arrDataSeriesValues                            // plotValues
);

//	プロットエリアにチャート・データシリーズに設定
$objPlotArea = new PHPExcel_Chart_PlotArea(NULL, array($objSeries));

//  チャート・タイトル生成
$objTitle = new PHPExcel_Chart_Title('売上データ');
//	チャート生成
$objChart = new PHPExcel_Chart(
	'chart1',       // name
	$objTitle,      // title
	NULL,           // legend
	$objPlotArea,   // plotArea
	TRUE,           // plotVisibleOnly
	0,              // displayBlanksAs
	NULL,           // xAxisLabel
	NULL		    // yAxisLabel
);
//	ワークシート内のチャート位置設定
$objChart->setTopLeftPosition('A6');        // 左上
$objChart->setBottomRightPosition('G18');   // 右下

//	ワークシートにチャート追加
$objWorksheet->addChart($objChart);

// [test-g-1-2.xlsx]:Excel2007形式で保存する
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, "Excel2007");
$objWriter->setIncludeCharts(TRUE);
$objWriter->save('test-g-1-2.xlsx');
exit();
?>

出力されたエクセルファイルを見てみると以下の様になります。




■複数の折れ線グラフをチャートに表示2(描画データの縦横の入替)

上記の例のデータの縦横を入れ替えた場合、つまり売り上げの時間軸が縦方向となり、商品毎の年度ごとの売り上げを1個の列に並べます。
チャート用テストデータ生成の fromArray() では縦横を入れ替えたデータに変更します。

X軸ラベルの指定は、年度の数値なので A列2行目6行目PHPExcel_Chart_DataSeriesValues への範囲設定は Worksheet!$A$2:$A$6 となります。

また、描画データの指定は、各商品毎の数値なので「商品1」であれば B列2行目6行目PHPExcel_Chart_DataSeriesValues への範囲設定は Worksheet!$B$2:$B$6 となります。

尚、各グラフの線が何を指しているのかを表示する為に、系列ラベルの指定を追加で行います。 描画データの指定と同様に、「商品1」「商品2」「商品3」の文字列をそれぞれ PHPExcel_Chart_DataSeriesValues クラスで生成し、配列に設定します。 この配列を PHPExcel_Chart_DataSeries クラスで生成時に plotLabel の引数として指定します。
この系列ラベルをチャート上に表示させるには、 レジェンドクラス PHPExcel_Chart_Legend で生成したオブジェクトを PHPExcel_Chart 生成時に指定する必要があります。
よってソースは以下の様になります。

<?php
// ライブラリ読込
require_once './PHPExcel-1.8/Classes/PHPExcel.php';
// PHPExcelオブジェクト作成
$objPHPExcel = new PHPExcel();
// ワークシートオブジェクト取得
$objWorksheet = $objPHPExcel->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 PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1),       //商品1
	new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1),       //商品2
	new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1),       //商品3
);
//  X軸ラベルの指定
$arrCategorysDataSeries = array(
	new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$6', NULL, 5),	//2016 to 2020
);
//  描画データの指定
$arrDataSeriesValues = array(
	new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$6', NULL, 5),  //商品1
	new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$6', NULL, 5),  //商品2
	new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$6', NULL, 5),  //商品3
);
//	チャート・データシリーズの生成
$objSeries = new PHPExcel_Chart_DataSeries(
	PHPExcel_Chart_DataSeries::TYPE_LINECHART,      // plotType
    NULL,                                           // plotGrouping(PHPExcel_Chart_DataSeries::GROUPING_STANDARD)
	range(0, count($arrDataSeriesValues) - 1),      // plotOrder
	$arrDataSeriesLabels,                           // plotLabel
	$arrCategorysDataSeries,                        // plotCategory
	$arrDataSeriesValues                            // plotValues
);

//	プロットエリアにチャート・データシリーズに設定
$objPlotArea = new PHPExcel_Chart_PlotArea(NULL, array($objSeries));
//	レジェンド生成(各折れ線の説明を行う)
$objLegend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_TOPRIGHT, NULL, false);
//  チャート・タイトル生成
$objTitle = new PHPExcel_Chart_Title('売上データ');
//	チャート生成
$objChart = new PHPExcel_Chart(
	'chart1',       // name
	$objTitle,      // title
	$objLegend,     // legend
	$objPlotArea,   // plotArea
	TRUE,           // plotVisibleOnly
	0,              // displayBlanksAs
	NULL,           // xAxisLabel
	NULL		    // yAxisLabel
);
//	ワークシート内のチャート位置設定
$objChart->setTopLeftPosition('A8');        // 左上
$objChart->setBottomRightPosition('G20');   // 右下

//	ワークシートにチャート追加
$objWorksheet->addChart($objChart);

// [test-g-1-3.xlsx]:Excel2007形式で保存する
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, "Excel2007");
$objWriter->setIncludeCharts(TRUE);
$objWriter->save('test-g-1-3.xlsx');
exit();
?>

出力されたエクセルファイルを見てみると以下の様になります。
データの並びは縦横が違いますが、作成されたチャートは、1個前のチャートと同じものが作成されます。














PR

コメント

コメントを書く