如何从模板以编程方式创建Word文档

我试图在microsoft office Word中创建大约600个报告。 文档中填充了数据库中的数据和本地驱动器上的图像。 我已经想到,我可以在visual studio 2010中创建一个Word模板项目,并对模板进行编程,这样当您输入单个值(id-number)时,它会自动填写整个文档。

我很有信心这是可能的。 唯一的问题是。 如何遍历数据库中的所有条目,根据模板打开新文档并设置id-value?

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"); } 

应用程序应该只运行一次,生成报告,而且不一定要快。 它必须易于开发。

这里的问题是,似乎在Word项目之外无法访问DocumentBase对象。 替代Microsoft.Office.Interop.Word.Document没有像SelectContentControlsByTitle这样的function,它允许我查找和设置我的ContentControls。 而这正是我需要做的……

这就是我的代码现在将文本插入我的字段:Word.Application app = new Word.Application();

  Word.Document doc = app.Documents.Add(@"C:\..\test.dotx"); foreach (Word.ContentControl cc in doc.SelectContentControlsByTitle("MyCCTitle")) { cc.Range.Text += "1234"; } doc.SaveAs(FileName: @"c:\temp\test.docx"); 

然后我的模板上的事件处理程序在BeforeSave上根据MyCCTitle标题对象中的文本填写文档。

也许你应该看看Microsoft.Office.Tools.Word.Document?

Document.SelectContentControlsByTitle

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

看看Open XML。 你可以在下面找到它的负载:

http://openxmldeveloper.org/

编辑:Openxmldeveloper正在关闭。 请在http://www.ericwhite.com/上找到上面提到的所有来源。

如果您使用的是Word 2007或2010格式,则应阅读有关OpenXML格式的信息

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

似乎这里有两个问题:

  1. 你如何开始特定id值的过程

  2. 如何填充文档。

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

OP的重点似乎是Q1。

没有命令行开关允许您将任意值传递给Word: http : //support.microsoft.com/kb/210565

所以我看到你有4个选择:

  1. 通过OpenXML SDK完成所有工作,从不打开Word(正如其他海报所建议的那样)

  2. 使用OpenXML SDk创建一个最小的预先存在的文档(包含您的ID号),然后打开Word

  3. 自动化Word将ID号传递给文档,可能作为文档属性

  4. 使用VSTO或Word宏(VBA)在Word中创建600个文档的工作

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

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

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

添加Document.OpenXml.dllWindowsBase.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 { } }