Open hxhgxy opened 1 year ago
At the moment we don't support ContentControl (I even didn't knew it existed).
Some docs fo future implementation:
If someone/you want to tackle this it would be great :-) If not, probably if I will be bored enough I'll take a look what Content Control is and will decide.
Quick look for a custom form based on:
Added a single element, and it looks like this
using DocumentFormat.OpenXml.Wordprocessing;
using DocumentFormat.OpenXml;
namespace GeneratedCode
{
public class GeneratedClass
{
// Creates an SdtBlock instance and adds its children.
public SdtBlock GenerateSdtBlock()
{
SdtBlock sdtBlock1 = new SdtBlock();
SdtProperties sdtProperties1 = new SdtProperties();
SdtId sdtId1 = new SdtId(){ Val = 734359063 };
SdtPlaceholder sdtPlaceholder1 = new SdtPlaceholder();
DocPartReference docPartReference1 = new DocPartReference(){ Val = "DefaultPlaceholder_-1854013440" };
sdtPlaceholder1.Append(docPartReference1);
SdtContentText sdtContentText1 = new SdtContentText();
sdtProperties1.Append(sdtId1);
sdtProperties1.Append(sdtPlaceholder1);
sdtProperties1.Append(sdtContentText1);
SdtContentBlock sdtContentBlock1 = new SdtContentBlock();
Paragraph paragraph1 = new Paragraph(){ RsidParagraphAddition = "00A7755C", RsidRunAdditionDefault = "00A7755C", ParagraphId = "21E9D7DC", TextId = "7A60725A" };
Run run1 = new Run();
Text text1 = new Text();
text1.Text = "Test";
run1.Append(text1);
paragraph1.Append(run1);
sdtContentBlock1.Append(paragraph1);
sdtBlock1.Append(sdtProperties1);
sdtBlock1.Append(sdtContentBlock1);
return sdtBlock1;
}
}
}
It's similar to Watermark and a few other elements we already kind of support.
I assume this is Content Control you mean right?
Here is the way i figure out to get all contentcontrol (richtextbox) in a document and find one whose tag is what I am looking for:
/// <summary>
/// 查找并返回指定Word文档里的所有内容控件集合
/// </summary>
/// <param name="document">指定文档</param>
/// <returns></returns>
public List<SdtElement> ContentControls(WordprocessingDocument document)
{
List<SdtElement> contentControls = new List<SdtElement>();
var allElements = document.MainDocumentPart.Document.Body.ChildElements;
foreach (var element in allElements)
{
if (element is SdtElement)
{
contentControls.Add((SdtElement)element);
}
else
{
getChildren(element, contentControls);
}
}
return contentControls;
}
/// <summary>
/// 查找指定元素的所有层级的子元素
/// </summary>
/// <param name="element">指定的元素</param>
/// <param name="contentControls">符合要求的元素的集合</param>
private void getChildren(OpenXmlElement element, List<SdtElement> contentControls)
{
if (element.HasChildren == true)
{
foreach (OpenXmlElement child in element.ChildElements)
{
if (child is SdtElement)
{
contentControls.Add((SdtElement)child);
}
else
{
getChildren(child, contentControls);
}
}
}
}
/// <summary>
/// 从内容控件集合里找到指定Tag的内容控件
/// </summary>
/// <param name="contentControls">内容控件集合</param>
/// <param name="tagName">指定的Tag</param>
/// <returns></returns>
public SdtElement ContentControl(List<SdtElement> contentControls, string tagName)
{
foreach (SdtElement item in contentControls)
{
var tag = item.SdtProperties?.GetFirstChild<Tag>();
if (tag != null && tag.Val.HasValue)
{
if (tag.Val == tagName)
{
return item;
}
}
}
return null;
}
By the way, by using your codes or the codes from OpenXML tools, it is quite easy to create a document. But i didn't figure out how to open an existing document to find some parts to edit.
I made a word template (.docx) in a folder. Everytime, I open the document and then save as a new file. i want to make edition on the new one. however, if i open the original one with iseditable=true, all revision will be saved to the original one.
I tried to open the original document with no editable, and save as a new one. when I try to open the new document right after, it is occupied.
What should i do?
Thanks.
It's a bug I think:
It seems to be a bug in the Open-XML-SDK. I guess workaround would be to copy document before opening it up, and use Load that way. It's a different issue, so lets no hijack this thread here.
How can I insert ContentControl or input text into an existing contentcontrol?
Thanks a lot!