HotXLS stochează celulele de foaie de calcul în blocuri compacte de 256 de rânduri, rezolvă formatarea rândurilor, coloanelor și dreptunghiurilor prin suprapuneri interval leneșe în loc să creeze obiecte celulă, iar trimite fiecare rând direct în fluxul deflate al pachetului la salvare. Împreună acele trei schimbări decid profilul de memorie al unui registru de lucru mare: vârful de utilizare urmează cel mai mare rând singular mai degrabă decât dimensiunea completului XML de foaie de calcul
Motivul pentru care contează este o formă pe care fiecare dezvoltator de foi de calcul o întâlnește în cele din urmă. Un utilizator formatează o coloană întreagă — un clic, un milion de celule — iar un model de obiecte naiv răspunde alocând un milion de obiecte celulă pentru a ține un singur index de format-număr. Fișierul pe disc rămâne mic pentru că formatul XLSX exprimă asta ca o singură intrare <col>. Procesul nu rămâne mic deloc
De ce costă formatarea unei coloane mai multă memorie decât umplerea ei?
Pentru că formatarea nu are date care să justifice obiectul. O celulă cu o valoare trebuie să existe undeva. O celulă care este goală dar stilizată există doar pentru a purta un index de stil, iar materializarea a milioane dintre acelea este calea clasică prin care o aplicație Delphi de foi de calcul epuizează spațiul de adrese pe un fișier pe care Excel îl deschide instant
Suprapunerile de stil interval elimină nevoia. O instrucțiune de formatare de rând, coloană sau dreptunghi este stocată o dată ca interval plus părțile de stil pe care le contribuie, iar se rezolvă leneș când o celulă din acel interval este efectiv accesată. Suprapunerile supraviețuiesc editărilor structurale — inserarea unui rând în interiorul unui bloc formatat mută intervalul în loc să-l reconstruiască — iar fac drum dus-întors ca intrări compacte de coloană, rând și celulă doar cu stil, exact modul în care le scrie 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 este setul care decide ce contribuie o suprapunere: xfpFont, xfpFill, xfpBorder, xfpNumberFormat, xfpAlignment și xfpProtection. Numirea doar a părților pe care le aveți în vedere este ce permite suprapunerilor să se așterne sensibil — o suprapunere de coloană care livrează un format de număr nu se luptă cu o suprapunere de rând care livrează o umplere, deoarece niciuna nu revendică partea celeilalte
Ce vă dă blocul de 256 de rânduri
Localitate. Celulele sunt ținute în blocuri de 256 de rânduri cu handle-uri publice stabile, serializate row-major, astfel încât scrierea unei foi de calcul parcurge memoria în ordinea în care va emite octeți mai degrabă decât să urmărească pointeri prin heap. Handle-urile stabile contează pentru suprafața API: un handle pe care îl ține un apelant rămâne valabil peste reorganizarea internă pe care o execută așezarea pe blocuri, ceea ce face reprezentarea compactă un detaliu de implementare mai degrabă decât o schimbare de rupere
Compactarea pool-ului de stiluri rulează alături. Înainte de fiecare salvare, fonturile, umplerile, chenarele, formatele de număr, aliniamentele și protecțiile pe care nicio celulă nu le referențiază sunt abandonate. Registrele de lucru longevive acumulează înregistrări de stil nereferențiate la fel cum documentele longevive acumulează stiluri neutilizate, iar un registru de lucru editat de un utilizator timp de o oră poate purta sute dintre ele într-un fișier din care nimeni nu le va citi vreodată
Salvarea în flux pe rânduri, și când nu se aplică
Cu StreamingWrite activat — implicit — fiecare rând de foaie de calcul este scris direct în fluxul deflate al pachetului. Alternativa, pe care fanionul o oprește, construiește întregul XML de foaie de calcul mai întâi și îl comprimă ulterior, astfel încât memoria de vârf scala cu toată foaia. Fluxul face să scaleze cu un singur rând
Șirurile partajate și părțile auxiliare urmează aceeași disciplină printr-un serializator UTF-8 reutilizabil care emite intrări una câte una, limitând memoria de vârf la cea mai mare intrare singulară mai degrabă decât la partea întreagă. Asta acoperă tabela de șiruri partajate și înregistrările pivot, care pe un registru de lucru analitic larg sunt frecvent mai mari decât orice foaie de calcul individuală
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;
Lăsați-l pornit cu excepția cazului în care aveți un motiv concret să nu o faceți. Calea ne-flux există pentru cazurile în care altceva din flux are nevoie de XML-ul asamblat, iar plătirea pentru ea implicit înseamnă să plătiți pentru un caz pe care majoritatea aplicațiilor nu îl întâlnesc niciodată
Cum spuneți dacă suprapunerile sunt de fapt folosite
Urmăriți numărul de celule, nu graficul de memorie. Dacă o foaie de calcul raportează un număr plauzibil de celule fizice după ce ați aplicat formatare largă, suprapunerile își fac treaba. Dacă numărul sare cu dimensiunea intervalului formatat, ceva din calea de cod a materializat celulele — de obicei o buclă care citește fiecare celulă din interval pentru a-i verifica stilul, ceea ce forțează rezolvarea o celulă la un moment dat și învinge întregul aranjament
Rezolvați un stil când aveți nevoie de formatul efectiv al unei singure celule. Nu rezolvați un stil pentru un milion de celule pentru a afla că acea coloană are un format de număr; întrebați suprapunerea. Aceeași regulă se aplică la scriere: atribuiți valori celulelor care au valori, iar lăsați formatarea să rămână un interval
Unde se mai duce memoria rămasă
Odată ce celulele și stilurile sunt compacte, următorii cei mai mari consumatori pe un registru de lucru mare sunt tabela de șiruri partajate și orice părți satelit pe care le poartă fișierul — cache-uri pivot, desene, XML păstrat de la părți pe care modelul de obiecte nu le modelează. Acelea au strategiile lor, iar răspunsul onest este că nicio setare singulară nu le rezolvă pe toate odată
Dacă blocajul este la deschidere mai degrabă decât la salvare, încărcarea selectivă este pârghia: prezentarea detaliată despre încărcarea doar-metadate și selectivă a foilor de calcul acoperă citirea unui registru de lucru fără să plătiți pentru foile pe care nu le veți atinge. Pentru throughput pe calea de citire pe fișiere foarte mari, vedeți notele despre analiza XLSX paralelă și alocatorul de memorie, iar pentru sarcini doar-ieșire care nu au nevoie deloc de model de obiecte, scrierile în flux pentru sarcini de lot pe server este de obicei o potrivire mai bună decât oricâtă reglare aici
HotXLS citește și scrie XLS și XLSX din cod Delphi și C++Builder nativ fără instalare de Excel și fără automatizare OLE, ceea ce face aceste caracteristici de memorie observabile și controlabile în primul rând — pagina componentei de foi de calcul HotXLS listează formatele suportate și versiunile RAD Studio