HotXLS schrijft ISO/IEC 29500 Strict Open XML-werkmappen vanuit Delphi en C++Builder door vóór het opslaan één enkele eigenschap in te stellen, StrictOOXML. Elk onderdeel in het pakket, van xl/workbook.xml tot en met de relatiebestanden en content types, wordt geschreven met de strikte purl.oclc.org-vocabulaires in plaats van de transitionele schemas.openxmlformats.org-vocabulaires, en functies die Strict niet toestaat, worden geweigerd met een expliciete uitzondering in plaats van toch te worden weggeschreven
De meeste ontwikkelaars komen deze eis tegen via een aanbestedingsdocument. Aanbestedingen in de publieke sector in verschillende jurisdicties vragen om de ISO-gestandaardiseerde vorm van Open XML, niet de transitionele vorm die Office standaard schrijft, en een archief dat ISO 29500 Strict verplicht stelt, weigert een normaal .xlsx-bestand, ook al opent Excel het probleemloos. De transitionele namespaces bestaan om legacy binair gedrag te accommoderen; de strikte namespaces zijn de eigenlijke standaard
Wat verschilt er eigenlijk tussen Strict en Transitional?
Het zichtbare verschil is de vocabulaire. Een strikt werkmaponderdeel declareert http://purl.oclc.org/ooxml/spreadsheetml/main als root-namespace en http://purl.oclc.org/ooxml/officeDocument/relationships voor relatieverwijzingen, en geen enkele transitionele namespace mag ergens in het pakket overleven. Relatietypen veranderen mee, dus het root-relatieonderdeel noemt .../ooxml/officeDocument/relationships/officeDocument in plaats van het vertrouwde openxmlformats-equivalent, en het type voor uitgebreide eigenschappen wordt in camelCase geschreven als extendedProperties
Het onzichtbare verschil is het bereik. Strict laat bewust delen van het transitionele schema weg die alleen bestonden om legacy binaire bestanden rondtrip-compatibel te maken, samen met de leveranciersextensies die Office er later aan toevoegde. Daarom is de conversie geen zoek-en-vervang-actie over strings: sommige functies hebben simpelweg geen strikte spelling en mogen helemaal niet worden geschreven
Het inschakelen
Gewone code voor het opstellen verandert niet. Bouw de werkmap zoals u altijd doet, stel de vlag in en sla op:
var
Wb: TXLSXWorkbook;
Sh: TXLSXWorksheet;
begin
Wb := TXLSXWorkbook.Create;
try
Sh := Wb.Sheets.Add('Data');
Sh.Cells[1, 1].Value := 'Product';
Sh.Cells[1, 2].Value := 'Amount';
Sh.Cells[2, 1].Value := 'Widget';
Sh.Cells[2, 2].Value := 17;
Sh.Cells[3, 2].Formula := '=SUM(B2:B2)';
Wb.StrictOOXML := True; // ISO/IEC 29500 Strict-uitvoer
if Wb.SaveAs('archive-copy.xlsx') <> 1 then
raise Exception.Create('strict save failed');
finally
Wb.Free;
end;
end;
De vlag wordt aan het begin van elke opslagbewerking gereset en opnieuw toegewezen vanuit de werkmapeigenschap, zodat een uitzondering tijdens de ene opslagbewerking geen strikte modus kan laten doorlekken naar de volgende. Dat detail doet ertoe in serverprocessen waar één werkmapobject meerdere exportverzoeken bedient
Waarom kan een strikte opslag weigeren te draaien?
Vier functiefamilies zijn Microsoft-extensies zonder ISO 29500 Strict-equivalent, en HotXLS werpt bij het opslaan een uitzondering in plaats van een pakket te produceren dat strikte conformiteit claimt terwijl dat niet zo is:
// Strict-uitvoer kan geen VBA-project insluiten
// -> sla macro-ingeschakelde werkmappen op als transitioneel .xlsm
// Strict-uitvoer kan geen formuliercontrols dragen
// -> knoppen, selectievakjes, keuzelijsten en hun ctrlProps
// Strict-uitvoer kan geen threaded comments dragen
// -> het moderne persons/threads-model, niet klassieke notities
// Strict-uitvoer kan geen metadata voor dynamische arrays dragen
// -> spill-bereiken vastgelegd via het metadata-onderdeel
Luid falen is hier de juiste afweging. Een stilzwijgend weggevallen VBA-project verandert een werkende werkmap in een kapotte werkmap die nog steeds opent, en het foutrapport komt weken later binnen via een gebruiker. Een uitzondering benoemt de functie en de eigenschap die moet worden gewijzigd, terwijl de aanroepende code nog weet wat ze aan het exporteren was. Behoud van macro's en externe links op het transitionele pad wordt behandeld in het behouden van VBA-projecten en externe links
Twee extensiefamilies worden anders behandeld, en het is de moeite waard om te weten waarom. Databalken, sparklines en vergelijkbare functies bevinden zich in de x14- en xm-vocabulaires, en de SVG-varianten van afbeeldingen bevinden zich in c15. Dit is extension-list-inhoud waarvan de namespaces zelfbeschrijvend zijn, algemene spreadsheetparsers tolereren ze, en er is geen ISO-equivalent om ze naar te vertalen. HotXLS behoudt ze in plaats van gebruikersinhoud te laten vallen. Als een validator in uw pijplijn even strikt is over extensies als over namespaces, verwijder die functies dan uit de bronwerkmap vóór het exporteren
Vertaling moet onderdelen bereiken die niemand normaal herschrijft
Het interessante technische probleem bij strikte uitvoer is niet de werkblad-XML. Het zijn de onderdelen die een snelle writer liever letterlijk zou kopiëren. HotXLS behoudt thema's, verbindingen, externe links, grafieken en draaitabel-blobs door hun originele gecomprimeerde bytes rechtstreeks door te kopiëren, wat precies het juiste is voor getrouwheid en precies het verkeerde voor strikte uitvoer, omdat gekopieerde bytes transitionele namespaces met zich meedragen
Onder StrictOOXML schakelen die vijf behouden paden over naar herbouw of naar een vertalende replay, waarbij het snelle byte-kopieerpad wordt omzeild. Alle XML gaat door één vertaalroutine, die verankert op dubbel aangehaalde attribuutwaarden, zodat een string die op een URI lijkt binnen een cel nooit per ongeluk kan worden herschreven. Celtekst die dezelfde URI bevat, wordt in de XML geëscaped als entiteit, zodat de verankerde vervanging deze niet kan zien. De streaming writer vertaalt eerst zijn skelet en splitst dan bij sheetData, omdat de rijblokken helemaal geen vocabulaire-URI's bevatten. Verwante mechanica voor het behoudpad wordt behandeld in verliesvrije round-trips van thema's, extension lists en calcChain
Bestanden lezen die Excel als strict heeft opgeslagen
Uitvoer is maar het halve verhaal. Excel biedt "Strict Open XML Spreadsheet" als opslagoptie, en bestanden die op die manier zijn geproduceerd, moeten correct openen. HotXLS normaliseert relatietypen op elke plek in het pakket waar relaties worden geparst: de root, externe links, werkbladen, tekeningen en draaitabellen, zodat een strikt relatietype overeenkomt met dezelfde interne constante als zijn transitionele tegenhanger
De tegenhanger aan de lezerskant is normalisatie van namespace-prefixen, waardoor willekeurige prefixen en beide vocabulaires kunnen worden herleid tot één canonieke naamtabel. Dat werk komt zowel gewone als strikte bestanden ten goede, aangezien generatoren van derden prefixen vrij toekennen, en het is dezelfde machinerie beschreven in OPC-relatieresolutie in XLSX-pakketten
Een korte checklist voordat u strikte uitvoer uitlevert
Verifieer met het pakket, niet met Excel. Excel opent beide vormen probleemloos, dus een succesvolle opening bewijst niets over conformiteit. Pak het resultaat uit en bevestig dat xl/workbook.xml de purl-namespace declareert, dat geen enkel onderdeel schemas.openxmlformats.org/spreadsheetml bevat, en dat relatietypen in _rels/.rels en xl/_rels/workbook.xml.rels de strikte vormen gebruiken
Open het bestand vervolgens opnieuw via HotXLS en vergelijk waarden, formules, opmaak en hyperlinks met de bron. Een terugleestest is de enige goedkope manier om te bewijzen dat de vertaling de inhoud niet heeft beschadigd, en oefent tegelijk de normalisatie aan de lezerskant. Als uw werkmappen grafieken bevatten, controleer die ook, aangezien het grafiekonderdeel een van de behouden onderdelen is dat onder strikte modus overschakelt naar een herbouwd pad
Strikte uitvoer, tolerante lezing en verliesvrij behoud maken allemaal deel uit van dezelfde OOXML-engine voor Delphi en C++Builder; de volledige functielijst staat op de HotXLS Delphi-spreadsheetcomponentpagina