65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Word 2007 XML 对象模型从 Word 模板生成 Word 文档

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.50/5 (6投票s)

2007年12月15日

CPOL
viewsIcon

46649

downloadIcon

876

如何使用 Word 2007 XML 格式从 Word 模板生成 Word 文档。

引言

在许多项目中,开发人员需要以特定格式或从模板生成 Word 文档中的报告。 使用服务器端 Word 实例化来生成这些文档的旧方法会消耗大量服务器资源,不建议使用。 一种替代方法是使用 Word 2007 XML 对象进行 Word 生成。 可以此处找到有关 Word 2007 XML 格式的基本信息。

本文涵盖了通过填充书签及其样式,从服务器上的模板生成合同文档。

Using the Code

此代码需要 Word 2007 和 .NET Framework 3.0 或更高版本才能工作。.NET 3.0 附带一个名为 WindowsBase.dll 的特殊 DLL 和一个名为 System.IO.Packaging 的命名空间,用于在不实例化服务器上的 Word 对象的情况下生成 Word 文档。

//Namespaces required
using System.IO;
using System.IO.Packaging;
using System.Xml;
using System.Collections.Generic;

//Variable and constants.
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;

//Method which will create the documents on the fly.

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

    //Word template file
    string templateName = "Template.docx";

    //New file name to be generated from 
    string docFileName = "Doc_" + randomInt + ".docx";

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

    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)
        {
           // S_ADDRESS_V1 and S_ADDRESS_V2 are
           // the bookmarks defined in the template 
           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

        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 is the bookmark of header in template
                    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;
}
© . All rights reserved.