2012-11-14 79 views
1

對於我在大學的其中一個項目,我必須創建一個測試作爲Word文檔,並添加一些ActiveX表單以供其他人完成。在此之後,我不得不以編程方式從中提取答案,並在考試中添加成績。獲取ActiveX控件值的OpenXML SDK

我用OpenXML SDK來處理文檔,但它讓我很頭疼,因爲我找不到獲取ActiveX值的方法。

那麼解決方案是什麼?

回答

1

在搜索互聯網和對文檔進行一些嗅探後,我發現ActiveX控件數據可以在由控件ID指定的文檔部分中找到。確定控制的類型有點棘手,因爲我沒有找到任何有關這方面的文檔。顯然,您必須從控件中獲取「classid」屬性,並嘗試將其與您所知道的classids進行匹配。以下是確定三種控件類型值的代碼。其餘的ID標記爲未知,您可以直觀地將它們與您在文檔中添加的ID進行匹配。


using System; 
using System.Collections.Generic; 
using System.Xml.Linq; 
using System.Xml; 
using System.IO; 
using System.Text; 
using DocumentFormat.OpenXml; 
using DocumentFormat.OpenXml.Wordprocessing; 
using DocumentFormat.OpenXml.Packaging; 

namespace OpenXMLTest 
{ 
    class Program 
    { 
     const string textBoxId = "{8BD21D10-EC42-11CE-9E0D-00AA006002F3}"; 
     const string radioButtonId = "{8BD21D50-EC42-11CE-9E0D-00AA006002F3}"; 
     const string checkBoxId = "{8BD21D40-EC42-11CE-9E0D-00AA006002F3}"; 

     static void Main(string[] args) 
     { 
      string fileName = @"C:\Users\Andy\Desktop\test_l1demo.docx"; 
      using (WordprocessingDocument doc = WordprocessingDocument.Open(fileName, false)) 
      { 
       foreach (Control control in doc.MainDocumentPart.Document.Body.Descendants()) 
       { 
        Console.WriteLine(); 
        Console.WriteLine("Control {0}:", control.Name); 
        Console.WriteLine("Id: {0}", control.Id); 

        displayControlDetails(doc, control.Id); 
       } 
      } 

      Console.Read(); 
     } 

     private static void displayControlDetails(WordprocessingDocument doc, StringValue controlId) 
     { 
      string classId, type, value; 

      OpenXmlPart part = doc.MainDocumentPart.GetPartById(controlId); 
      OpenXmlReader reader = OpenXmlReader.Create(part.GetStream()); 
      reader.Read(); 
      OpenXmlElement controlDetails = reader.LoadCurrentElement(); 

      classId = controlDetails.GetAttribute("classid", controlDetails.NamespaceUri).Value; 

      switch (classId) 
      { 
       case textBoxId: 
        type = "TextBox"; 
        break; 
       case radioButtonId: 
        type = "Radio Button"; 
        break; 
       case checkBoxId: 
        type = "CheckBox"; 
        break; 
       default: 
        type = "Not known"; 
        break; 
      } 

      value = "No value attribute"; //displays this if there is no "value" attribute found 
      foreach (OpenXmlElement child in controlDetails.Elements()) 
      { 
       if (child.GetAttribute("name", controlDetails.NamespaceUri).Value == "Value") 
       { 
        //we've found the value typed by the user in this control 
        value = child.GetAttribute("value", controlDetails.NamespaceUri).Value; 
       } 
      } 

      reader.Close(); 

      Console.WriteLine("Class id: {0}", classId); 
      Console.WriteLine("Control type: {0}", type); 
      Console.WriteLine("Control value: {0}", value); 

     } 
    } 
}