Technical Article

Mengekstrak Informasi Ringkasan Dokumen dari File Excel di Delphi

Saat memproses file spreadsheet Excel dalam jumlah besar di jalur otomatis, Anda jarang ingin memuat seluruh dokumen ke dalam memori hanya untuk mengetahui apa itu. Sering kali, metadata yang tertanam di dalam file, penulis, judul, tanggal pembuatan, dan properti kustom, sudah cukup untuk merutekan, mengindeks, atau menolak dokumen tersebut. Di dunia Microsoft Office, metadata ini dikenal sebagai Informasi Ringkasan Dokumen (Document Summary Information).

Mengekstrak informasi ini secara native di Delphi tanpa bergantung pada otomatisasi OLE (yang mengharuskan Excel diinstal pada mesin host) memerlukan pem-parsing-an struktur file dasar secara langsung. Dalam artikel ini, kita akan melihat bagaimana ringkasan dokumen berfungsi dalam file Excel dan bagaimana mengekstraknya secara efisien menggunakan pem-parsing-an aliran mentah.

Memahami Aliran Metadata Excel

Secara historis, file Excel lama (.xls) disimpan dalam format Dokumen Majemuk OLE (OLE Compound Document), yang secara efektif bertindak sebagai sistem file mini berisi aliran dan penyimpanan. Metadata ditempatkan dalam dua aliran spesifik:

  • SummaryInformation: Berisi properti standar seperti Judul, Subjek, Penulis, Kata Kunci, dan Nomor Revisi.
  • DocumentSummaryInformation: Berisi properti yang diperpanjang seperti Perusahaan, Manajer, dan properti kustom yang ditentukan pengguna.

File Excel modern (.xlsx) menggunakan format Office Open XML (OOXML), yang merupakan struktur XML yang dizip. Metadata di sini terletak di docProps/core.xml, docProps/app.xml, dan docProps/custom.xml. Komponen pem-parsing-an Delphi yang tangguh harus menangani kedua struktur internal dengan mulus sembari memaparkan API terpadu kepada pengembang.

Mem-parsing Dokumen Majemuk OLE di Delphi

Untuk membaca SummaryInformation dari file .xls lama tanpa alat bantu pihak ketiga, Anda perlu mem-parsing Penyimpanan Terstruktur OLE. Microsoft memaparkan hal ini melalui antarmuka COM IPropertySetStorage. Berikut adalah implementasi Delphi mentah yang menghindari memicu jalannya program Excel:

uses
  System.SysUtils, System.Win.ComObj, Winapi.ActiveX, Winapi.Windows;

procedure ExtractXlsSummaryInfo(const FileName: string);
var
  Stg: IStorage;
  PropSetStg: IPropertySetStorage;
  PropStg: IPropertyStorage;
  PropSpec: TPropSpec;
  PropVariant: TPropVariant;
  Hr: HRESULT;
begin
  // Open the OLE Compound Document
  Hr := StgOpenStorage(PWideChar(WideString(FileName)), nil,
    STGM_READ or STGM_SHARE_DENY_WRITE, nil, 0, Stg);
    
  if Failed(Hr) then
    raise Exception.Create('Failed to open OLE storage. File may not be a valid .xls document.');

  // Query for the property set storage interface
  if Stg.QueryInterface(IPropertySetStorage, PropSetStg) = S_OK then
  begin
    // Open the SummaryInformation stream (FMTID_SummaryInformation)
    Hr := PropSetStg.Open(FMTID_SummaryInformation, STGM_READ or STGM_SHARE_EXCLUSIVE, PropStg);
    if Succeeded(Hr) then
    begin
      // Read the Author property (PIDSI_AUTHOR = 4)
      PropSpec.ulKind := PRSPEC_PROPID;
      PropSpec.propid := PIDSI_AUTHOR;
      
      if PropStg.ReadMultiple(1, @PropSpec, @PropVariant) = S_OK then
      begin
        if PropVariant.vt = VT_LPSTR then
          Writeln('Author: ', string(AnsiString(PropVariant.pszVal)));
        PropVariantClear(PropVariant);
      end;
    end;
  end;
end;

Ekstraksi Terprogram dengan HotXLS

Meskipun API COM Windows berfungsi untuk file .xls, ini tidak berfungsi untuk file .xlsx modern (yang merupakan arsip ZIP). Terlebih lagi, penggunaan API COM lintas platform (misalnya, di Linux atau macOS melalui FireMonkey) adalah mustahil. Pembaruan terkini pada komponen HotXLS memperkenalkan unit khusus (misalnya, lxXlsSummary) untuk mengisolasi dan mengoptimalkan pembacaan aliran ringkasan ini di kedua format secara native dalam kode Delphi.

Contoh Lintas Platform

Dengan menggunakan antarmuka XlsReadDocumentSummaryInformation dan XlsReadSummaryInformation, Anda dapat dengan cepat mengambil string metadata dari .xls maupun .xlsx tanpa mengkhawatirkan arsitektur sistem file dasarnya.

uses
  lxXlsSummary;

var
  Summary: TXlsSummaryInfo;
  ExtendedInfo: TXlsDocumentSummaryInfo;
begin
  // Extract standard summary from an OOXML format seamlessly
  Summary := XlsReadSummaryInformation('C:\Data\FinancialReport.xlsx');
  try
    Writeln('Title: ', Summary.Title);
    Writeln('Author: ', Summary.Author);
    Writeln('Creation Date: ', DateTimeToStr(Summary.CreateTime));
  finally
    Summary.Free;
  end;

  // Extract extended document summary
  ExtendedInfo := XlsReadDocumentSummaryInformation('C:\Data\FinancialReport.xlsx');
  try
    Writeln('Company: ', ExtendedInfo.Company);
    Writeln('Manager: ', ExtendedInfo.Manager);
  finally
    ExtendedInfo.Free;
  end;
end;

Mengapa Ekstraksi Ringkasan Khusus Itu Penting

Manfaat utama dari pendekatan ini adalah kinerja dan keamanan memori. Dengan menghindari instansiasi DOM (Document Object Model) buku kerja secara penuh dan hanya mem-parsing docProps/core.xml atau aliran properti OLE, jejak aplikasi Anda tetap sangat kecil. Jika Anda mengindeks 10.000 file Excel di seluruh jaringan berbagi, upaya untuk mem-parsing secara penuh masing-masing file akan merusak memori Anda dan memakan waktu berjam-jam. Ekstraksi ringkasan khusus menyelesaikan tugas yang sama dalam hitungan detik.

Selain itu, membaca aliran secara native memastikan aplikasi Anda dapat berjalan sebagai layanan latar belakang atau pada server Linux tanpa antarmuka tanpa pernah memanggil Excel.exe, persyaratan penting untuk arsitektur modern yang dapat diskalakan.

Catatan: Alat bantu komprehensif untuk mem-parsing Excel dan mengekstrak metadata tersedia dalam Komponen VCL HotXLS.