HotXLS ukladá bunky pracovného hárku do kompaktných 256-riadkových blokov, řeší formátovanie riadkov, stĺpcov a obdĺžnikov cez lenivé intervalové prekryvy namiesto vytvárania objektov buniek a streamuje každý riadok priamo do deflate streamu balíka pri ukladaní. Spolu tieto tri zmeny rozhodujú o pamäťovom profile veľkého zošita: špičkové využitie pamäte sleduje najväčší jeden riadok a nie veľkosť úplného XML pracovného hárku
Dôvod, prečo to záleží, je tvar, s ktorým sa každý vývojár tabuliek skôr či neskôr stretne. Používateľ naformátuje celý stĺpec — jedno kliknutie, jeden milión buniek — a naivný objektový model odpovie alokovaním milióna objektov buniek, aby držal jeden index formátu čísla. Súbor na disku zostáva malý, pretože formát XLSX to vyjadruje ako jedinú položku <col>. Proces vôbec neostáva malý
Prečo formátovanie stĺpca stojí viac pamäte ako jeho vyplnenie?
Pretože formátovanie nemá žiadne dáta, ktoré by ospravedlňovali objekt. bunka s hodnotou musí existovať niekde. Bunka, ktorá je prázdna, ale štýlovaná, existuje iba preto, aby niesla index štýlu, a materializácia miliónov takýchto je klasicým spôsobom, akým Delphi tabuľková aplikácia minie adresný priestor na súbore, ktorý Excel otvorí okamžite
Intervalové prekryvy štýlov túto potrebu odstraňujú. Inštrukcia formátovania riadku, stĺpca alebo obdĺžnika sa uloží raz ako rozsah spolu s časťami štýlu, ktoré prispieva, a řeší sa lenivo, keď je bunka v tomto rozsahu skutočne prístupná. Prekryvy prežijú štrukturálne úpravy — vloženie riadku vnútri formátovaného bloku posunie interval namiesto jeho prestavby — a v okruhu sa vracajú ako kompaktné položky stĺpcov, riadkov a štýlom-bunka, čo je presne to, ako ich zapisuje Excel
var
Sheet: TXLSXWorksheet;
State: TXLSXCellStyleState;
begin
Sheet := Workbook.Sheets[1];
// Style indexes come from the workbook style pools, e.g. from a cell
// you have already formatted the way you want the range to look
State := BuildStateFromTemplateCell(Sheet.Cells.Item[1, 1]);
// Format columns B..D without creating a single empty cell object
Sheet.StyleOverlays.Add(1, 2, MaxRowIndex, 4,
[xfpNumberFormat, xfpAlignment], State);
end;
TXLSXFormatParts je množina, ktorá rozhoduje, čo prekryv prispieva: xfpFont, xfpFill, xfpBorder, xfpNumberFormat, xfpAlignment a xfpProtection. Menovanie iba tých častí, ktoré myslíte vážne, je to, čo umožňuje prekryvom vrstviť sa rozumne — prekryv stĺpca dodávajúci formát čísa sa nebije s prekryvom riadku dodávajúcim výplň, pretože ani jeden si nenárokuje časť toho druhého
Čo vám dá 256-riadkový blok
Lokalitu. Bunky sa držia v blokoch po 256 riadkoch so stabilnými verejnými handle, serializované row-major, takže zápis pracovného hárku prechádza pamäťou v poradí, v akom bude emitovať bajty, a nie naháňaním ukazovateľov cez haldu. Stabilné handle záležia pre API plochu: handle, ktorý drží volajúci, zostáva platný naprieč vnútornou reorganizáciou, ktorú vykonáva rozvrhnutie blokov, čo robí z kompaktnej reprezentácie implementačný detail a nie breaking change
Kompakcia poolu štýlov beží vedľa. Pred každým uložením sa zahodia fonty, výplne, okraje, formáty čísel, zarovnania a ochrany, na ktoré sa neodkazuje žiadna bunka. Dlho žijúce zošity hromadia nereferencované záznamy štýlov tak, ako dlho žijúce dokumenty hromadia nepoužité štýly, a zošit, ktorý bol hodinu upravovaný používateľom, môže niesť stovky z nich do súboru, z ktorého si ich nikto nikdy neprečíta
Row-streamed ukladanie a kedy neplatí
S zapnutým StreamingWrite — predvolené — sa každý riadok pracovného hárku zapisuje priamo do deflate streamu balíka. Alternatíva, ktorú prepínač vypína, postaví najprv úplné XML pracovného hárku a komprimuje ho až potom, takže špičková pamäť škáluje s celým hárkom. Streamovanie ju nechá škálovať s jedným riadkom
Zdieľané reťazce a auxiliárne časti nasledujú rovnakú disciplínu cez jeden znovupoužiteľný UTF-8 serializér, ktorý emituje položky po jednej a obmedzuje špičkovú pamäť najväčšou jednou položkou a nie celou časťou. To pokrýva tabuľku zdieľaných reťazcov a pivot záznamy, ktoré na širokom analytickom zošite bývajú často väčšie než ktorýkoľvek jednotlivý pracovný hárok
var
Workbook: TXLSXWorkbook;
begin
Workbook := TXLSXWorkbook.Create(nil);
try
Workbook.Open('ledger-2026.xlsx');
// StreamingWrite defaults to True; turn it off only when a downstream
// step requires the whole worksheet XML to exist before compression
Workbook.StreamingWrite := True;
Workbook.SaveAs('ledger-2026-out.xlsx');
finally
Workbook.Free;
end;
end;
Nechajte ho zapnutý, pokým nemáte konkrétny dôvod neurobiť tak. Cesta bez streamovania existuje pre prípady, kedy niečo iné v linke potrebuje zhromaždené XML, a platiť zaň predvolene je platenie za prípad, s ktorým sa väčšina aplikácií nikdy nestretne
Ako zistiť, či sa prekryvy skutočne používajú
Sledujte počet buniek, nie graf pamäte. Ak pracovný hárok po širokej aplikácii formátovania nahlásite vierohodný počet fyzických buniek, prekryvy robia svoju prácu. Ak počet vyskočí o veľkosť formátovaného rozsahu, niečo v ceste kódu bunky materializovalo — zvyčajne slučka, ktorá číta každú bunku v rozsahu, aby skontrolovala jej štýl, čo vynúti rozlíšenie jednu bunku po druhej a porazí celé usporiadanie
Rozlíšte štýl, keď potrebujete efektívny formát jednej bunky. Neriešite štýl pre milión buniek, aby ste zistili, že stĺpec má formát čísla; opýtajte sa prekryvu. Rovnaké pravidlo platí pre zápis: priraďte hodnoty bunkám, ktoré majú hodnoty, a nechajte formátovanie ostať intervalom
Kam odíde zvyšná pamäť
Keď sú bunky a štýly kompaktné, najväčšími spotrebiteľmi na veľkom zošite sú tabuľka zdieľaných reťazcov a satelitné časti, ktoré súbor nesie — pivot caches, kresby, preserved XML z častí, ktoré objektový model nemodeluje. Tie majú svoje vlastné stratégie a úprimná odpoveď je, že žiadne jediné nastavenie ich všetky naraz nerieši
Ak je vaším úzkym hrdlom otváranie a nie ukladanie, selektívne načítavanie je pákou: návod k načítavaniu len z metadát a selektívnemu načítavaniu hárkov pokrýva čítanie zošita bez platby za hárky, ktoré sa nedotknete. Pri priepustnosti čítacej cesty na veľmi veľkých súboroch pozri poznámky k paralelnému XLSX parsingu a alokátore pamäte a pre workloady len na výstup, ktoré nikdy nepotrebujú objektový model, je streaming zápis pre serverové dávkové úlohy zvyčajne vhodnejšia ako akékoľvek množstvo ladenia tu
HotXLS číta a zapisuje XLS a XLSX z natívneho Delphi a C++Builder kódu bez inštalácie Excelu a bez OLE automatizácie, čo je to, čo tieto pamäťové charakteristiky robí pozorovateľnými a kontrolovateľnými v prvom rade — stránka HotXLS spreadsheet komponentu uvádza podporované formáty a verzie RAD Studio