Műszaki cikk

ISO 29500 Strict XLSX-fájlok írása Delphiből

A HotXLS egyetlen tulajdonság, a StrictOOXML mentés előtti beállításával ír ISO/IEC 29500 Strict Open XML munkafüzeteket Delphiből és C++Builderből. A csomag minden része, az xl/workbook.xml-től egészen a kapcsolatfájlokig és a tartalomtípusokig, a szigorú purl.oclc.org szókészletekkel íródik az átmeneti schemas.openxmlformats.org szókészletek helyett, azokat a funkciókat pedig, amelyeket a Strict nem enged meg, egyértelmű kivétellel utasítja el, ahelyett hogy egyszerűen kiírná őket

A legtöbb fejlesztő egy beszerzési dokumentumon keresztül találkozik ezzel a követelménnyel. Több joghatóság közbeszerzési kiírása az Open XML ISO-szabványosított formáját kéri, nem az Office által alapértelmezetten írt átmeneti formát, és egy olyan archívum, amely ISO 29500 Strictet ír elő, elutasít egy normál .xlsx-et is, még akkor is, ha az Excel tökéletesen megnyitja. Az átmeneti névterek a régi bináris viselkedés kiszolgálására léteznek; a szigorúak maga a szabvány

Mi különbözik valójában a Strict és a Transitional között?

A látható különbség a szókészlet. Egy strict munkafüzet-rész a http://purl.oclc.org/ooxml/spreadsheetml/main címet deklarálja gyökér-névtérként, és a http://purl.oclc.org/ooxml/officeDocument/relationships-t a kapcsolathivatkozásokhoz, és a csomagban sehol nem maradhat fenn átmeneti névtér. Ezzel együtt a kapcsolattípusok is változnak, így a gyökérkapcsolatok rész a .../ooxml/officeDocument/relationships/officeDocument nevet viseli az ismert openxmlformats megfelelő helyett, a kiterjesztett tulajdonságok típusa pedig camelCase formában extendedProperties

A láthatatlan különbség a hatókör. A Strict szándékosan kihagyja az átmeneti séma azon részeit, amelyek kizárólag a régi bináris fájlok oda-vissza konvertálásához léteztek, valamint az Office által utólag hozzáadott gyártói kiterjesztéseket. Ezért a konverzió nem egyszerű szöveges keresés-csere: egyes funkcióknak egyszerűen nincs szigorú megfelelőjük, és egyáltalán nem szabad kiírni őket

Bekapcsolása

A szokásos létrehozó kód nem változik. Építsd fel a munkafüzetet ugyanúgy, mint mindig, állítsd be a jelzőt, és mentsd el:

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 kimenet
    if Wb.SaveAs('archive-copy.xlsx') <> 1 then
      raise Exception.Create('strict save failed');
  finally
    Wb.Free;
  end;
end;

A jelző minden mentési művelet elején visszaáll, és a munkafüzet-tulajdonságból kerül újra kiosztásra, így egy mentés közbeni kivétel nem szivároghat át strict módként a következőbe. Ez a részlet olyan szerverfolyamatokban számít, ahol egyetlen munkafüzet-objektum több exportkérést szolgál ki

Miért utasíthat vissza a strict mentés a futást?

Négy funkciócsalád Microsoft-kiterjesztés, amelyeknek nincs ISO 29500 Strict megfelelőjük, és a HotXLS mentéskor kivételt dob, ahelyett hogy olyan csomagot állítana elő, amely szigorú megfelelőséget állít, miközben nem az:

// A Strict kimenet nem ágyazhat be VBA-projektet
//   -> a makróengedélyezett munkafüzeteket átmeneti .xlsm-ként mentsd
// A Strict kimenet nem hordozhat űrlapvezérlőket
//   -> gombok, jelölőnégyzetek, legördülő listák és ctrlProps-jaik
// A Strict kimenet nem hordozhat szálas megjegyzéseket
//   -> a modern persons/threads modellt, nem a klasszikus jegyzeteket
// A Strict kimenet nem hordozhat dinamikus tömb metaadatokat
//   -> a metaadat-részen keresztül rögzített spill-tartományokat

A hangos elbukás itt a helyes megoldás. Egy csendben eldobott VBA-projekt egy működő munkafüzetet olyan hibássá tesz, amely még mindig megnyílik, a hiba jelentése pedig hetekkel később érkezik egy felhasználótól. Egy kivétel megnevezi a funkciót és a módosítandó tulajdonságot, miközben a hívó kód még tudja, mit exportált. A makrók és a külső hivatkozások megőrzését az átmeneti útvonalon a VBA-projektek és külső hivatkozások megőrzése ismerteti

