使用OpenXML在Word中获取CheckBox

如何使用OpenXML获取嵌入在Word文档中的CheckBox控件的句柄?

您会认为Paragraph.ControlPropertiesPart或Paragraph.Descendents()会实现某些function,但在每种情况下我都会返回null类型。

我可以使用实际的XML结构遍历文档树,但这看起来很麻烦。

建议欢迎。

下面的代码显示了如何使用docuement主体上的Decendants Decendants()方法枚举word文档中的所有复选框。

 using (WordprocessingDocument doc = WordprocessingDocument.Open("c:\\temp\\checkbox.docx", true)) { foreach (CheckBox cb in doc.MainDocumentPart.Document.Body.Descendants()) { Console.Out.WriteLine(cb.LocalName); FormFieldName cbName = cb.Parent.ChildElements.First(); Console.Out.WriteLine(cbName.Val); DefaultCheckBoxFormFieldState defaultState = cb.GetFirstChild(); Checked state = cb.GetFirstChild(); Console.Out.WriteLine(defaultState.Val.ToString()); if (state.Val == null) // In case checkbox is checked the val attribute is null { Console.Out.WriteLine("CHECKED"); } else { Console.Out.WriteLine(state.Val.ToString()); } } } 

要确定给定复选框输入元素的名称,您必须访问CheckBox实例的Parent属性,然后搜索FormFieldName元素(要为复选框指定名称,请使用Microsoft Word中的属性对话框)。

DefaultCheckBoxFormFieldState Val属性保持复选框的默认状态。 此外, Checked元素的Val属性保存CheckBox实例的实际检查状态。 请注意,对于Microsoft Word 2007,如果选中该复选框,则Val属性为null

开始编辑

我想扩展我的答案。 实际上,MS Word开发人员选项卡上有两种复选框控件 – 遗留复选框和ActiveX控件复选框。 上面显示的代码可用于枚举word文档中的旧复选框(请参阅有关如何创建旧版复选框的文章)。

据我所知,您不能使用OpenXML SDK来获取/设置ActiveX复选框的值。 但是,您可以使用以下代码枚举ActiveX控件:

 foreach (Control ctrl in doc.MainDocumentPart.Document.Body.Descendants()) { Console.Out.WriteLine(ctrl.Id); Console.Out.WriteLine(ctrl.Name); Console.Out.WriteLine(ctrl.ShapeId); } 

要确定给定的Control是否为复选框,您必须确定Control的类ID。 复选框的类ID为{8BD21D40-EC42-11CE-9E0D-00AA006002F3} 。 这是获取类ID的代码示例(我不知道是否有更简单的方法……):

 OpenXmlPart part = doc.MainDocumentPart.GetPartById(ctrl.Id); OpenXmlReader re = OpenXmlReader.Create(part.GetStream()); re.Read(); OpenXmlElement el = re.LoadCurrentElement(); if(el.GetAttribute("classid", el.NamespaceUri).Value == "{8BD21D40-EC42-11CE-9E0D-00AA006002F3}") { Console.WriteLine("Checkbox found..."); } re.Close(); 

结束编辑

编辑2

我没有意识到Word 2010中有一个新的复选框控件(感谢Dennis Palmer)。

要枚举这些新的复选框控件,您可以使用以下代码:

 using (WordprocessingDocument doc = WordprocessingDocument.Open(filename, true)) { MainDocumentPart mp = doc.MainDocumentPart; foreach(SdtContentCheckBox cb in mp.Document.Body.Descendants()) { if(cb.Checked.Val == "1"); { Console.Out.WriteLine("CHECKED"); } } } 

结束编辑2

希望这可以帮助。