Teknisk artikkel

Radblokk-cellelagring og strømmet XLSX-lagring i HotXLS

HotXLS lagrer regnearkceller i kompakte 256-rads blokker, løser rad-, kolonne- og rektangel-formatering gjennom late intervall-overlegg i stedet for å opprette celleobjekter, og strømmer hver rad rett inn i pakkens deflate-strøm ved lagring. Sammen avgjør disse tre endringene minneprofilen til en stor arbeidsbok: spiss-bruk følger den største enkelraden snarere enn størrelsen på den komplette regneark-XML-en

Grunnen til at dette betyr noe er en form som hver regnearkutvikler møter til slutt. En bruker formaterer en hel kolonne — ett klikk, én million celler — og en naiv objektmodell svarer med å allokere én million celleobjekter for å holde ett tallformat-indeks. Filen på disk forblir liten fordi XLSX-formatet uttrykker det som én enkelt <col>-oppføring. Prosessen forbliver ikke liten i det hele tatt

Hvorfor koster formatering av en kolonne mer minne enn å fylle den?

Fordi formatering ikke har noen data å rettferdiggjøre objektet. En celle med en verdi må finnes et sted. En celle som er tom men stilisert finnes kun for å bære en stilindeks, og å materialisere millioner av slike er den klassiske måten en Delphi-regnearkapplikasjon går tom for adresse-rom på en fil Excel åpner umiddelbart

Intervall-stil-overlegg fjerner behovet. En rad-, kolonne- eller rektangel-formateringsinstruksjon lagres én gang som et område pluss de stildelene den bidrar med, og løser seg lat når en celle i det området faktisk aksesseres. Overlegg overlever strukturelle redigeringer — å sette inn en rad inne i en formatert blokk flytter intervallet snarere enn å bygge det om — og de rundturerer som kompakte kolonne-, rad- og kun-stil-celle-oppføringer, noe som er nøyaktig hvordan Excel skriver dem

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 er mengden som avgjør hva et overlegg bidrar med: xfpFont, xfpFill, xfpBorder, xfpNumberFormat, xfpAlignment og xfpProtection. Å navngi kun de delene du mener er det som lar overlegg lagres fornuftig — et kolonne-overlegg som leverer et tallformat slåss ikke med et rad-overlegg som leverer en fylling, fordi ingen av dem krever den andres del

Hva 256-rads-blokken gir deg

Lokalitet. Cellene holdes i blokker på 256 rader med stabile offentlige håndtak, serialisert rad-major, slik at å skrive et regneark går gjennom minnet i den rekkefølgen det vil sende ut bytes snarere enn å jakte peker over haugen. Stabile håndtak betyr noe for API-flaten: et håndtak en oppringer holder forblir gyldig på tvers av den interne reorganiseringen blokk-layouten utfører, noe som er det som gjør den kompakte representasjonen til en implementasjonsdetalj snarere enn en brytende endring

Stilpool-kompaktering kjører ved siden av. Før hver lagring droppes skrifter, fyllinger, kanter, tallformater, justeringer og beskyttelser som ingen celle refererer. Langlivede arbeidsbøker samler urefererte stil-poster slik langlivede dokumenter samler ubrukte stiler, og en arbeidsbok som har vært redigert av en bruker i en time kan bære hundrevis av dem inn i en fil ingen noensinne vil lese dem fra

Rad-strømmet lagring, og når det ikke gjelder

Med StreamingWrite aktivert — standarden — skrives hver regnearkrad direkte inn i pakkens deflate-strøm. Alternativet, som er det flagget slår av, bygger den komplette regneark-XML-en først og komprimerer den etterpå, slik at spiss-minne skalerer med hele arket. Strømming får det til å skalere med én rad

Delte strenger og hjelpedeler følger den samme disiplinen gjennom én gjenbrukbar UTF-8-serialisator som sender ut oppføringer én av gangen, og binder spiss-minne til den største enkel-oppføringen snarere enn hele delen. Det dekker den delte streng-tabellen og pivot-poster, som på et bredt analytisk regneark ofte er større enn noe enkelt regneark

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;

La det stå på med mindre du har en konkret grunn til å ikke gjøre det. Den ikke-strømmende stien finnes for de tilfeller der noe annet i pipelinen trenger den sammensatte XML-en, og å betale for det som standard er å betale for et tilfelle de fleste applikasjoner aldri treffer

Hvordan se om overlegg faktisk brukes

Se på celleantallet, ikke minne-grafen. Hvis et regneark rapporterer et plausibelt antall fysiske celler etter at du har påført bred formatering, gjør overlegg jobben sin. Hvis antallet hopper med størrelsen på det formaterte området, materialiserte noe i kodebanen cellene — vanligvis en løkke som leser hver celle i området for å sjekke stilen, noe som fremtvinger oppløsning én celle av gangen og beseirer hele arrangementet

Løs en stil når du trenger én cells effektive format. Ikke løs en stil for en million celler for å finne ut at kolonnen har et tallformat; spør overlegget. Den samme regelen gjelder for skriving: tilordne verdier til de cellene som har verdier, og la formatering forbli et intervall

Hvor det gjenværende minnet går

Når celler og stiler er kompakte, er de neste største forbrukerne på en stor arbeidsbok den delte streng-tabellen og de satellitt-delene filen bærer — pivot-mellomlagre, tegninger, bevart XML fra deler objektmodellen ikke modellerer. De har sine egne strategier, og det ærlige svaret er at ingen enkelt innstilling løser alle på en gang

Hvis din flaskehals er åpning snarere enn lagring, er selektiv innlasting spaken: gjennomgangen av kun-metadata og selektiv regnearkinnlasting dekker å lese en arbeidsbok uten å betale for arkene du ikke vil røre. For gjennomstrømming på lese-stien på svært store filer, se notatene om parallell XLSX-parsing og minneallokatoren, og for kun-skrive-arbeidsmengder som aldri trenger en objektmodell i det hele tatt, er strømmende skriving for tjener-batch-jobber vanligvis et bedre pass enn noe som helst trimming her

HotXLS leser og skriver XLS og XLSX fra ren Delphi- og C++Builder-kode uten Excel-installasjon og uten OLE-automasjon, noe som er det som gjør disse minne-karakteristikkene observerbare og kontrollerbare i utgangspunktet — HotXLS-regnearkkomponentsiden lister de støttede formatene og RAD Studio-versjonene