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)



Balássy György (MS RD, ASP.NET MVP, MCTS)

Balássy György (MS RD, ASP.NET MVP, MCTS) Villamosmérnök, a BME Automatizálási és Alkalmazott Informatikai Tanszékén webportálok fejlesztését oktatja. 2000 óta foglalkozik a Microsoft .NET platformjával, melynek meghonosításában jelentős szerepet vállalt előadóként, konzulensként és A .NET Framework és programozása című könyv társszerzőjeként. Az MSDN Kompetencia Központon belül a Portál Technológiák Csoport vezetője, szakterülete web alapú rendszerek fejlesztése és üzemeltetése. 2004-ben Magyarországon elsőként kapta meg a Most Valuable Professional címet, majd 2005 óta a Microsoft magyarországi regionális igazgatója. Publikációi a Technet Magazinban, az MSDN Kompetencia Központ honlapján és szakmai blogjában olvashatóak.

2008.04.21. 0:19:53 | Permalink | Hozzászólások: 0 | Tárgyszavak: , ,


  • CryptographicException: Keyset does not exist

    Balássy György (MS RD, ASP.NET MVP, MCTS) Korábban CardSpace használatakor futottam bele a fenti hibaüzenetbe, most egy IIS-ben hosztolt WCF szolgáltatás készítésekor jött elő. Elvesztettem volna a kulcsaimat? A problémát az okozza, hogy a web.config fájlban szerepel egy tanúsítvány hivatkozás a <serviceCertificate> ágban, de az IIS worker process felhasználói fiókjának, alapértelmezés szerint a Network Service fióknak, nincs joga hozzáférni a tanúsítványhoz. De hogy adok egy tanúsítványra olvasási jogot? Tovább »
  • TFS-t mindenkinek

    Balássy György (MS RD, ASP.NET MVP, MCTS) Korábban már írtam arról, hogy a Dev10 hullámmal megváltozott az online és az offline MSDN is. A teljes képhez hozzátartozik, hogy az MSDN előfizetések is megváltoznak. Tovább »


Írja meg Ön is véleményét!


Hozzászólásokat csak regisztrált, bejelentkezett felhasználóktól tudunk elfogadni!

Hozzászólások