Word dokumentum generálása adatkötéssel – 5. rész: A kód neve

Az előző részben láttuk, hogyan kapcsolódik a DOCX állományban lévő customXml part kétirányú adatkötéssel a content control vezérlőkhöz. Ha ezzel a módszerrel akarunk programozottan dokumentumot előállítani, akkor már csak egyetlen lépés van hátra: olyan kódot kell írnunk, amely belenyúl az Open XML állományba és felülírja a korábban már odatett XML partot, aminek tartalma azután az adatkötéseken keresztül automatikusan megjelenik a felhasználó számára.

A feladat megoldásában a System.IO.Packaging névtér nagy segítségünkre lesz. A Package osztály segítségével meg tudjuk nyitni a DOCX fájlt ZIP tudomány nélkül, csak az elérési útját kell ismernünk:

    // A sablon dokumentum megnyitása.
Package package = Package.Open( path, FileMode.Open, FileAccess.ReadWrite );

A következő lépés az XML part megkeresése. Az egyes part-okra a csomagon belüli URI-jük segítségével hivatkozhatunk. A Word 2007 Content Control Toolkit által generált Item1.xml itt található:

    // Az XML part útvonala a sablon dokumentumban.
    Uri partUri = new Uri( "/customXml/Item1.xml", UriKind.Relative );

Lekérdezhetjük, hogy egyáltalán létezik-e ilyen part a dokumentumban:

    // Ellenőrizzük, hogy a sablonban van-e XML part.
    if( package.PartExists( partUri ) )
    {
        // itt folytatjuk...

Ha létezik, akkor el is kérhetjük, mégpedig egy PackagePart formájában:

    // Az XML part elkérése.
    PackagePart xmlPart = package.GetPart( partUri );

Az XML part tartalmát streamként tudjuk elérni. Ha például egy content nevű változóban megtalálható a beírandó XML UTF-16 formátumban, akkor annak beírására használhatjuk például az alábbi kódot:

    // Az XML part tartalmát kezelő stream elkérése.
    using( Stream xmlStream = xmlPart.GetStream() )
    {
        // A stream hosszának beállítása, hogy rövidebb szöveg esetén a régi tartalom levágódjon.
        xmlStream.SetLength( content.Length );

        // Az új tartalom beírása a streambe. Unicode kell, mert az XML stringben utf-16 szerepel.
        using( StreamWriter writer = new StreamWriter( xmlStream, Encoding.Unicode ) )
        {
            writer.Write( content );
            writer.Flush();
            // writer.Close(); automatikus a Dispose miatt.
        }

        // Az XML part mentése.
        // xmlStream.Close(); automatikus a Dispose miatt.
    }

Nincs is más hátra, mint a dokumentum módosításait elmenteni a diszkre:

    // A dokumentum változásainak mentése.
    package.Flush();
    package.Close();

Miért vacakoltam az UTF-16 kódolással? Azért, mert a beírandó XML előállítására szerintem az a legegyszerűbb megoldás, ha készítünk például egy Contact osztályt, annak beállítjuk úgy a tulajdonságait, ahogy azokat a Word dokumentumban látni szeretnénk, majd egyszerűen XmlSerializer segítségével kisorosítjuk:

    XmlSerializer serializer = new XmlSerializer( typeof( Contact ) );

    using( StringWriter writer = new StringWriter( CultureInfo.InvariantCulture ) )
    {
        serializer.Serialize( writer, this );
        result = writer.ToString();
        // writer.Close(); automatikus a Dispose miatt.
    }

Mivel itt StringWritert használok, az eredmény a .NET Framework sztringjeinek alapértelmezett kódolása, azaz "utf-16" lesz, amivel tapasztalataim szerint a Word nem birkózik meg. Persze biztosan lehet egyszerűbben is…

Egyetlen dologra hívnám fel a figyelmet – azon kívül természetesen, hogy a fenti kód a probléma megoldásának igen egyszerű módja: kódból módosítunk egy Word dokumentumot, de mindezt úgy tesszük, hogy nem használjuk hozzá a Word objektum modelljét. Sőt, nem használjuk a Word egyik komponensét sem, azaz a fenti kód működik akkor is, ha nincs Word a gépen! Ez igen fontos fegyvertény az Open XML mellett, hiszen aki próbált már szerver oldalon Office dokumentumot előállítani az biztosan belefutott abba a problémába, hogy az Office-t nem kiszolgáló oldali automatizálásra tervezték. Ez még a 2007-es verzióra is igaz, de nem az Open XML-re!

Ezt a tudásunkat felhasználva akár a SharePointot is kiegészíthetjük, készíthetünk például egy olyan új funkciót a Névjegyalbum listákba, amely lehetővé teszi a névjegy lista elemek alapján megcímzett, fejléces levelek egy kattintással történő előállítását. Ehhez nem kell mást tennünk, mint…

(folytatjuk)

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés / Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés / Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés / Módosítás )

Google+ kép

Hozzászólhat a Google+ felhasználói fiók használatával. Kilépés / Módosítás )

Kapcsolódás: %s