Streamování velkých tabulek
Přehled
Načítání velmi velkých tabulek (např. milionů naplněných buněk) do paměti může vést k chybám nedostatku paměti v 32bitových procesech; HotXLS poskytuje streamované čtečky a zapisovače s téměř konstantní spotřebou paměti, které obcházejí generování DOM během analýzy sešitu
Přímé rozhraní API čtečky
Třída TXLSDirectReader analyzuje proudy sešitu bez vytváření modelů buněk v paměti a spouští události OnSheet a OnCell ve chvíli, kdy narazí na vybrané buňky
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 zapne inflatery listů a čtečky XML lokální pro jednotlivá vlákna workerů, zatímco volající vlákno vysílá zpětná volání v pořadí listů a buněk
ParallelBufferMemoryLimit ohraničuje celkovou frontu surových dat buněk napříč aktivními workery a má výchozích 16 MiB, zatímco ParallelPeakBufferedBytes hlásí vrchol posledního paralelního čtení pro diagnostiku a testy kapacity
Každý aktivní list dostane nezávislý podíl z rozpočtu fronty, takže pozdější list nemůže vyhladovat list, který se právě vysílá; jediná buňka větší než svůj podíl se pustí dál jako neredukovatelný obsah
OnDimension, OnSheetFormat, OnColumn, OnRow, OnPane a OnMerge zpřístupňují použitý rozsah, výchozí šířky a výšky, rozsahy sloupců, výšku či viditelnost řádků, indexy obrysů a stylů, stav panelů a sloučené oblasti, a to bez stavění objektů listu
Zpětná volání rozvržení jsou volitelná a běží v průchodu metadaty s ohraničenou pamětí dřív, než se spustí zpětná volání OnCell vybraného listu; sloučené oblasti proto dorazí před buňkami uvnitř sloučení, i když OOXML ukládá mergeCells až za sheetData
Při zapnutém paralelním rozboru listů zůstávají zpětná volání rozvržení na volajícím vlákně a pro vybrané listy se dokončí dřív, než se vyprázdní fronty workerů
Nastavení Abort v OnCell probudí blokované producenty i konzumenty, zastaví běžící čtení ZIP a dekompresi v ohraničených vnitřních krocích, připojí všechny workery a nechá čtečku znovupoužitelnou
Přímé rozhraní API zapisovače
Třída TXLSDirectWriter zapisuje řádky přímo do balíčku souboru ZIP, čímž při generování velkých exportů dat zajišťuje minimální režii paměti
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 zapisuje klasické poznámky k buňkám s metadaty autora a odpovídajícími tvary poznámek VML, aniž by načítal objektový model listu
AddImage, AddImageFromFile a AddImageFromStream přijímají kotvy přes dvě buňky a obsahy PNG, JPEG, GIF, BMP, EMF nebo WMF; zdroje ze souborů tečou přímo do položky ZIP, jakmile se list dokončí, zatímco zdroje ze streamů si drží jen referenci na stream a zaznamenaný rozsah bajtů
Když AddImageFromStream dostane OwnsStream=True, zapisovač stream uvolní po finalizaci bočních částí listu; jinak musí volající udržet seekovatelný stream naživu do dalšího volání AddSheet nebo Close
AddChart a AddChartSeries generují ChartML pro sloupcové, pruhové, spojnicové, plošné, koláčové, prstencové nebo bodové grafy se sériemi založenými na vzorcích, zatímco AddChartXml připojí kompletní grafovou part dodanou volajícím pro pokročilé rodiny grafů a rozšíření
Komentáře, kotvy kresby a popisovače grafů se uchovávají jen pro aktuální list; po uzavření sheetData zapisovač postupně vysílá relace listu, komentáře, VML, DrawingML, média a ChartML a pak uvolní stav bočního kanálu dřív, než začne další list