Két kiterjesztéscsaládot eltérően kezel a rendszer, és érdemes tudni, miért. Az adatsávok, mini diagramok és hasonló funkciók az x14 és xm szókészletekben élnek, a képek SVG-változatai pedig a c15-ben. Ezek olyan kiterjesztéslista-tartalmak, amelyek névterei önleíróak, az általános táblázatkezelő-elemzők tolerálják őket, és nincs olyan ISO-megfelelő, amelyre le lehetne fordítani őket. A HotXLS megtartja ezeket, ahelyett hogy elveszítené a felhasználói tartalmat. Ha a folyamatodban lévő validátor a névterek mellett a kiterjesztésekre nézve is szigorú, távolítsd el ezeket a funkciókat a forrás-munkafüzetből az exportálás előtt

A fordításnak olyan részekhez is el kell jutnia, amelyeket senki nem szokott újraírni

A strict kimenet érdekes mérnöki problémája nem a munkalap XML-je. Azok a részek okozzák, amelyeket egy gyors író inkább szó szerint másolna. A HotXLS a témákat, kapcsolatokat, külső hivatkozásokat, diagramokat és pivot-blobokat úgy őrzi meg, hogy az eredeti tömörített bájtjaikat egyenesen átmásolja, ami a hűség szempontjából pontosan a helyes megoldás, a strict kimenet szempontjából viszont pontosan a rossz, mert a másolt bájtok átmeneti névtereket hordoznak

A StrictOOXML alatt ez az öt megőrzött útvonal átvált újraépítésre vagy fordító visszajátszásra, megkerülve a bájtmásoló gyors útvonalat. Minden XML egyetlen fordítási rutinon megy keresztül, amely az idézőjelbe zárt attribútumértékekhez rögzít, így egy cellán belüli, URI-nak tűnő string soha nem íródhat felül véletlenül. Az ugyanazt az URI-t tartalmazó cellaszöveg entitásként van escape-elve az XML-ben, így a rögzített csere nem látja azt. A streamelő író először a vázát fordítja le, majd a sheetData-nál bontja szét, mivel a sorblokkok egyáltalán nem tartalmaznak szókészlet-URI-kat. A megőrzési útvonal kapcsolódó mechanizmusait a témák, kiterjesztéslisták és calcChain veszteségmentes oda-vissza konvertálása ismerteti

Excel által strictként mentett fájlok olvasása

A kimenet csak a történet fele. Az Excel a „Strict Open XML Spreadsheet” lehetőséget kínálja mentési opcióként, és az így előállított fájloknak helyesen kell megnyílniuk. A HotXLS normalizálja a kapcsolattípusokat a csomag minden kapcsolatelemző pontján, a gyökérnél, a külső hivatkozásoknál, a munkalapoknál, a rajzoknál és a pivot táblázatoknál, így egy strict kapcsolattípus ugyanarra a belső konstansra illeszkedik, mint az átmeneti megfelelője

Az olvasó oldali megfelelője a névtér-előtag normalizálás, amely lehetővé teszi, hogy tetszőleges előtagok és mindkét szókészlet egyetlen kanonikus névtáblára oldódjon fel. Ez a munka a normál fájloknak is hasznára válik, nemcsak a stricteknek, mivel a harmadik féltől származó generátorok szabadon köthetnek előtagokat, és ez ugyanaz a gépezet, amelyet az OPC-kapcsolatfeloldás XLSX-csomagokban ismertet

Rövid ellenőrzőlista, mielőtt élesbe állítod a strict kimenetet

A csomaggal ellenőrizz, ne az Excellel. Az Excel mindkét formát boldogan megnyitja, így egy sikeres megnyitás semmit nem bizonyít a megfelelőségről. Csomagold ki az eredményt, és győződj meg róla, hogy az xl/workbook.xml a purl névteret deklarálja, hogy egyetlen rész sem tartalmazza a schemas.openxmlformats.org/spreadsheetml-t, és hogy a _rels/.rels-ben és az xl/_rels/workbook.xml.rels-ben szereplő kapcsolattípusok a strict formákat használják

Ezután nyisd meg újra a fájlt a HotXLS-en keresztül, és hasonlítsd össze az értékeket, képleteket, formátumokat és hivatkozásokat a forrással. A visszaolvasási teszt az egyetlen olcsó módja annak bizonyítására, hogy a fordítás nem károsította a tartalmat, és egyúttal az olvasó oldali normalizálást is próbára teszi. Ha a munkafüzeteid diagramokat is tartalmaznak, azokat is ellenőrizd, mivel a diagramrész az egyik olyan megőrzött rész, amely strict módban újraépített útvonalra vált

A strict kimenet, a toleráns olvasás és a veszteségmentes megőrzés mind ugyanannak az OOXML-motornak a részei Delphihez és C++Builderhez; a teljes funkciólista a HotXLS Delphi táblázatkezelő-komponens oldalán található