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: , ,


  • Véletlen sorok lekérdezése MS SQL adatbázisból

    Dávid Zoltán Véletlen értékek generálása alapvető fejlesztői technika. Használjuk teszteléshez, játékokhoz, ajánlók generálásához. Mi a helyzet akkor, ha egy Microsoft SQL szerver táblából szeretnénk néhány - de egymástól különböző - random rekordot visszaadni? Tovább »
  • Melyik oldal jön be bejelentkezés után?

    Balássy György (MS RD, ASP.NET MVP, MCTS) Az ASP.NET Login vezérlőnek van egy DestinationPageUrl tulajdonsága, amellyel megadhatjuk annak az oldalnak a címét, ahova sikeres bejelentkezés után a vezérlő továbbdob. Ez szép is lenne, már ha működne. 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