Een spreadsheet draagt twee lagen identiteit. Er is het raster van cellen, en er zijn de documentmetagegevens die ernaast meereizen: titel, auteur, bedrijf, trefwoorden, de tijdstempels. Excel toont die tweede laag nooit in het raster, en toch is het de laag die Windows Search indexeert, de laag die SharePoint leest om een document een titel te geven, en de laag waarop een systeem voor recordbeheer archiveert. Wanneer een gegenereerde werkmap haar Author en Title erft van het sjabloon waaruit ze is gebouwd, registreert elk systeem verderop de sjabloonontwerper als auteur van vierduizend klantoverzichten. De metagegevens kloppen nergens en worden overal geraadpleegd
HotXLS brengt deze laag naar boven als gewone eigenschappen op werkmapniveau in beide engines: de BIFF-facade voor .xls en de OOXML-facade voor .xlsx. U leest een veld nadat u een bestand hebt geopend en u schrijft een veld voordat u er een opslaat. De bibliotheek beslist in welke fysieke container de waarde belandt. Wat het begrijpen waard is voordat u een generator schrijft, is welke velden elk formaat werkelijk ondersteunt, waar die velden fysiek wonen, en de ene poortregel die bepaalt of een .xlsx überhaupt metagegevens vastlegt
Twee formaten, twee opslagmodellen
De reden dat een spreadsheetbibliotheek twee implementaties van metagegevens nodig heeft, en de reden dat halfafgemaakte gereedschappen het ene formaat correct stempelen en het andere vergeten, is dat .xls en .xlsx hun eigenschappen op ongerelateerde plekken bewaren. Een BIFF-werkmap schrijft ze in OLE-samengestelde-bestandsstromen, hoofdzakelijk de eigenschappenset SummaryInformation die ouder is dan Excel zelf, naast het record WRITEACCESS in de stroom dat benoemt wie het bestand als laatste heeft opgeslagen. Een OOXML-werkmap bewaart ze als XML-onderdelen binnen het zip-pakket, gesplitst naar doel: docProps/core.xml bevat de Dublin Core-velden (titel, maker, onderwerp, trefwoorden, datums) en docProps/app.xml bevat de velden op applicatieniveau zoals bedrijf en genererende applicatie, volgens ECMA-376 deel 1
HotXLS platst beide opslagmodellen tot directe eigenschappen van het werkmapobject. U opent nooit een eigenschappenset-stroom en bewerkt nooit met de hand een XML-onderdeel. U wijst tekenreeksen en datums aan de werkmap toe, en de juiste container ontstaat vanzelf voor het formaat waarin u opslaat
Gegenereerde werkmappen stempelen vanuit het bedrijfsrecord
Aan de XLSX-kant stelt TXLSXWorkbook de velden Title, Subject, Author, Keywords, Description, Category, LastModifiedBy, Company, Application en AppVersion als tekenreeksen bloot, plus Created en Modified als TDateTime-waarden waarbij nul betekent dat ze niet zijn gezet. De regel die het overervingsgat dichttrekt, past in één zin: wijs bij elke run elk veld toe, met de waarden uit het bedrijfsrecord in plaats van te vertrouwen op wat het sjabloon toevallig meedroeg
var
Book: TXLSXWorkbook;
begin
Book := TXLSXWorkbook.Create;
try
if Book.Open('statement-template.xlsx') <> 1 then
raise Exception.Create('Template not available');
// Overschrijf elk veld: alles wat onaangeroerd blijft, wordt
// geerfd van degene die het sjabloon heeft ontworpen.
Book.Title := 'Account Statement 2026-06 / ACME Corp';
Book.Subject := 'Monthly account statement';
Book.Author := 'Billing Service 4.2';
Book.LastModifiedBy := 'Billing Service 4.2';
Book.Company := 'Northwind Financial';
Book.Category := 'Customer Delivery';
Book.Keywords := 'statement;billing;2026-06;acct-10024';
Book.Description := 'Generated document - manual edits are not retained';
Book.Created := Now;
Book.Modified := Now;
Book.SaveAs('statement-10024.xlsx');
finally
Book.Free;
end;
end;
Het veld Keywords beloont meer nadenken dan het meestal krijgt. Zoekinfrastructuur indexeert het letterlijk, zowel Windows Search als SharePoint als de meeste DMS-producten, dus een conventie met puntkomma's die het rekeningnummer en de periode meedraagt, maakt van elke geleverde werkmap een vindbaar record zonder één databaseraadpleging. Datzelfde bereik is de valstrik. Eigenschappen reizen mee met elke kopie van het bestand, ver voorbij de toegangscontroles van het systeem dat ze schreef, dus persoonsgegevens horen daar niet thuis
Het tijdstempelpaar draagt semantiek die u beter in beleid vastlegt dan aan gewoonte overlaat. Created hoort het moment te markeren waarop uw pijplijn het document genereerde en daarna bevroren te blijven. Modified is het veld dat Excel bijwerkt zodra een ontvanger het bestand opslaat, dus een verschil tussen die twee na levering is positief bewijs dat iemand de werkmap verderop heeft bewerkt, wat meer dan één geschil beslecht over wiens getallen een doorgestuurde spreadsheet werkelijk bevat. Eén valkuil schuilt in de niet-gezette toestand: dat is de letterlijke waarde nul, geen uitzondering en geen null, dus auditcode moet expliciet op nul testen. Formatteer een niet-gezette TDateTime zonder die beveiliging en uw logboeken vullen zich met een zelfverzekerd foute datum in december 1899
DocPropsTouched: de werkmap die zonder docProps de deur uitgaat
Een alleen-lezen vlag, DocPropsTouched, bewaakt de poort naar de XLSX-eigenschappenschrijver. Een werkmap waarin nooit een eigenschap is toegewezen, levert helemaal geen docProps-onderdelen op; HotXLS weigert een leeg metagegevensskelet te schrijven. Het gedrag is netjes, en het heeft twee gevolgen waar het ontwerpen omheen loont
Innamecode aan de verbruikende kant mag er niet van uitgaan dat core.xml in elk pakket bestaat. Een gereedschap dat het hard vereist, zal volkomen geldige minimale bestanden afwijzen. En als uw nalevingshouding eist dat elk uitgaand document ten minste een generatoridentiteit draagt, dan wordt die eis code in plaats van een eigenschap van het formaat: wijs Application en Author onvoorwaardelijk toe in het opslagpad, want een onaangeroerde werkmap is volledig legaal onder de specificatie terwijl ze stilletjes uw beleid schendt
Het klassieke XLS-oppervlak en de Comments-valstrik
De BIFF-facade draagt de oudere, kleinere veldenset: Title, Subject, Author, Keywords, Comments, Company en Manager, plus LastSavedBy, een alias van UserName, die het record WRITEACCESS schrijft dat Excel toont wanneer een andere gebruiker het bestand vergrendeld houdt
var
Legacy: IXLSWorkbook; // referentiegetelde interface: geen handmatige Free
begin
Legacy := TXLSWorkbook.Create;
if Legacy.Open('archive-1999.xls') <= 0 then
raise Exception.Create('Cannot open archive file');
Legacy.Title := 'FY1999 ledger (migrated copy)';
Legacy.Author := 'Archive Migration Batch';
Legacy.Company := 'Northwind Financial';
Legacy.Comments := 'Migrated 2026-06-11; source retained in cold storage';
Legacy.LastSavedBy := 'migration-svc'; // BIFF-record WRITEACCESS
Legacy.SaveAs('archive-1999-stamped.xls');
end;
Eén naamsbotsing veroorzaakt terugkerende verwarring. De eigenschap Comments op documentniveau is hier de vrije-tekstopmerking die in het eigenschappenvenster van het bestand verschijnt. Zij heeft niets te maken met celopmerkingen, die tekenlaagobjecten zijn die via een volledig aparte API aan bereiken hangen. Een codereview die "we schrijven Comments al" aanvaardt zonder te controleren welke van de twee bedoeld is, heeft een bewering over de verkeerde functie aanvaard, en dat gebeurt vaker dan de gedeelde naam zou doen vermoeden. De twee delen vier letters en geen enkele byte opslag
Metagegevens lezen bij inname, en het peilgat
Lezen is symmetrisch. Na Open komen dezelfde eigenschappen gevuld uit het bestand terug, wat een metagegevensaudit van binnenkomende werkmappen tot een korte lus maakt
var
Book: TXLSXWorkbook;
begin
Book := TXLSXWorkbook.Create;
try
if Book.Open(FileName) = 1 then
begin
Writeln(Format('%s | title="%s" author="%s" created=%s',
[ExtractFileName(FileName), Book.Title, Book.Author,
FormatDateTime('yyyy-mm-dd', Book.Created)]));
if Book.Created = 0 then
Writeln(' no creation date recorded');
end;
finally
Book.Free;
end;
end;
Houd ondertussen rekening met één beperking. Er is geen peiling die alleen de eigenschappen leest. GetSheetNames kan bladen opsommen zonder een werkmap te laden, maar Title of Author lezen vereist een volledige Open, dus metagegevenstriage over een groot archief betaalt bij elk bestand de volle parseerprijs. Aan de BIFF-kant kunt u die prijs voor alleen-lezen audits drukken door _DisableGraphics vóór het openen op true te zetten, wat de tekenlaag ronduit overslaat. Het past bij een lus die alleen eigenschappen en celstatistieken leest, en het is precies verkeerd zodra dezelfde instantie ook zou kunnen opslaan, want de overgeslagen tekeninhoud zou dan wegvallen. Wanneer de bladstructuur alleen al de verzameling kan voorfilteren, waarbij exports met één blad het voor de hand liggende zijn om over te slaan, snijden de goedkope technieken uit ons artikel over bladlijsten en lichtgewicht inspectie in het aantal bestanden dat de dure fase bereikt. En bij bulkstempeltaken, waar duizenden uitvoerbestanden worden geschreven in plaats van geïnspecteerd, gelden de doorvoerpatronen aan de schrijfkant uit ons artikel over streaming schrijven voor batchtaken onveranderd, want het toewijzen van eigenschappen voegt niets meetbaars toe aan de opslagtijd
Formaten oversteken en het lek beheersen
Eigenschappen maken binnen één facade een schone rondgang: open een .xlsx, bewerk hem, sla hem op, en de verzameling komt intact terug. Formaten oversteken is waar de aanname van gelijkwaardigheid breekt, want de veldensets van BIFF en OOXML sluiten niet één op één aan. BIFF heeft Manager en geen tijdstempels; OOXML heeft Category, Description en het paar Created/Modified. Een converter die blind kopieert, verliest alles wat het doelformaat niet kan bevatten, dus breng de velden expliciet in kaart en zet die toewijzing in uw conversiechecklist naast al het andere dat de overtocht niet overleeft
Het lek dat sjabloonoverdracht opent, loopt de andere kant op: informatie die u nooit hebt willen meesturen. Auteursnamen, interne projectlabels die in trefwoorden zijn geparkeerd, een concepttitel die niemand heeft vrijgegeven. De discipline om alles te overschrijven uit de generator hierboven is de hele verdediging, en het loont die te verifiëren zoals een buitenstaander zou doen, door het eigenschappenvenster te openen dat elke klant kan bereiken of door de .xlsx uit te pakken en docProps/core.xml rechtstreeks uit het pakket te lezen. Wat u daar ziet, is precies wat elke indexeerder verderop ziet
Die zichtbaarheid verderop is ook de reden dat een paar velden meer zorg verdienen dan de rest. Title, Author, Keywords (die als Tags verschijnen) en Comments of Description dragen het meeste indexeergewicht in SharePoint en Windows Search. Een Title die per document werkelijk uniek is en de periode en de rekening meedraagt, doet meer voor vindbaarheid dan welk mapnamenschema er ook bovenop wordt gestapeld, en het kost één toewijzing per opslag
Documenteigenschappen zijn de goedkoopste professionele afwerking die een gegenereerde werkmap kan dragen, en het meest geleverde defect wanneer niemand er eigenaar van is. Beide hier beschreven eigenschappenoppervlakken horen bij de HotXLS Delphi-component, die ze native voor XLS en XLSX schrijft zonder Excel-automatisering