OpenXML 将文本插入内容控件 Word 2007
我正在学习 OpenXML。我花了几个小时试图找到如何执行一个简单的任务:将文本插入到 c# 中的内容控件中。
我有一个模板文档,其中包含两个控件“姓名”和“年龄”。我可以很好地找到它们,但我无法在其中添加文本。我已经尝试了很多事情,但都无济于事。
byte[] templateBytes = System.IO.File.ReadAllBytes(fileName);
using (MemoryStream templateStream = new MemoryStream())
{
templateStream.Write(templateBytes, 0, (int)templateBytes.Length);
using (WordprocessingDocument outDoc = WordprocessingDocument.Open(templateStream, true))
{
MainDocumentPart mainPart = outDoc.MainDocumentPart;
foreach (SdtElement sdt in mainPart.Document.Descendants<SdtElement>().ToList())
{
SdtAlias alias = sdt.Descendants<SdtAlias>().FirstOrDefault();
if (alias != null)
{
string sdtTitle = alias.Val.Value;
switch (sdtTitle)
{
case "Name":
// ¿Qué?
break;
case "Age":
// ¿Qué?
break;
}
}
}
outDoc.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
}
using (FileStream fileStream = new FileStream(savePath, System.IO.FileMode.CreateNew))
{
templateStream.WriteTo(fileStream);
}
}
非常感谢所有帮助。
干杯,
蒂姆。
编辑--
感谢您的回复。根据您的建议,我尝试使用生产力工具进行转换和钻取,以找到要更新的子元素。您能告诉我您是否能明白为什么这段代码根本没有向文档写入任何内容吗?
foreach (SdtElement sdt in mainPart.Document.Descendants<SdtElement>().ToList())
{
SdtAlias alias = sdt.Descendants<SdtAlias>().FirstOrDefault();
if (alias != null)
{
SdtRun xRun = (SdtRun)sdt;
SdtContentRun xContentRun = xRun.Descendants<SdtContentRun>().FirstOrDefault();
Run xRun = xContentRun.Descendants<Run>().FirstOrDefault();
Text xText = xRun.Descendants<Text>().FirstOrDefault();
string sdtTitle = alias.Val.Value;
switch (sdtTitle)
{
case "Name":
xText.Text = "Whatever";
break;
case "Age":
xText.Text = "69";
break;
}
}
}
I am learning OpenXML. I have been looking for hours trying to find how to do a simple task: insert text into a content control in c#.
I have a template document with two controls "Name" and "Age." I can find them well enough, but I just cannot add text in them. I've tried a number of things, all to no avail.
byte[] templateBytes = System.IO.File.ReadAllBytes(fileName);
using (MemoryStream templateStream = new MemoryStream())
{
templateStream.Write(templateBytes, 0, (int)templateBytes.Length);
using (WordprocessingDocument outDoc = WordprocessingDocument.Open(templateStream, true))
{
MainDocumentPart mainPart = outDoc.MainDocumentPart;
foreach (SdtElement sdt in mainPart.Document.Descendants<SdtElement>().ToList())
{
SdtAlias alias = sdt.Descendants<SdtAlias>().FirstOrDefault();
if (alias != null)
{
string sdtTitle = alias.Val.Value;
switch (sdtTitle)
{
case "Name":
// ¿Qué?
break;
case "Age":
// ¿Qué?
break;
}
}
}
outDoc.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
}
using (FileStream fileStream = new FileStream(savePath, System.IO.FileMode.CreateNew))
{
templateStream.WriteTo(fileStream);
}
}
All help greatly appreciated.
Cheers,
Tim.
EDIT --
Thanks for the response. Taking your advice, I've attempted to cast and drilled down with the productivity tool to find the child elements to update. Could you tell me if you can see why this code is simply not writing anything to the document?
foreach (SdtElement sdt in mainPart.Document.Descendants<SdtElement>().ToList())
{
SdtAlias alias = sdt.Descendants<SdtAlias>().FirstOrDefault();
if (alias != null)
{
SdtRun xRun = (SdtRun)sdt;
SdtContentRun xContentRun = xRun.Descendants<SdtContentRun>().FirstOrDefault();
Run xRun = xContentRun.Descendants<Run>().FirstOrDefault();
Text xText = xRun.Descendants<Text>().FirstOrDefault();
string sdtTitle = alias.Val.Value;
switch (sdtTitle)
{
case "Name":
xText.Text = "Whatever";
break;
case "Age":
xText.Text = "69";
break;
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您需要将 SdtElement 转换为无论它是什么,才能获取其内容子元素。
例如,如果它是一个 SdtBlock:
那么您可以向其中添加内容(例如添加子项)。
来自 MSDN,继承层次结构:
You need to cast your SdtElement to whatever it is, in order to get at its content child.
For example, if its an SdtBlock:
Then you can add stuff (eg add children) to that.
From MSDN, the inheritance hierarchy:
经过几个小时的痛苦后,我解决了这个问题。
问题出在两件事上:
1)我需要一个 mainPart.Document.Save();在那里指挥。
2)我使用内容控制工具包添加了一个customXmlPart。所以我假设这个 customxml 部分覆盖了我用代码添加的文本,因为当我返回内容控制工具包并删除 xml 部分时,它起作用了。
再次感谢 plutext 让我找到解决方案!
After many hours of pain, I solved it.
Two things were the problem:
1) I needed a mainPart.Document.Save(); command in there.
2) I had added a customXmlPart with the Content Control Toolkit. So I assume that this customxml part was overriding the text I was adding with the code, because when I went back into the content control toolkit and deleted the xml part, it worked.
Thanks again plutext for putting me onto the solution!
任何想要 VB 格式的代码直接查找/替换键/值字典数组的人...
出于某种原因,最后一部分似乎是 sdtBlock 而不是 sdtRun 因此 ElseIf...!
Anyone wanting the code in VB format to do a straight find/replace of a key/value dictionary array...
for some reason the last part seems to be sdtBlock instead of sdtRun hence the ElseIf..!
顺便说一句,在 foreach 之前添加以下代码行将自动清除任何现有的自定义 xml:
By the way, adding the following line of code before the foreach will automatically clean out any existing custom xml: