1

大学での私のプロジェクトの1つでは、Word文書としてテストを作成し、その中にいくつかのActiveXフォームを追加して、別の人が記入する必要がありました。この後、私はそれからプログラムで答えを抽出し、テストに成績をつける必要がありました。

ドキュメントの処理にOpenXMLSDKを使用しましたが、ActiveX値を取得する方法が見つからなかったため、頭痛の種になりました。

それで、解決策は何でしたか?

4

1 に答える 1

3

インターネットを検索し、ドキュメントを少し調べたところ、ActiveXコントロールデータがコントロールIDで指定されたドキュメント部分にあることがわかりました。コントロールのタイプを決定することは、これに関するドキュメントが見つからなかったため、少し注意が必要です。どうやら、コントロールから「classid」属性を取得し、それを既知のclassidと一致させようとする必要があります。以下は、3種類のコントロールの値を決定するためのコードです。残りの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);

        }
    }
}
于 2012-11-14T11:15:01.013 に答える