我在Word模板中有一个富文本框contentControl。我正在尝试将RTF数据插入ContentControl并从中生成word文档。我按照here告诉AltChunk
。这适用于SdtBlock
。由于SdtBlock
的父级是Body
,我们可以直接将AltChunk
插入到正文中。如果word文档有多个富文本框contentControls,则word将控件保存为SdtRun
。 SdtRun
的父级为Paragraph
,其父级为Body。如果我们尝试做类似
SdtRun contentControl = (SdtRun)wordprocessingDocument.MainDocumentPart.RootElement.Descendants<SdtRun>().FirstOrDefault(x => x.Descendants<Tag>().Any(y => y.Val == "richtextbox"));
contentControl.Parent.Parent.InsertAfter(altChunk, contentControl); //contentControl.Parent.Parent - Returns body of document
抛出异常 由于对象的当前状态,操作无效
所以我尝试使用Paragraph
Paragraph contentControl = (Paragraph)wordprocessingDocument.MainDocumentPart.RootElement.Descendants<Paragraph>().FirstOrDefault(x => x.Descendants<Tag>().Any(y => y.Val == "richtextbox"));
contentControl.Parent.InsertAfter(altChunk, contentControl); //contentControl.Parent - Returns body of document
此代码以RTF格式插入数据。但问题是我无法插入Rich TextControl的正确位置,因为我们在Paragraph
上操作。
完整代码发布在
下面 string templatePath = @"Template1.docx";
string newFile = @"Template1_Processed.docx";
System.IO.File.Copy(templatePath, newFile, true);
using (WordprocessingDocument wordprocessingDocument = WordprocessingDocument.Open(newFile, true))
{
Paragraph sdtElement = (Paragraph)wordprocessingDocument.MainDocumentPart.RootElement.Descendants<Paragraph>().FirstOrDefault(x => x.Descendants<Tag>().Any(y => y.Val == "richtextbox"));
string innerText = @"{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Microsoft Sans Serif;}}{\colortbl ;\red139\green0\blue0;}\viewkind4\uc1\pard\cf1\f0\fs24 test\par}";
string altChunkId = "myId";
MainDocumentPart mainDocPart = wordprocessingDocument.MainDocumentPart;
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(innerText));
// Create alternative format import part.
AlternativeFormatImportPart formatImportPart =
mainDocPart.AddAlternativeFormatImportPart(
AlternativeFormatImportPartType.Rtf, altChunkId);
// Feed HTML data into format import part (chunk).
formatImportPart.FeedData(ms);
AltChunk altChunk = new AltChunk();
altChunk.Id = altChunkId;
sdtElement.Parent.InsertAfter<AltChunk>(altChunk, sdtElement);
SdtElement contentControl = (SdtElement)wordprocessingDocument.MainDocumentPart.RootElement.Descendants<SdtElement>().FirstOrDefault(x => x.Descendants<Tag>().Any(y => y.Val == "richtextbox"));
contentControl.Remove();
wordprocessingDocument.MainDocumentPart.CreateRelationshipToPart(formatImportPart);
sdtElement = (Paragraph)wordprocessingDocument.MainDocumentPart.RootElement.Descendants<Paragraph>().FirstOrDefault(x => x.Descendants<Tag>().Any(y => y.Val == "richtextbox1"));
if (sdtElement != null)
{
innerText = @"<html><head></head><body><h1>HELLO</h1></body></html>";
altChunkId = "myId1";
ms = new MemoryStream(Encoding.UTF8.GetBytes(innerText));
// Create alternative format import part.
formatImportPart =
mainDocPart.AddAlternativeFormatImportPart(
AlternativeFormatImportPartType.Html, altChunkId);
// Feed HTML data into format import part (chunk).
formatImportPart.FeedData(ms);
altChunk = new AltChunk();
altChunk.Id = altChunkId;
sdtElement.Parent.InsertAfter(altChunk, sdtElement);
contentControl = (SdtElement)wordprocessingDocument.MainDocumentPart.RootElement.Descendants<SdtElement>().FirstOrDefault(x => x.Descendants<Tag>().Any(y => y.Val == "richtextbox1"));
contentControl.Remove();
wordprocessingDocument.MainDocumentPart.CreateRelationshipToPart(formatImportPart);
wordprocessingDocument.MainDocumentPart.Document.Save();
wordprocessingDocument.Close();
}
}
附加模板的屏幕截图 并生成word文档
由于我们在Paragraph
之后插入,因此它会在Paragraph
旁边插入。因此,我们无法将数据插入到文档中存在富文本数据的正确位置。
有人可以帮我解决这个问题/建议任何其他方法来实现吗?
答案 0 :(得分:0)
docx4j实现了内容控制数据绑定的一些约定,称为&#34; OpenDoPE&#34;。 (我对这个名字负责,还有更多......)
OpenXML允许您通过XPath表达式将内容控件绑定到XML元素(在CustomXML数据部分中)。
使用OpenDoPE,该XML元素可以包含转义的XHTML,而docx4j会自动将该XHTML转换为真正的Word内容。
答案 1 :(得分:0)
您要做的不是altChunk的功能。 altChunk只能在块级别插入内容,而不能在运行级别插入内容。此外,您可以做很少的事情来影响altChunk内容的处理。 Word(或Word Automation Services)可以完成它所做的工作,而且你无法改变它。
您是导入RTF的唯一选择吗?您是否有其他可能的格式,例如XHTML或?
我想到了一个非常奇怪的想法 - 如果您在要导入RTF的位置插入文本框怎么办?我很确定你可以在文本框中导入 - 事实上,你会在块级别导入内容。您可以创建一个随文本移动的内嵌文本框。虽然不是超级简单,但您也可以影响相对于文本显示文本框的位置。根据您的实际情况,这可能是可能的。
如果要导入HTML,可以选择在适当的位置将HTML转换为WordprocessingML。这更可行。我不知道任何将RTF转换为WordprocessingML的工具(虽然这听起来像一个有趣的项目!)
-Eric