最近的项目(MOSS项目)需要,用户需要根据word模板生成相关的word文档,具体需求是根据infopath表单中的内容和相关的模板生成一份word文档

着手做之前想想要是用word api操作的话,后台进程,多用户并发操作等等问题

看来还是用openxml来操作比较好,于是找了找资料,实现了这小小的功能

现在把代码贴出来跟大家分享下

使用openxml技术时,首先需要引用windowsbase.dll

部分常量

 

;
        const string strUri = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
        
static List<string> bookmarkText;
        
string bookmarkName;

 

该方法是将模板中所有标签都取出,并放到一个datatable中

 

 fileName)
        {
             

            dt = new DataTable();
            dt.Columns.Add(
"标签"typeof(string));
            dt.Columns.Add(
"内容"typeof(string));
            DataRow dr;

            Stream strm 
= null;
            PackagePart documentPart;
            Package package;
            
            
            
using (SPSite site = new SPSite("http://ascentn-moss:8686/"))
            {
                SPWeb web 
= site.OpenWeb();
                strm 
= web.GetFile(fileName).OpenBinaryStream();
                documentPart 
= null;
                package 
= Package.Open(strm, FileMode.Open, FileAccess.ReadWrite);

                
//FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate);

                
//PackagePart documentPart = null;
                
//Package package = Package.Open(fileName, FileMode.Open, FileAccess.ReadWrite);
                
//MessageBox.Show(strm.Length.ToString());
                
// Package package = Package.Open(strm, FileMode.Open, FileAccess.ReadWrite);

                
foreach (System.IO.Packaging.PackageRelationship documentRelationship in package.GetRelationshipsByType(documentRelationshipType))
                {
                    NameTable nt 
= new NameTable();
                    XmlNamespaceManager nsManager 
= new XmlNamespaceManager(nt);
                    nsManager.AddNamespace(
"w", strUri);

                    Uri documentUri 
= PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative), documentRelationship.TargetUri);
                    documentPart 
= package.GetPart(documentUri);
                    XmlDocument xdoc 
= new XmlDocument();
                    xdoc.Load(documentPart.GetStream());
                    XmlNodeList nodeList 
= xdoc.SelectNodes("//w:bookmarkStart", nsManager);
                    
foreach (XmlNode node in nodeList)
                    {
                        dr 
= dt.NewRow();

                        
if (node.NextSibling.Name.ToString() == "w:bookmarkEnd")
                        {
                            bookmarkText 
= new List<string>();
                            bookmarkName 
= node.Attributes["w:name"].Value;
                            bookmarkText.Add(
" ");

                            dr[
0= bookmarkName;
                            
//dataGridView
                        }
                        
else
                        {

                            bookmarkName 
= node.Attributes["w:name"].Value;
                            dr[
0= bookmarkName;
                            
string bookmarkId = node.Attributes["w:id"].Value;
                            bookmarkText 
= new List<string>();

                            XmlNode nextParentNode 
= node.ParentNode;
                            XmlNode nodeIterate 
= node.NextSibling;

                            
while (nodeIterate.Name.ToString() != "w:bookmarkEnd")
                            {
                                
if (nodeIterate.Name.ToString() == "w:r")

                                    bookmarkText.Add(nodeIterate.InnerText);

                                nodeIterate 
= nodeIterate.NextSibling;
                                
if (nodeIterate == null)
                                {
                                    
if (nextParentNode.NextSibling.Attributes.Count != 0)
                                    {
                                        
if ((nextParentNode.NextSibling.Attributes["w:id"].Value == bookmarkId))
                                        {
                                            nodeIterate 
= nextParentNode.NextSibling;
                                        }
                                    }

                                    
else
                                    {
                                        nextParentNode 
= nextParentNode.NextSibling;

                                        nodeIterate 
= nextParentNode.FirstChild;
                                        bookmarkText.Add(
'\n' + nodeIterate.InnerText);

                                    }

                                }

                            }
                            
//dic.Add(bookmarkName, bookmarkText);
                        }
                        dt.Rows.Add(dr);

                    }

                }
                package.Close();
            }

        }

 

