Streaming großer Tabellenkalkulationen
Übersicht
Das Laden sehr großer Tabellenkalkulationen (z. B. Millionen gefüllter Zellen) in den Speicher kann in 32-Bit-Prozessen zu Speichermangel-Fehlern führen; HotXLS bietet Streaming-Reader und -Writer mit nahezu konstanter Speichernutzung, die die DOM-Generierung beim Parsen der Arbeitsmappe umgehen
Direct-Reader-API
Die Klasse TXLSDirectReader parst Arbeitsmappen-Streams, ohne In-Memory-Zellmodelle zu erzeugen, und feuert OnSheet- und OnCell-Ereignisse, sobald ausgewählte Zellen angetroffen werden
Reader := TXLSDirectReader.Create;
try
Reader.ParallelSheets := True;
Reader.ParallelMaxThreads := 4;
Reader.ParallelBufferMemoryLimit := 16 * 1024 * 1024;
Reader.OnDimension := HandleDimension;
Reader.OnColumn := HandleColumn;
Reader.OnRow := HandleRow;
Reader.OnMerge := HandleMerge;
Reader.OnCell := HandleCell;
Reader.ReadFile('large.xlsx');
finally
Reader.Free;
end;
ParallelSheets aktiviert worker-lokale Arbeitsblatt-Inflater und XML-Reader, während der aufrufende Thread die Callbacks in Arbeitsblatt- und Zellenreihenfolge ausgibt
ParallelBufferMemoryLimit begrenzt die aggregierte Warteschlangen-Payload roher Zellen über alle aktiven Worker und steht standardmäßig auf 16 MiB, während ParallelPeakBufferedBytes den Spitzenwert des letzten parallelen Lesens für Diagnosen und Kapazitätstests meldet
Jedes aktive Arbeitsblatt erhält einen unabhängigen Anteil des Warteschlangenbudgets, sodass ein späteres Arbeitsblatt das aktuell ausgegebene nicht aushungern kann; eine einzelne Zelle, die größer als ihr Anteil ist, wird als nicht teilbarer Payload zugelassen
OnDimension, OnSheetFormat, OnColumn, OnRow, OnPane und OnMerge legen den benutzten Bereich, Standardbreiten und -höhen, Spaltenspannen, Zeilenhöhe oder -sichtbarkeit, Gliederungs- und Style-Indizes, Fensterzustand und Verbundbereiche offen, ohne Arbeitsblattobjekte zu erzeugen
Layout-Callbacks sind opt-in und laufen in einem speicherbegrenzten Metadaten-Durchlauf vor den OnCell-Callbacks des ausgewählten Blatts; Verbundbereiche treffen deshalb ein, bevor die Zellen innerhalb des Verbunds kommen, obwohl OOXML mergeCells nach sheetData speichert
Ist das parallele Parsen von Blättern aktiviert, bleiben Layout-Callbacks auf dem aufrufenden Thread und laufen für die ausgewählten Blätter durch, bevor die Worker-Warteschlangen abgearbeitet werden
Das Setzen von Abort in OnCell weckt blockierte Producer und Consumer, stoppt laufende ZIP-Lesevorgänge und Dekompression an begrenzten internen Schritten, joinet jeden Worker und lässt den Reader wiederverwendbar zurück
Direct-Writer-API
Die Klasse TXLSDirectWriter schreibt Zeilen direkt in das ZIP-Dateipaket und gewährleistet minimalen Speichermehraufwand beim Erzeugen großer Datenexporte
Writer := TXLSDirectWriter.Create;
try
Writer.BeginFile('large.xlsx');
Writer.AddSheet('Data');
Writer.AddRow(1);
Writer.WriteString(1, 'Quarter');
Writer.WriteString(2, 'Revenue');
Writer.AddComment(2, 1, 'Validated source', 'Reviewer');
Writer.AddImageFromFile(4, 1, 8, 12, 'logo.png',
xlsDirectImagePng, 'Company logo');
ChartIndex := Writer.AddChart(9, 1, 18, 16,
xlsDirectChartColumn, 'Revenue');
Writer.AddChartSeries(ChartIndex, 'Revenue',
'Data!$A$2:$A$5', 'Data!$B$2:$B$5');
Writer.Close;
finally
Writer.Free;
end;
AddComment schreibt klassische Zellnotizen mit Autoren-Metadaten und die passenden VML-Notizformen, ohne ein Arbeitsblatt-Objektmodell zu laden
AddImage, AddImageFromFile und AddImageFromStream nehmen Zwei-Zellen-Anker sowie PNG-, JPEG-, GIF-, BMP-, EMF- oder WMF-Payloads; Dateiquellen fließen beim Abschluss des Blatts direkt in den ZIP-Eintrag, während Stream-Quellen nur die Stream-Referenz und die aufgezeichnete Byten-spanne zurückhalten
Erhält AddImageFromStream OwnsStream=True, gibt der Writer diesen Stream frei, nachdem die arbeitsblattseitigen Teile finalisiert sind; andernfalls muss der Aufrufer den seekable Stream bis zum nächsten AddSheet- oder Close-Aufruf am Leben halten
AddChart und AddChartSeries erzeugen Säulen-, Balken-, Linien-, Flächen-, Kreis-, Ring- oder Punktdiagramm-ChartML mit formelgestützten Datenreihen, während AddChartXml einen vollständigen, vom Aufrufer gelieferten Diagrammteil für erweiterte Diagrammfamilien und Erweiterungen anhängt
Kommentare, Zeichnungsanker und Diagramm-Deskriptoren werden nur für das aktuelle Arbeitsblatt vorgehalten; nach dem Schließen von sheetData gibt der Writer Arbeitsblatt-Beziehungen, Kommentare, VML, DrawingML, Medien und ChartML sequenziell aus und räumt den Seitenkanal-Zustand auf, bevor das nächste Arbeitsblatt beginnt