C# 如何从模板以编程方式创建word文档

C# 如何从模板以编程方式创建word文档,c#,ms-word,office-interop,C#,Ms Word,Office Interop,我正在尝试用MicrosoftOfficeWord创建大约600份报告。文档由数据库中的数据和本地驱动器上的图像填充。 我发现,我可能会在VisualStudio2010中创建一个Word模板项目,并对模板进行编程,这样当您输入单个值(id号)时,它会自动填充整个文档 我相信这是可能的。唯一的问题是。如何循环数据库中的所有条目,根据模板打开新文档并设置id值 for(int i = 0; i < idnumbers.Count(); i++) { Word.Application

我正在尝试用MicrosoftOfficeWord创建大约600份报告。文档由数据库中的数据和本地驱动器上的图像填充。 我发现,我可能会在VisualStudio2010中创建一个Word模板项目,并对模板进行编程,这样当您输入单个值(id号)时,它会自动填充整个文档

我相信这是可能的。唯一的问题是。如何循环数据库中的所有条目,根据模板打开新文档并设置id值

for(int i = 0; i < idnumbers.Count(); i++)
{
     Word.Application app = new Word.Application();
     Word.Document doc = app.Documents.Add(@"C:\..\WordGenerator\bin\Debug\WordTemplate.dotx");
     //input the id-number below: HOW??

     doc.SaveAs(FileName: @"c:\temp\test.docx"); 
}

然后,BeforeSave上我的模板上的eventhandler根据MyCCTitle中标题为object的文本填写文档。

如果使用Word 2007或2010格式,您应该阅读OpenXML格式


不要使用办公自动化。 Office automation在后台打开Office实例并对其执行操作。打开一个office实例600次似乎不是一件很有趣的事情。(而且它永远不会在服务器端运行)

看看开放式XML。您可以在下面找到关于它的信息:


编辑:Openxmldeveloper正在关闭。找到上面提到的所有来源。

这里似乎有两个问题:

  • 如何启动特定id值的过程

  • 如何填充文档

  • sunilp已经回答了问题2。数据绑定内容控件是为Word 2007及更高版本注入数据的最佳方式

    OP的重点似乎是第一季度

    没有命令行开关允许您将任意值传递给Word:

    在我看来,你有4个选择:

  • 通过OpenXMLSDK完成所有的工作,不要打开Word(正如其他海报所建议的那样)

  • 使用OpenXMLSDK创建一个最小的预先存在的文档(包含您的id号),然后打开Word

  • 自动Word将id号传递给文档,可能作为文档属性

  • 使用VSTO或Word宏(VBA)在Word中创建600个文档

  • 我?我将在Word中创建一个包含数据绑定内容控件的docx,并保存它


    然后,in将把我的数据作为自定义xml部分注入其中,并保存它。(这一步可以使用OpenXML SDK完成,如果需要Word更新某些下游进程的绑定,可以使用Word完成)

    也许您应该查看Microsoft.Office.Tools.Word.Document


    关于上述答案,我同意J.Vermeire的观点,即OpenXML是一条出路。我已经使用基于OpenXML的工具包三年多了,它可以生成.docx文档,并将模板和数据库数据合并在一起。这里有一个如何使用它的示例。该示例显示了如何一次处理一个文档,要处理更多文档,只需添加一个循环并调用一个方法来生成文档。

    添加
    document.OpenXml.dll
    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
            {
    
            }
        }
    

    这对于他想要实现的目标来说太过分了,Word自动化/互操作在这种情况下更容易实现。太过分了?一点也不。OpenXMLSDK很容易使用,并且正是为了做到这一点。在执行Word自动化/互操作时,您不需要在服务器上安装Word吗?有了OpenXML,你就不需要了。另外,我想在Moontear评论中添加一点,OpenXML格式就是XML。他想做的事情非常快(生成600个文档),我知道我可能会使用OpenXML,但对我来说,在wysiwyg编辑器中用可绑定的内容控件设计我的文档似乎要快得多。谢谢你的回答,请您详细说明一下最后一部分:“那么,in将把我的数据作为自定义xml部分注入其中,并保存它。”这可能就是实现这一点的方法。您可以在word中创建内容控件,并将它们与xml文件绑定在一起。该xml文件也将保存到word文档中。替换xml文件将更改文档中显示的数据。我建议您看看word内容控制工具包来为您进行绑定。最后我发现,这实际上是一条可行的道路。。但是有很多事情你必须注意。首先,您需要添加对名为office的组件的引用,并且您必须让舒尔确认您的组件是正确的版本,否则您将无法访问正确的方法和对象。请更新链接,看起来链接中的数据在您发布到此处7个月后被删除参考文章于2015年7月10日被删除,其最新版本可在Wighty WebArchive中获得。无论如何,它是关于DocentricToolkit的,这是一个付费的库。。。
    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
            {
    
            }
        }