How to create word docs programmatically from a template

风流意气都作罢 提交于 2019-11-30 04:51:07

Maybe you should be looking at Microsoft.Office.Tools.Word.Document?

Document.SelectContentControlsByTitle

Don't use Office Automation. Office automation opens up an instance of office in the background and performs the actions on it. Opening up an office instance 600 times doesn't seem like a very interesting thing to do. (and it would never run serverside)

Take a look at Open XML. You can find loads about it below:

http://openxmldeveloper.org/

edit: Openxmldeveloper is shutting down. Find all the sources mentioned above at http://www.ericwhite.com/ instead.

You Should read about OpenXML format if you are using Word 2007 or 2010 Format

http://msdn.microsoft.com/en-us/library/bb264572(office.12).aspx

Seems that there are 2 questions here:

  1. How do you kick off the process for a particular id-value

  2. How do you populate the document.

sunilp has answered Q2. Data bound content controls are the best way to inject data for Word 2007 and later.

OP's focus looks to be Q1.

There is no command line switch that lets you pass an arbitrary value to Word: http://support.microsoft.com/kb/210565

So as I see it you have 4 choices:

  1. do all the work via the OpenXML SDK, never opening Word at all (as other posters have suggested)

  2. create a minimal pre-existing document (containing your id number) using the OpenXML SDk, then open Word

  3. automate Word to pass the id number to the document, perhaps as a document property

  4. do the work to create the 600 documents in Word using VSTO or Word macros (VBA)

Me? I would create a docx containing data bound content controls in Word, and save it.

Then, in would inject my data into it as a custom xml part, and save it. (This step you could do using the OpenXML SDK, or in Word if you needed to have Word update the bindings for some downstream process of yours)

In regard to the answers above I agree with J. Vermeire that OpenXML is the way to go. I have been using an OpenXML based toolkit for over three years now, which produces .docx documents, merged from templates and database data. There is an example how to use it here. The example shows how to work with one document at the time, to work with more of them, just add a loop and call a method for document generation.

Sachin Patkar

Add references for Document.OpenXml.dll and WindowsBase.dll

using System.IO.Packaging;

using DocumentFormat.OpenXml.Packaging;

using System.DirectoryServices;

 protected void btnOK_Click(object sender, EventArgs e)
  {

        try
        {
            Package package;
            string strTemplateName = ddl_Templates.SelectedValue.ToString(); //Select Dotx template 
            string strClaimNo = "3284112";
            string strDatePart = DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Day.ToString() + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString();
            //Word template file
            string templateName = Server.MapPath("~\\LetterTemplates\\" + strTemplateName + ".dotx");
            PackagePart documentPart = null;
            //New file name to be generated from 
            string docFileName = Server.MapPath("~\\LetterTemplates\\" + strClaimNo + "_" + strTemplateName + "_" + strDatePart + ".docx");

            File.Copy(templateName,docFileName, true);
            string fileName = docFileName;
            package = Package.Open(fileName, FileMode.Open, FileAccess.ReadWrite);
            DataSet DS = GetDataSet(strClaimNo, ""); // to get the data from backend to fill in for merge fields
            try
            {
                if (DS != null)
                {
                    if (DS.Tables.Count > 0)
                    {
                        if (DS.Tables[0].Rows.Count > 0)
                        {
                            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);

                                //Get document xml
                                XmlDocument xdoc = new XmlDocument();
                                xdoc.Load(documentPart.GetStream(FileMode.Open, FileAccess.Read));
                                int intMergeFirldCount = xdoc.SelectNodes("//w:t", nsManager).Count;

                                XmlNodeList nodeList = xdoc.SelectNodes("//w:t", nsManager);
                                foreach (XmlNode node in nodeList)
                                {
                                    try
                                    {
                                        xdoc.InnerXml = xdoc.InnerXml.Replace(node.InnerText, DS.Tables[0].Rows[0][node.InnerText.Replace("«", "").Replace("»", "").Trim()].ToString());
                                    }catch(Exception x) { }
                                }

                                StreamWriter streamPart = new StreamWriter(documentPart.GetStream(FileMode.Open, FileAccess.Write));
                                xdoc.Save(streamPart);
                                streamPart.Close();
                                package.Flush();
                                package.Close();
                            }
                            using (WordprocessingDocument template = WordprocessingDocument.Open(docFileName, true))
                            {
                                template.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
                                template.MainDocumentPart.Document.Save();
                            }

                            byte[] bytes = System.IO.File.ReadAllBytes(docFileName);
                            System.IO.File.Delete(docFileName);
                            System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
                            response.ClearContent();
                            response.Clear();
                            response.ContentType = "application/vnd.msword.document.12"; //"application/msword";
                            Response.ContentEncoding = System.Text.Encoding.UTF8;
                            response.AddHeader("Content-Disposition", "attachment; filename=" + strClaimNo + "_" + strTemplateName + "_" + strDatePart + ".docx;");
                            response.BinaryWrite(bytes);
                            response.Flush();
                            response.Close();
                        }
                        else
                        {
                            throw (new Exception("No Records Found."));
                        }
                    }
                    else
                    {
                        throw (new Exception("No Records Found."));
                    }
                }
                else
                {
                    throw (new Exception("No Records Found."));
                }


            }
            catch (Exception ex)
            {
                package.Flush();
                package.Close();
                // Softronic to add code for exception handling
            }
        }
        catch (Exception ex)
        {

            // add code for exception handling
        }
        finally
        {

        }
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!