HotXLSは、DelphiおよびC++Builderから、Excelのスプレッドシート内の単一のセルに描画されるミニグラフであるスパークライン(Sparklines)を1回の呼び出しで作成します。TXLSXWorksheet.AddSparklineGroup はデータ範囲に対してスパークライングループを構築し、ワークブックを保存すると、それがワークシートの extLst 内に x14 拡張ブロックとして書き込まれます。これは Excel 2010 以降がレンダリングし、それより古いリーダーはエラーを出すことなく無視します。グラフオブジェクトも、描画パーツも、アンカーの指定も不要です。
スパークラインを導入する価値のあるシナリオは常に同じです。ダッシュボードワークブックに、製品ごと、地域ごと、あるいはアカウントごとに1行ずつ、合計数百行のデータがあり、それぞれに12ヶ月分の数値が格納されています。そして、すべての行の末尾にトレンドを示すグリフを配置したいという要求が生じます。これを本物のグラフで表現しようとすると、ファイルサイズやオープン時間に与える影響は言うまでもなく、数百ものDrawingMLグラフパーツを作成し、それぞれに独自のXMLパーツ、関係性、およびアンカー配置を割り当てなければなりません。しかしスパークライングループであれば、「B2:M2からN2へ、B3:M3からN3へ小さなグラフを描画する」という定義を保持する1つのXMLブロックだけで済み、行数が増えても低コストで処理できます。
スパークラインがグラフではなくx14拡張である理由
スパークラインは、ECMA-376ベーススキーマが確定してから3年後の Excel 2010 で導入されたため、既存のリーダーを破壊することなくワークシートのマークアップ自体に組み込むことはできませんでした。Microsoftの解決策は、拡張リスト(Extension List)メカニズムです。ワークシートの末尾に <extLst> 要素を置き、その中に機能を特定するURIがタグ付けされた <ext> ブロックを保持させます([MS-XLSX] §2.3.6)。スパークラインは、URI {05C60535-1F16-4fd2-B633-F4F36F0B64E0} と x14 名前空間を使用します。このGUIDを認識するリーダーはブロックを解析し、認識しないリーダーはスキップすることが要求されます。これが前方互換性(フォワード互換性)の仕様であり、Excel 2007 でスパークラインを含むワークブックを開いた場合でも、警告を出すことなく単純にグリフのない元のデータのみが表示されます。
このメカニズムについて、一般的な前提と矛盾する注目すべき詳細が1つあります。それは、ワークシートのルートで mc:Ignorable 宣言を行う必要がないという点です。拡張URIのゲートだけで十分であり、Excel独自のライターもルートを変更するのではなく、<ext> 要素上でローカルに x14 名前空間を宣言します。HotXLSもこれと同じパターンに従うため、ワークシートXMLの他の部分は変更されずに保たれます。また、これが本物のグラフとの構造的な違いでもあります。グラフは、独自の描画パイプラインを持つ独立したDrawingMLパーツであり、これについてはグラフ、画像、および描画に関する記事で説明されています。一方、スパークラインは、スプレッドシートグリッド自体が描画するワークシートのメタデータです。
プログラムからXLSXファイルにスパークラインを追加する方法
TXLSXWorksheet.AddSparklineGroup(AType, ASourceRange, ALocation) が直接の解決策です。指定されたタイプのグループを作成し、Excelのデフォルトのシリーズカラーを設定し、シート修飾されたソース範囲をホストセルにマッピングする最初のスパークラインを追加します。返された TXLSXSparklineGroup は、その後 Add メソッドを介して、1行につき1つの F/Sqref ペアの形式でさらに多くのスパークラインを受け入れます。これらはすべて、グループのタイプとフォーマット設定を共有します。ダッシュボードのケースでは、まさにこの形状が適しています。すなわち、1つのグループ、1つのビジュアル設定、および多数のメンバーです。
var
Book: TXLSXWorkbook;
Sheet: TXLSXWorksheet;
Grp: TXLSXSparklineGroup;
Row: Integer;
begin
Book := TXLSXWorkbook.Create;
try
Book.Open('dashboard.xlsx');
Sheet := Book.Sheets[0];
// One group: every product row shares type and formatting
Grp := Sheet.AddSparklineGroup(xlsxSparklineLine,
'Sheet1!B2:M2', 'N2');
for Row := 3 to 201 do
Grp.Add(Format('Sheet1!B%d:M%d', [Row, Row]),
Format('N%d', [Row]));
Book.SaveAs('dashboard-trends.xlsx');
finally
Book.Free;
end;
end;
TXLSXSparklineType は、Excelが提供する3つのタイプをカバーしています。トレンドを示す xlsxSparklineLine、小さな棒グラフである xlsxSparklineColumn、およびすべての値を上下のブロックとして描画する勝敗(win/loss)ストリップである xlsxSparklineStacked です。メンバーとなる個々のスパークラインは、シート修飾されたソース範囲 F と、グリフが描画されるセル Sqref の2つの文字列だけなので、行ごとに他に設定することはありません。空白のグループから開始したい場合は、Worksheet.SparklineGroups コレクションを介してグループを手動で構築することもできます。
型指定されたモデルにおけるマーカー、カラースロット、および軸のスケーリング
TXLSXSparklineGroup は、Excelの「スパークライン ツール」リボンが提供する完全なオプションセットをプレーンなプロパティとして公開します。データポイントを強調するための6つのブーリアン(真偽値)切り替えがあります。折れ線スパークラインのすべてのポイントを示す Markers、さらに HighPoint (頂点)、LowPoint (最下点)、NegativePoints (負のポイント)、FirstPoint (始点)、および LastPoint (終点)です。これらとペアになる8つのARGBカラースロット(ColorSeries、ColorNegative、ColorAxis、ColorMarkers、ColorFirst、ColorLast、ColorHigh、ColorLow)があり、0のままにされたスロットはファイルから除外され、Excelが独自のデフォルト色を適用します。ライブラリ全体で同じ完全に不透明なARGB形式が使用されているため、ここでの $FFD00000 は、条件付き書式スタイルで指定する赤と同じ意味になります。
Grp := Sheet.AddSparklineGroup(xlsxSparklineStacked,
'Sheet1!B2:M2', 'N2');
Grp.NegativePoints := True; // losing months stand out
Grp.ColorNegative := $FFD00000;
Grp.HighPoint := True;
Grp.ColorHigh := $FF00B050;
Grp.MinAxisType := xlsxSparklineAxisGroup; // one scale for all rows
Grp.MaxAxisType := xlsxSparklineAxisGroup;
Grp.DisplayEmptyCellsAs := xlsxSparklineEmptyGap;
保存時にHotXLSがワークシートのextLstに書き出す内容
保存時、HotXLSは各グループを x14:sparklineGroup 要素としてシリアライズします。これには、タイプや切り替え属性、子要素としてのカラースロット、および xm:f 範囲数式と xm:sqref ホストセルをペアにした x14:sparklines リストが含まれます。構造全体は、ワークシートパーツの末尾にある <extLst><ext uri="{05C60535-1F16-4fd2-B633-F4F36F0B64E0}"> の中に配置され、Excelの書き出しと同様に、ブロック上で x14 名前空間が直接宣言されます。スパークライングループを持たないワークシートは extLst を出力しないため、この機能を使用していないファイルは、以前のHotXLSバージョンが作成したものとバイト単位で同一になります。これは、ロスレス往復(ラウンドトリップ)インフラに関する記事で説明されている保守的なライターの規律です。
出力をExcelのものと比較したり、手動でXMLをチェックしたりする場合、仕様の重要な詳細が1つあります。それは、lineWeight (線の太さ)のスキーマのデフォルト値が、いくつかの二次資料が引用している 1.25 ポイントではなく、0.75 ポイントであるという点です。[MS-XLSX] は CT_SparklineGroup@lineWeight のデフォルト値を 0.75 と定義しており、これはExcelのUIが実際に適用する太さと一致します。HotXLSはデフォルト値を除外することでこの仕様を尊重しています。LineWeight に 0.75 以外の値を設定すると属性が書き出され、0.75 のままであれば書き出されません。これを誤ると、Excelから保存した同じワークブックよりも、線が微妙に太く、あるいは細くレンダリングされるファイルが生成されてしまいます。
往復処理、シートのコピー、およびHotXLSがモデル化しない拡張ブロックについて
開く処理は、保存処理の裏返しです。HotXLSがスパークラインを含むワークブックを開くと(HotXLSが作成したものであれ、Excelが作成したものであれ)、パーサーはスパークラインの拡張GUIDに基づいてゲートを開き、すべてのグループ、メンバー、カラー、および軸オプションを型指定されたモデルに再構築します。そのため、開いて編集して保存するというサイクルで、これらを完全に維持できます。ワークシートを別のワークブックにコピーすると、そのシートのスパークライングループも他のパーツと一緒にクローンされるため、テンプレート駆動のレポート生成が容易になります。すなわち、スタイリングされたテンプレートシートを保持し、レポートごとにコピーして範囲を再指定するだけです。
extLst には、HotXLSが型指定されたモデルを持っていない拡張ブロックも含まれる場合があります。Excelは、スライサーや拡張された条件付き書式などの機能のための x14 ブロックを同じリストに書き出します。v2.131.0以降、それらの外部ブロックはラウンドトリップ時にドロップされることなく、そのまま維持されます。パーサーはこれらをキャプチャし、Worksheet.RawWorksheetExts を介して読み取り専用で公開し、保存時に書き戻します。これらはシートが別のワークブックにコピーされる際にも一緒に移動します。保存されたXMLはパーサーのイベントから再構成されるため、元のものとバイト単位で完全に同一ではなくセマンティクス的に同等ですが、Excelはこれを受け入れ、機能も維持されます。実用的なメリットとして、顧客のワークブックを開いて再保存した際に、HotXLSが理解できないからといって拡張機能が勝手に剥ぎ取られることがなくなります。
率直な制限として、スパークラインは Excel 2010 以降、および x14 拡張を実装している他のリーダーでレンダリングされます。Excel 2007 ではグリフのないデータのみが表示され、これはフォーマットがそのように格下げされるように設計された仕様です。3つのスパークラインタイプ、8つのカラースロット、ポイントの切り替え、および3つの軸モードは、Excel独自のダイアログが提供する完全なオプションの表面をカバーしています。スパークラインのサポートは、ここで示したXLSXエンジンの他の部分と並んで、DelphiおよびC++Builder向けのHotXLS Delphi Excel Componentに同梱されています。