HotXLS erzeugt Excel-Sparklines — die Miniaturdiagramme, die Excel innerhalb einer einzelnen Zelle zeichnet — aus Delphi und C++Builder mit einem einzigen Aufruf: TXLSXWorksheet.AddSparklineGroup legt eine Sparkline-Gruppe über einem Datenbereich an, und beim Speichern der Arbeitsmappe wird sie als x14-Erweiterungsblock in das extLst des Arbeitsblatts geschrieben, das Excel 2010 und neuer darstellen und ältere Leseprogramme kommentarlos überspringen. Keine Diagrammobjekte, keine Drawing-Parts, keine Anker
Das Szenario, das Sparklines lohnend macht, ist immer dasselbe. Eine Dashboard-Arbeitsmappe enthält einige hundert Zeilen, eine je Produkt, Region oder Konto, mit jeweils zwölf Monatswerten, und jemand möchte am Ende jeder Zeile ein Trendsymbol. Bildet man das mit echten Diagrammen ab, erzeugt man hunderte DrawingML-Diagrammteile, jedes mit eigenem XML-Part, eigener Beziehung und eigener Ankergeometrie, ganz zu schweigen davon, was das für Dateigröße und Öffnungszeit bedeutet. Eine Sparkline-Gruppe ist ein einziger XML-Block, der sagt: „zeichne eine winzige Linie von B2:M2 nach N2 und von B3:M3 nach N3“, und der sich für beliebig viele Zeilen billig wiederholt
Warum sind Sparklines eine x14-Erweiterung und kein Diagramm?
Sparklines kamen mit Excel 2010, drei Jahre nachdem das ECMA-376-Basisschema eingefroren worden war, sodass sie nicht im eigentlichen Arbeitsblatt-Markup leben konnten, ohne jedes vorhandene Leseprogramm zu brechen. Microsofts Antwort ist der Mechanismus der Erweiterungsliste: Ein Arbeitsblatt darf mit einem <extLst>-Element enden, das <ext>-Blöcke enthält, jeder ausgezeichnet mit einer URI, die das Feature identifiziert ([MS-XLSX] §2.3.6). Sparklines verwenden die URI {05C60535-1F16-4fd2-B633-F4F36F0B64E0} und den Namensraum x14. Ein Leseprogramm, das die GUID kennt, verarbeitet den Block; eines, das sie nicht kennt, muss ihn überspringen. Das ist die gesamte Geschichte der Vorwärtskompatibilität, und deshalb öffnet Excel 2007 eine Sparkline-Arbeitsmappe sauber — es zeigt schlicht die Quellzahlen ohne die Symbole
Ein Detail des Mechanismus ist erwähnenswert, weil es einer verbreiteten Annahme widerspricht: Am Wurzelelement des Arbeitsblatts ist keine mc:Ignorable-Deklaration nötig. Die Absicherung über die ext-GUID genügt für sich allein, und Excels eigener Writer deklariert den x14-Namensraum lokal am <ext>-Element, statt die Wurzel anzufassen. HotXLS folgt demselben Muster, was das übrige Arbeitsblatt-XML unberührt lässt. Darin liegt auch der strukturelle Unterschied zu echten Diagrammen: Ein Diagramm ist ein eigener DrawingML-Part mit eigener Rendering-Pipeline, behandelt in dem begleitenden Artikel zu Diagrammen, Bildern und Zeichnungen, während eine Sparkline Arbeitsblatt-Metadaten darstellt, die das Tabellenraster selbst zeichnet
Wie fügt man Sparklines programmgesteuert in eine XLSX-Datei ein?
TXLSXWorksheet.AddSparklineGroup(AType, ASourceRange, ALocation) ist der Weg mit einem einzigen Aufruf: Er erzeugt eine Gruppe des angegebenen Typs, versieht sie mit Excels voreingestellter Serienfarbe und fügt die erste Sparkline hinzu, die einen blattqualifizierten Quellbereich auf eine Wirtszelle abbildet. Die zurückgegebene TXLSXSparklineGroup nimmt anschließend über ihre Methode Add weitere Sparklines auf, ein F/Sqref-Paar je Zeile, die alle Typ und Formatierung der Gruppe teilen. Für den Dashboard-Fall ist genau das die gewünschte Form: eine Gruppe, ein Satz visueller Optionen, hunderte Mitglieder
var
Book: TXLSXWorkbook;
Sheet: TXLSXWorksheet;
Grp: TXLSXSparklineGroup;
Row: Integer;
begin
Book := TXLSXWorkbook.Create;
try
Book.Open('dashboard.xlsx');
Sheet := Book.Sheets[0];
// Eine Gruppe: jede Produktzeile teilt Typ und Formatierung
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 deckt die drei Arten ab, die Excel bietet: xlsxSparklineLine für Trendlinien, xlsxSparklineColumn für winzige Balkendiagramme und xlsxSparklineStacked für Gewinn/Verlust-Streifen, in denen jeder Wert als Block nach oben oder unten erscheint. Jede Mitglieds-Sparkline besteht nur aus zwei Strings — F, dem blattqualifizierten Quellbereich, und Sqref, der Zelle, in der das Symbol gezeichnet wird —, sodass es je Zeile nichts weiter zu konfigurieren gibt. Gruppen lassen sich auch vollständig von Hand über die Sammlung Worksheet.SparklineGroups aufbauen, wenn Sie lieber mit einer leeren Gruppe als mit der vorbelegten Voreinstellung beginnen
Marker, Farbslots und Achsenskalierung am typisierten Modell
TXLSXSparklineGroup stellt den vollen Optionsumfang aus Excels Menüband „Sparklinetools“ als gewöhnliche Eigenschaften bereit. Sechs boolesche Schalter heben Datenpunkte hervor: Markers für jeden Punkt einer Linien-Sparkline sowie HighPoint, LowPoint, NegativePoints, FirstPoint und LastPoint. Dazu gehören acht ARGB-Farbslots — ColorSeries, ColorNegative, ColorAxis, ColorMarkers, ColorFirst, ColorLast, ColorHigh, ColorLow — mit der Konvention, dass ein auf 0 belassener Slot nicht in die Datei geschrieben wird und Excel seine eigene Voreinstellung anwendet. Dieselbe voll deckende ARGB-Form findet sich in der ganzen Bibliothek, sodass $FFD00000 hier dasselbe Rot bedeutet wie in Stilen der bedingten Formatierung
Grp := Sheet.AddSparklineGroup(xlsxSparklineStacked,
'Sheet1!B2:M2', 'N2');
Grp.NegativePoints := True; // Verlustmonate treten hervor
Grp.ColorNegative := $FFD00000;
Grp.HighPoint := True;
Grp.ColorHigh := $FF00B050;
Grp.MinAxisType := xlsxSparklineAxisGroup; // eine Skala für alle Zeilen
Grp.MaxAxisType := xlsxSparklineAxisGroup;
Grp.DisplayEmptyCellsAs := xlsxSparklineEmptyGap;
Die Achseneigenschaften verdienen einen Moment Nachdenken, bevor Sie die Voreinstellungen übernehmen. MinAxisType und MaxAxisType nehmen jeweils individuelle, gruppenweite oder benutzerdefinierte Skalierung an: Individuell dehnt jede Sparkline auf ihr eigenes Minimum und Maximum, wodurch eine Zeile, die zwischen 99 und 101 schwankt, ebenso dramatisch aussieht wie eine Zeile, die sich verdreifacht. Gruppenskalierung stellt alle Mitglieder auf eine gemeinsame vertikale Skala, sodass die Höhe eines Symbols in jeder Zeile dieselbe Menge bedeutet — meist das, was ein vergleichendes Dashboard braucht. DisplayEmptyCellsAs entscheidet, was eine leere Quellzelle mit einer Linie macht: eine Lücke lassen, als Null zählen oder das Loch durch Verbinden der Nachbarn überspannen
Was HotXLS beim Speichern in das extLst des Arbeitsblatts schreibt
Beim Speichern serialisiert HotXLS jede Gruppe als x14:sparklineGroup-Element, das die Typ- und Schalterattribute trägt, die Farbslots als Kindelemente und eine x14:sparklines-Liste, deren Mitglieder eine xm:f-Bereichsformel mit einer xm:sqref-Wirtszelle paaren. Die gesamte Struktur sitzt in <extLst><ext uri="{05C60535-1F16-4fd2-B633-F4F36F0B64E0}"> am Ende des Arbeitsblatt-Parts, mit dem direkt am Block deklarierten x14-Namensraum, genau so, wie Excel es schreibt. Ein Arbeitsblatt ohne Sparkline-Gruppen gibt überhaupt kein extLst aus, sodass Dateien, die das Feature nie genutzt haben, Byte für Byte identisch zu dem herauskommen, was frühere HotXLS-Versionen erzeugt haben — dieselbe Disziplin eines zurückhaltenden Writers, die der Artikel zur verlustfreien Round-Trip-Infrastruktur beschreibt
Ein Detail der Spezifikation zählt, falls Sie die Ausgabe je mit der von Excel vergleichen oder das XML von Hand prüfen: Der Schema-Standard für lineWeight ist 0,75 Punkt, nicht die 1,25, die manche Sekundärquellen nennen — [MS-XLSX] definiert CT_SparklineGroup@lineWeight mit dem Standardwert 0.75, was der Stärke entspricht, die Excels Oberfläche tatsächlich anwendet. HotXLS respektiert den Standard durch Weglassen: Setzen Sie LineWeight auf etwas anderes als 0,75, wird das Attribut geschrieben; lassen Sie es bei 0,75, wird es weggelassen. Wer das in die eine oder andere Richtung falsch macht, erzeugt Dateien, die subtil kräftiger oder feiner dargestellt werden als dieselbe aus Excel gespeicherte Arbeitsmappe
Round-Trips, Blattkopien und Erweiterungen, die HotXLS nicht modelliert
Das Öffnen ist das Spiegelbild des Speicherns. Wenn HotXLS eine Arbeitsmappe mit Sparklines öffnet — gleich ob HotXLS oder Excel sie geschrieben hat —, prüft der Parser die Sparkline-ext-GUID und baut jede Gruppe, jedes Mitglied, jede Farbe und jede Achsenoption im typisierten Modell wieder auf, sodass ein Zyklus aus Öffnen, Bearbeiten und Speichern sie vollständig erhält. Beim Kopieren eines Arbeitsblatts in eine andere Arbeitsmappe werden die Sparkline-Gruppen zusammen mit dem übrigen Blatt geklont, was die vorlagengesteuerte Berichtserzeugung unkompliziert macht: Halten Sie ein gestaltetes Vorlagenblatt vor, kopieren Sie es je Bericht und richten Sie die Bereiche neu aus
Das extLst kann auch Erweiterungsblöcke enthalten, für die HotXLS kein typisiertes Modell hat — Excel schreibt x14-Blöcke für Funktionen wie Datenschnitte und erweiterte bedingte Formatierung in dieselbe Liste. Seit v2.131.0 bleiben diese fremden Blöcke über einen Round-Trip hinweg wortgetreu erhalten, statt verworfen zu werden: Der Parser erfasst sie, stellt sie schreibgeschützt über Worksheet.RawWorksheetExts bereit und schreibt sie beim Speichern zurück, und sie wandern mit einem Blatt mit, wenn es in eine andere Arbeitsmappe kopiert wird. Das erhaltene XML wird aus Parser-Ereignissen rekonstruiert, ist also semantisch gleichwertig zum Original statt byte-identisch, doch Excel akzeptiert es, und die Funktionen überleben. Die praktische Folge ist die, auf die es in der Produktion ankommt: Das Öffnen und erneute Speichern einer Kundenarbeitsmappe entfernt keine Erweiterungen mehr, um deren Verständnis Sie HotXLS nie gebeten haben
Die ehrliche Abgrenzung: Sparklines werden in Excel 2010 und neuer dargestellt sowie in jedem anderen Leseprogramm, das die x14-Erweiterung umsetzt; Excel 2007 zeigt die Daten ohne die Symbole, was genau die Degradation ist, für die das Format entworfen wurde. Die drei Sparkline-Typen, die acht Farbslots, die Punktschalter und die drei Achsenmodi decken den vollen Optionsumfang ab, den Excels eigener Dialog bietet. Die Sparkline-Unterstützung wird zusammen mit dem übrigen hier gezeigten XLSX-Motor in der HotXLS Delphi Excel Component für Delphi und C++Builder ausgeliefert