Technický článek

Načítání XLSX pouze z metadat a selektivní načítání s HotXLS

HotXLS umí otevřít sešit XLSX a nenaparsovat vůbec žádné buňky listu. TXLSXWorkbook.MetadataOnly přečte vlastnosti sešitu, definované názvy, názvy listů a stavy viditelnosti, styly, motiv, připojení a externí odkazy a pak se zastaví před cell XML. Pro skener, který potřebuje vědět, co je v adresáři sešitů, to je rozdíl mezi minutami a sekundami

Tři související přepínače dotvářejí obraz: SelectedSheets parsuje buňky pro pojmenovanou podmnožinu, LoadSheet materializuje přeskočený list později z původního archivu a PreserveRawParts kopíruje komprimované bajty nezměněných částí rovnou při ukládání. Společně mění „otevřít sešit" z jedné all-or-nothing operace v něco, co lze vymezit

Co se dá zjistit bez parsování jediné buňky?

Víc než většina discovery úloh potřebuje. S MetadataOnly nastaveným před Open se sešit vrátí nesoucí názvy listů a stavy viditelnosti, definované názvy, vlastnosti dokumentu, styly a motiv, externí odkazy a připojení. Listy jsou přítomny jako objekty s nulou buněk

To je přesně informace, na kterých běží katalog, audit nebo rozhodnutí o routování. Které sešity definují název TaxRate? Které mají skryté listy? Které odkazují na server, který byl vyřazen? Odpovídat na to plným načtením každého souboru je cesta, jak se noční úloha stane celonoční

var
  Workbook: TXLSXWorkbook;
  I: Integer;
begin
  Workbook := TXLSXWorkbook.Create(nil);
  try
    Workbook.MetadataOnly := True;      // set before Open
    Workbook.Open(FileName);
    for I := 1 to Workbook.Sheets.Count do      // Sheets[] is 1-based
      if not Workbook.Sheets[I].Visible then
        Report.Add(FileName + ': hidden sheet ' +
          Workbook.Sheets[I].Name);
  finally
    Workbook.Free;
  end;
end;

Načtení dvou listů ze čtyřiceti

SelectedSheets je TStringList názvů listů. Když není prázdný, parsuje Open cell XML jen pro listy, které jmenuje; každý jiný list si ponechá správný název a stav viditelnosti a nedrží buňky. Prázdný seznam znamená předchozí chování, tedy načtení všeho

Interakce s MetadataOnly stojí za to říct na rovinu, protože její prohození produkuje matoucí prázdný sešit: MetadataOnly = True přepíše výběr a přeskočí všechny listy. Použijte jedno nebo druhé. Discovery používá pouze metadata; cílená práce používá výběr

Workbook.SelectedSheets.Add('Summary');
Workbook.SelectedSheets.Add('Q3 Detail');
Workbook.Open('consolidated-2026.xlsx');
// Later, when the user opens a tab you skipped.
// LoadSheet takes the 0-based position and needs the source file,
// so it does not work on a workbook opened from a stream
if Workbook.LoadSheet(ZeroBasedPosition) then
  Grid.Refresh;

LoadSheet(Index) materializuje přeskočený list na vyžádání z původního archivu, což je to, co umožňuje tento vzor použít v interaktivní aplikaci místo jen v dávce. Otevřete s listem, na který se uživatel dívá, a načtete ostatní, když na ně klikne. Archiv zůstává otevřený přesně z tohoto důvodu, takže držte sešit živý tak dlouho, dokud může uživatel žádat o další list

Proč round trip mění části, kterých jste se ani nedotkli?

Protože naivní uložení regeneruje všechno. Dekomprimujte motiv, postavte objektový model, serializujte ho zpět, rekomprimujte — a bajty se liší, přestože se o motivu nic nezměnilo. U VBA projektů a pivot caches je to horší než plýtvání, protože ty části nesou strukturu, kterou objektový model plně nereprezentuje

PreserveRawParts to řeší tak, že během SaveAs kopíruje komprimovanou reprezentaci nezměněných částí přímo ze zdrojového archivu. Motiv, VBA projekt, pivot tabulky a pivot caches se přesouvají jako bajty, pokud nebyly modifikovány. Žádná dekomprese, žádná rekomprese, žádné riziko, že se něco ztratí v serializačním round tripu

Cenou je omezení, které jste už měli: zdrojový archiv musí být v době uložení stále k dispozici. Pokud vaše roura načte soubor do paměti, zavře ho a uloží o hodinu později, raw-copy cesta nemá odkud kopírovat. Držte zdroj dosažitelný po dobu života sešitu, což je stejný požadavek, který klade LoadSheet

Discovery roura, která účelně znovuotevírá

Vzor, který funguje v produkci, má dva průchody a žádnou chytrost. První průchod otevře pouze metadata a rozhodne. Druhý průchod znovuotevře soubory, na kterých záleží, s výběrem listů a odpracuje to. Znovuotevření působí plýtvavě, dokud nepočítáte, čemu se první průchod vyhnul: druhé otevření je to jediné, které parsuje buňky, a parsuje jen listy, které první průchod vybral

// Pass 1: discovery
Workbook.MetadataOnly := True;
Workbook.Open(FileName);
Wanted := SheetsMatching(Workbook, 'Invoice');
Workbook.Free;

// Pass 2: targeted load
Workbook := TXLSXWorkbook.Create(nil);
Workbook.SelectedSheets.AddStrings(Wanted);
Workbook.Open(FileName);

Nepokoušejte se metadata-only sešit povýšit in place tím, že byste příznak vyčistili po Open. Příznak se čte během otevírání; jeho vyčištění dodatečně nic nezmění na sešitu, jehož cell XML nikdy nebylo navštíveno

Kam to zapadá mezi ostatní páky velkých souborů

Selektivní načítání snižuje to, co parsujete. Nesnižuje náklad na list, jak je jednou načten, a nepomáhá, když skutečně potřebujete každou buňku každého listu. Pro tento případ je relevantní práce na straně úložiště, popsaná v poznámkách k row-block buněčnému úložišti a interval style overlay, a na straně parsování v paralelním parsování XLSX a alokátoru paměti. Když je úlohou čistý scan bez úprav, streaming direct reader přeskakuje objektový model úplně a přebije jakoukoli load strategii, která ho staví

HotXLS otevírá soubory XLS a XLSX z nativního kódu Delphi a C++Builder bez závislosti na Excelu, takže server-side discovery úloha běží bez toho, aby bylo instalováno cokoliv mimo váš vlastní spustitelný soubor — viz stránka spreadsheet komponenty HotXLS pro podporované formáty a licencování