Click here to Skip to main content
15,896,154 members
Articles / Web Development / ASP.NET

Generate Word documents from Word templates using the Word 2007 XML object model

Rate me:
Please Sign up or sign in to vote.
2.50/5 (6 votes)
16 Dec 2007CPOL 45.4K   859   27  
How to generate Word documents from Word templates using the Word 2007 XML format.
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
using System.IO.Packaging;
using System.Xml;
using System.Collections.Generic;


public partial class _Default : System.Web.UI.Page 
{
    const string documentRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
    const string headerContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml";
    const string footerContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml";
    XmlNamespaceManager nsManager;

    protected void Page_Load(object sender, EventArgs e)
    {
        CreateWordDocument();
    }

    private void CreateWordDocument()
    {
        Random RandomClass = new Random();
        int randomInt = RandomClass.Next();

        string templateName = "Template.docx";
        string docFileName = "Dec_" + randomInt + ".docx";

        File.Copy(Server.MapPath(@"_Documents/" + templateName), Server.MapPath(@"_Documents/" + docFileName),true);

        //string fileName = Server.MapPath(@"_Documents/Template.dotx");
        string fileName = Server.MapPath(@"_Documents/" + docFileName);
        
        PackagePart documentPart = null;
        Package package = Package.Open(fileName, FileMode.Open, FileAccess.ReadWrite);
        //  Get the main document part (document.xml).
        foreach (System.IO.Packaging.PackageRelationship documentRelationship in package.GetRelationshipsByType(documentRelationshipType))
        {
            NameTable nt = new NameTable();
            nsManager = new XmlNamespaceManager(nt);
            nsManager.AddNamespace("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");

            Uri documentUri = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative), documentRelationship.TargetUri);
            documentPart = package.GetPart(documentUri);

            

            #region Update Document Bookmarks
            //Get document xml
            XmlDocument xdoc = new XmlDocument();
            //xdoc.Load(documentPart.GetStream());
            xdoc.Load(documentPart.GetStream(FileMode.Open,FileAccess.Read));

            //Select all bookmark nodes
            XmlNodeList nodeList = xdoc.SelectNodes("//w:bookmarkStart", nsManager);
            foreach (XmlNode node in nodeList)
            {

                if(this.SetBookmarkText(xdoc, node, "S_ADDRESS_V1", RandomClass.Next().ToString())) continue;

                if (this.SetBookmarkText(xdoc, node, "S_ADDRESS_V2", RandomClass.Next().ToString())) continue;

            }

            #endregion


            #region Update Header/Footer Bookmarks

            //Uri documentUri = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative),  documentRelationship.TargetUri);
            PackagePartCollection documentParts = package.GetParts();

            foreach (PackagePart part in documentParts)
            {
                //Update header bookmarks
                if (part.ContentType == headerContentType)
                {
                    //Get document xml
                    XmlDocument xheader = new XmlDocument();
                    xheader.Load(part.GetStream(FileMode.Open, FileAccess.Read));

                    //Select all bookmark nodes
                    XmlNodeList headerNodeList = xheader.SelectNodes("//w:bookmarkStart", nsManager);
                    foreach (XmlNode node in headerNodeList)
                    {
                        //HEADER5
                        if (this.SetBookmarkText(xheader, node, "HEADER5", "Test Header")) continue;
                    }
                    
                    //Save 
                    if (headerNodeList.Count > 0)
                    {
                        StreamWriter streamHeader = new StreamWriter(part.GetStream(FileMode.Open, FileAccess.Write));
                        xheader.Save(streamHeader);
                        streamHeader.Close();
                    }
                }

                //Update footer bookmarks
                if (part.ContentType == footerContentType)
                {
                    //Get document xml
                    XmlDocument xfooter = new XmlDocument();
                    xfooter.Load(part.GetStream(FileMode.Open, FileAccess.Read));

                    //Select all bookmark nodes
                    XmlNodeList footerNodeList = xfooter.SelectNodes("//w:bookmarkStart", nsManager);
                    foreach (XmlNode node in footerNodeList)
                    {
                        //FOOTER_1_1
                        if (this.SetBookmarkText(xfooter, node, "FOOTER_1_1", "Number", true)) continue;
                        if (this.SetBookmarkText(xfooter, node, "FOOTER_1_2", "123456", true)) continue;
                    }

                    //Save 
                    if (footerNodeList.Count > 0)
                    {
                        StreamWriter streamFooter = new StreamWriter(part.GetStream(FileMode.Open, FileAccess.Write));
                        xfooter.Save(streamFooter);
                        streamFooter.Close();
                    }
                }
            }

