C# 如何从模板以编程方式创建word文档
我正在尝试用MicrosoftOfficeWord创建大约600份报告。文档由数据库中的数据和本地驱动器上的图像填充。 我发现,我可能会在VisualStudio2010中创建一个Word模板项目,并对模板进行编程,这样当您输入单个值(id号)时,它会自动填充整个文档 我相信这是可能的。唯一的问题是。如何循环数据库中的所有条目,根据模板打开新文档并设置id值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
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正在关闭。找到上面提到的所有来源。这里似乎有两个问题:
然后,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
{
}
}