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.