接下来需要做的是用infopath中的相关节点去逐个替换标签内容

 



                string spUrl = (string)ds["SPServer"];

                APWS.Service apws 
= new APWS.Service();
                apws.Url 
= spUrl + "/spsws/Service.asmx";
                apws.Credentials 
= WFSystem.GetSystemUserCredential();

                System.IO.MemoryStream fileStream 
= new System.IO.MemoryStream();
                
string newfilename = string.Empty;
                
if(fileLocation.EndsWith("/"))
                    newfilename 
= fileLocation + fileName + template.Substring(template.LastIndexOf('.'));
                
else
                    newfilename 
= fileLocation +"/"+ fileName + template.Substring(template.LastIndexOf('.'));

                apws.SPCopyFile(template, newfilename);

                fileStream.Write(apws.SPOpenBinary(newfilename), 
0, apws.SPGetFileLenght(newfilename));

                originalDocPackage 
= Package.Open(fileStream, FileMode.Open, FileAccess.ReadWrite);

                
foreach (PackageRelationship relationship in originalDocPackage.GetRelationshipsByType(documentRelationshipType))
                {
                    Uri documentUri 
= PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative), relationship.TargetUri);
                    originalDocumentPart 
= originalDocPackage.GetPart(documentUri);

                    
break;
                }

                originalXmlDocument 
= new XmlDocument();
                originalXmlDocument.Load(originalDocumentPart.GetStream());

                NameTable nt 
= new NameTable();
                XmlNamespaceManager xmlNamespaceManager 
= new XmlNamespaceManager(nt);
                xmlNamespaceManager.AddNamespace(
"w", strUri);

                
#region 多个书签循环检索
                XmlNodeList bookmarknodeList 
= originalXmlDocument.SelectNodes("//w:bookmarkStart", xmlNamespaceManager);
                XmlNodeList bookmarknodeEndList 
= originalXmlDocument.SelectNodes("//w:bookmarkEnd", xmlNamespaceManager);
                XmlNode parentNodeOfBookMark;
                
foreach (XmlNode xmlnode in bookmarknodeList)
                {
                    
foreach (string columnName in hvalues.Keys)
                    {
                        
if (xmlnode.Attributes["w:name"].Value == columnName)
                        {
                            
if (xmlnode.NextSibling.Name == "w:r")
                            {
                                xmlnode.NextSibling.RemoveChild(xmlnode.NextSibling.LastChild);

                                XmlElement textElement 
= originalXmlDocument.CreateElement("w:t", strUri);
                                xmlnode.NextSibling.AppendChild(textElement);

                                XmlNode textNode 
= originalXmlDocument.CreateNode(XmlNodeType.Text, "w:t", strUri);
                                
if(hvalues[columnName].ToString().EndsWith("T00:00:00"))
                                    textNode.Value 
= hvalues[columnName].ToString().Substring(0,hvalues[columnName].ToString().IndexOf('T'));
                                
else
                                    textNode.Value 
= hvalues[columnName].ToString();
                                textElement.AppendChild(textNode);
                            }
                        }
                    }
                    parentNodeOfBookMark 
= xmlnode.ParentNode;
                    parentNodeOfBookMark.RemoveChild(xmlnode);
                }

                
foreach (XmlNode xmlnode in bookmarknodeEndList)
                {
                    parentNodeOfBookMark 
= xmlnode.ParentNode;
                    parentNodeOfBookMark.RemoveChild(xmlnode);
                }
                
#endregion

                
//save document
                originalXmlDocument.Save(originalDocumentPart.GetStream(FileMode.Create, FileAccess.Write));


                
byte[] bs = fileStream.ToArray();

                apws.SPSaveBinary(newfilename, bs);
                originalDocPackage.Close();
                
#endregion

 

 以上只是贴出了其中主要的代码

文件包参考代码:/Files/jhobo/Bookmarks_SourceCode.rar

相关文章: