Технічна стаття

Метадані-only та вибіркове завантаження XLSX з HotXLS

HotXLS здатен відкрити книгу XLSX й не розбирати жодної комірки аркуша. TXLSXWorkbook.MetadataOnly читає властивості книги, визначені імена, імена аркушів та стани видимості, стилі, тему, з'єднання та зовнішні посилання, а тоді зупиняється перед XML комірок. Для сканера, якому треба знати, що лежить у каталозі книг, це різниця між хвилинами та секундами

Три споріднені перемикачі завершують картину: SelectedSheets розбирає комірки для іменованої підмножини, LoadSheet матеріалізує пропущений аркуш пізніше з оригінального архіву, а PreserveRawParts копіює стиснені байти незмінених частин прямо далі під час збереження. Разом вони перетворюють «відкрити книгу» з операції «все або нічого» на те, що можна обмежити

Що можна дізнатися, не розбираючи жодної комірки?

Більше, ніж потрібно більшості завдань виявлення. Із MetadataOnly, установленим до Open, книга повертається, несучи імена аркушів та стани видимості, визначені імена, властивості документа, стилі та тему, зовнішні посилання та з'єднання. Аркуші присутні як об'єкти з нульовою кількістю комірок

Це саме та інформація, на якій працює каталогізація, аудит або рішення про маршрутизацію. Які книги визначають ім'я TaxRate? У яких є приховані аркуші? Які посилаються на сервер, що виведено з експлуатації? Відповіді на ці питання повним завантаженням кожного файла — так щонічне завдання стає завданням на всю ніч

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;

Завантаження двох аркушів із сорока

SelectedSheets — це TStringList імен аркушів. Коли він непорожній, Open розбирає XML комірок лише для аркушів, які він називає; кожен інший аркуш зберігає коректне ім'я та стан видимості й не містить комірок. Порожній список означає попередню поведінку — завантажити все

Взаємодію з MetadataOnly варто висловити прямо, бо переплутане місцями дає дивну порожню книгу: MetadataOnly = True переважає вибір і пропускає всі аркуші. Використовуйте щось одне. Виявлення використовує лише метадані; цілева робота — вибір

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) матеріалізує пропущений аркуш за вимогою з оригінального архіву, що й робить цей шаблон придатним в інтерактивному застосунку, а не лише в партії. Відкрийте з аркушем, на який дивиться користувач, завантажте решту, коли він клікне. Архів залишається відкритим саме з цієї причини, тож тримайте книгу живою, поки користувач може попросити інший аркуш

Чому цикл туди-сюди змінює частини, яких ви не торкалися?

Тому що наївне збереження регенерує все. Розпакуйте тему, побудуйте об'єктну модель, серіалізуйте її назад, перепакуйте — і тепер байти різні, хоча в темі нічого не змінилося. Для проєктів VBA та кешів зведених таблиць це гірше, ніж марно, бо ці частини несуть структуру, яку об'єктна модель не повністю репрезентує

PreserveRawParts відповідає на це, копіюючи стислене подання незмінених частин безпосередньо з вихідного архіву під час SaveAs. Тема, проєкт VBA, зведені таблиці та кеші зведених таблиць переносяться як байти, коли їх не змінювали. Без розпакування, без перепакування, без ризику щось утратити в циклі серіалізації

Ціна — обмеження, яке у вас уже було: вихідний архів має все ще бути доступний під час збереження. Якщо ваш робочий процес читає файл у пам'ять, закриває його та зберігає через годину, шляху сирого копіювання брати нізвідки. Тримайте джерело доступним упродовж життя книги, що є тією самою вимогою, яку ставить LoadSheet

Конвеєр виявлення, що навмисно відкриває двічі

Шаблон, що працює у виробництві, має два проходи й нічого хитрого. Перший прохід відкриває лише метадані та приймає рішення. Другий прохід відкриває файли, що важать, із вибором аркушів і робить роботу. Повторне відкритя здається марнотратним, поки не порахуєте, чого уникнув перший прохід: другий відкриття — єдине, що розбирає комірки, і розбирає лише аркуші, що їх перший прохід обрав

// 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);

Не намагайтеся підвищити книгу лише з метаданими на місці, очистивши прапорець після Open. Прапорець читається під час відкриття; очищення після нього нічого не змінює для книги, чий XML комірок ніколи не відвідувався

Куди це вписується з іншими важелями великих файлів

Вибіркове завантаження зменшує те, що ви розбираєте. Воно не зменшує того, що коштує аркуш після завантаження, і не допомагає, коли вам справді потрібна кожна комірка кожного аркуша. Для цього випадку відповідна робота лежить на боці зберігання, описана в нотатках про зберігання комірок рядковими блоками та інтервальні накладання стилів, а на боці розбору — у паралельному розборі XLSX та алокаторі пам'яті. Коли завданням є чисте сканування взагалі без редагування, потоковий прямий читач оминає об'єктну модель цілком і обійде будь-яку стратегію завантаження, що її будує

HotXLS відкриває файли XLS та XLSX з рідного коду Delphi та C++Builder без залежності від Excel, тож серверне завдання виявлення працює з нічим не встановленим, окрім вашого власного виконуваного файла — дивіться сторінку компонента електронних таблиць HotXLS щодо підтримуваних форматів та ліцензування