Technical Article

Asiakirjan yhteenvetotietojen purkaminen Excel-tiedostoista Delphissä

Käsiteltäessä suuria eriä Excel-laskentataulukoita automaattisessa putkessa harvoin halutaan ladata koko asiakirjaa muistiin vain sen selvittämiseksi, mikä se on. Usein tiedostoon upotetut metatiedot, kuten tekijä, otsikko, luontipäivämäärä ja mukautetut ominaisuudet, riittävät asiakirjan reitittämiseen, indeksointiin tai hylkäämiseen. Microsoft Office -maailmassa tämä metatieto tunnetaan nimellä Document Summary Information (asiakirjan yhteenvetotiedot).

Tämän tiedon purkaminen natiivisti Delphissä ilman OLE-automaatiota (joka vaatii Excelin asennuksen isäntäkoneelle) vaatii taustalla olevan tiedostorakenteen suoraa jäsentämistä. Tässä artikkelissa tarkastelemme, kuinka asiakirjojen yhteenvedot toimivat Excel-tiedostoissa ja kuinka niitä voidaan purkaa tehokkaasti käyttämällä raakavirtojen jäsentämistä.

Excel-metatietovirtojen ymmärtäminen

Historiallisesti vanhemmat Excel-tiedostot (.xls) on tallennettu OLE Compound Document -muotoihin, jotka toimivat käytännössä minitiedostojärjestelminä sisältäen virtoja ja tallennustiloja. Metatiedot on sijoitettu kahteen tiettyyn virtaan:

  • SummaryInformation: Sisältää vakio-ominaisuudet, kuten otsikko, aihe, tekijä, avainsanat ja revisionumero.
  • DocumentSummaryInformation: Sisältää laajennettuja ominaisuuksia, kuten yritys, esihenkilö ja mukautettuja käyttäjän määrittelemiä ominaisuuksia.

Nykyaikaiset Excel-tiedostot (.xlsx) käyttävät Office Open XML (OOXML) -muotoa, joka on pakattu XML-rakenne. Täällä metatiedot sijaitsevat tiedostoissa docProps/core.xml, docProps/app.xml ja docProps/custom.xml. Vankan Delphi-jäsennyskomponentin on käsiteltävä saumattomasti molempia sisäisiä rakenteita samalla kun se tarjoaa yhtenäisen sovellusliittymän kehittäjälle.

OLE Compound Document -tiedostojen jäsentäminen Delphissä

Lukeaksesi SummaryInformation-tiedot vanhasta `.xls`-tiedostosta ilman kolmannen osapuolen työkaluja, sinun on jäsennettävä OLE-rakenteellinen tallennustila. Microsoft paljastaa tämän COM-rajapinnan IPropertySetStorage kautta. Tässä on raaka Delphi-toteutus, joka välttää Excelin käynnistämisen:

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;

Ohjelmallinen purkaminen HotXLS:n avulla

Vaikka Windowsin COM-sovellusliittymä toimii `.xls`-tiedostoille, se ei toimi nykyaikaisille `.xlsx`-tiedostoille (jotka ovat ZIP-arkistoja). Lisäksi COM-sovellusliittymän käyttö eri alustoilla (esim. Linuxissa tai macOS:ssä FireMonkeyn kautta) on mahdotonta. HotXLS-komponentin viimeisimmät päivitykset toivat mukanaan erilliset yksiköt (esim. lxXlsSummary) eristämään ja optimoimaan näiden yhteenvetovirtojen lukemista molemmissa muodoissa täysin natiivisti Delphi-koodissa.

Monialustainen esimerkki

Käyttämällä XlsReadDocumentSummaryInformation- ja XlsReadSummaryInformation-rajapintoja voit nopeasti napata metatietomerkkijonot sekä `.xls`- että `.xlsx`-tiedostoista huolehtimatta taustalla olevasta tiedostojärjestelmäarkkitehtuurista.

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;

Miksi omistettu yhteenvedon purkaminen on tärkeää

Tämän lähestymistavan ensisijainen etu on suorituskyky ja muistiturvallisuus. Välttämällä koko työkirjan DOM:n (Document Object Model) ilmentämistä ja jäsentämällä vain docProps/core.xml-tiedoston tai OLE-ominaisuusvirrat, sovelluksesi jalanjälki pysyy uskomattoman pienenä. Jos indeksoit 10 000 Excel-tiedostoa verkkolevyltä, jokaisen täydellinen jäsentäminen kuormittaa muistiasi raskaasti ja kestää tunteja. Omistettu yhteenvedon purkaminen suorittaa saman tehtävän sekunneissa.

Lisäksi virtojen lukeminen natiivisti varmistaa, että sovelluksesi voi toimia taustapalveluna tai Linux-palvelimella ilman graafista käyttöliittymää ilman, että Excel.exe-ohjelmaa koskaan käynnistetään. Tämä on kriittinen vaatimus nykyaikaisille skaalautuville arkkitehtuureille.

Huomautus: Kattavat Excel-jäsennys- ja metatietojen purkutyökalut ovat saatavilla HotXLS VCL -komponentissa.