            #endregion

            StreamWriter streamPart = new StreamWriter(documentPart.GetStream(FileMode.Open, FileAccess.Write));
            xdoc.Save(streamPart);
            streamPart.Close();
        }

        package.Flush();
        package.Close();

        ////send response to browser
        /*string File_Name = "_Documents/" + docFileName;
        string popupScript = "<script language='javascript'>" +
                         "window.open('" + File_Name + "', 'Document', " +
                         "'width=700, height=600, menubar=yes, resizable=yes')" +
                         "</script>";

        ClientScript.RegisterClientScriptBlock(this.GetType(), "PopupScriptOffer", popupScript);
         */
    }


    /// <summary>
    /// 
    /// </summary>
    /// <param name="xdoc"></param>
    /// <param name="node"></param>
    /// <param name="bookmarkName"></param>
    private bool SetBookmarkText(XmlDocument xdoc, XmlNode node, string bookmarkName, string bookmarkValue)
    {
        if (node.NextSibling.Name.ToString() == "w:bookmarkEnd")
        {
            if (node.Attributes["w:name"].Value == bookmarkName)
            {
                //get the node previous sibling style ("w:rPr") to apply to the bookmark text
                XmlNode nodeStyle = node.PreviousSibling.CloneNode(true);

                //parent node "w:p"
                XmlNode bookmrkParent = node.ParentNode;

                XmlElement tagRun;
                tagRun = xdoc.CreateElement("w:r", nsManager.LookupNamespace("w"));
                bookmrkParent.AppendChild(tagRun);

                //if (nodeStyle != null && nodeStyle.FirstChild.Name == "w:rPr")
                //    tagRun.AppendChild(nodeStyle.FirstChild);

                if (nodeStyle.SelectSingleNode("//w:rPr", nsManager) != null)
                    tagRun.AppendChild(nodeStyle.SelectSingleNode("//w:rPr", nsManager));

                XmlElement tagText;
                tagText = xdoc.CreateElement("w:t", nsManager.LookupNamespace("w"));
                tagRun.AppendChild(tagText);

                //*** insert text into part as a Text node 
                XmlNode nodeText;
                nodeText = xdoc.CreateNode(XmlNodeType.Text, "w:t", nsManager.LookupNamespace("w"));
                nodeText.Value = bookmarkValue;
                tagText.AppendChild(nodeText);

                return true;
            }
        }
        return false;
    }

    private bool SetBookmarkText(XmlDocument xdoc, XmlNode node, string bookmarkName, string bookmarkValue, bool IsFooter)
    {
        if (node.NextSibling.Name.ToString() == "w:bookmarkEnd")
        {
            if (node.Attributes["w:name"].Value == bookmarkName)
            {
                //get the node previous sibling style ("w:rPr") to apply to the bookmark text
                XmlNode nodeStyle = node.PreviousSibling.CloneNode(true);

                //parent node "w:p"
                XmlNode bookmrkParent = node.ParentNode;

                XmlElement tagRun;
                tagRun = xdoc.CreateElement("w:r", nsManager.LookupNamespace("w"));
                bookmrkParent.AppendChild(tagRun);

                if (nodeStyle.SelectSingleNode("//w:rPr", nsManager) != null)
                {
                    XmlNode xfootStyle = nodeStyle.SelectSingleNode("//w:rPr", nsManager);
                    
                    //reduce font size for footer to 16.  <w:sz w:val="20" />
                    /*if (IsFooter)
                    {
                        xfootStyle.SelectSingleNode("//w:sz", nsManager).Attributes["w:val"].Value = "16";
                    }*/
                    tagRun.AppendChild(xfootStyle);
                }

                XmlElement tagText;
                tagText = xdoc.CreateElement("w:t", nsManager.LookupNamespace("w"));
                tagRun.AppendChild(tagText);

                //*** insert text into part as a Text node 
                XmlNode nodeText;
                nodeText = xdoc.CreateNode(XmlNodeType.Text, "w:t", nsManager.LookupNamespace("w"));
                nodeText.Value = bookmarkValue;
                tagText.AppendChild(nodeText);

                return true;
            }
        }
        return false;
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer TCS Hyderabad
India India
I am a Software Engineer working for TCS.

I have an experience in ASP, ASP.NET, C#, SQL Server 2005.

Comments and Discussions