Программный доступ к свойствам пользовательских документов Excel - PullRequest
13 голосов
/ 16 июля 2009

Я пытаюсь добавить пользовательские свойства в книгу, которую я создал программным способом. У меня есть метод для получения и установки свойств, но проблема в том, что рабочая книга возвращает значение NULL для свойства CustomDocumentProperties. Я не могу понять, как инициализировать это свойство, чтобы я мог добавлять и получать свойства из книги. Microsoft.Office.Core.DocumentProperties - это интерфейс, поэтому я не могу пойти и сделать следующее

if(workbook.CustomDocumentProperties == null)
    workbook.CustomDocumentProperties = new DocumentProperties;

Вот код, который я должен получить и установить свойства:

     private object GetDocumentProperty(string propertyName, MsoDocProperties type)
    {
        object returnVal = null;

        Microsoft.Office.Core.DocumentProperties properties;
        properties = (Microsoft.Office.Core.DocumentProperties)workBk.CustomDocumentProperties;

        foreach (Microsoft.Office.Core.DocumentProperty property in properties)
        {
            if (property.Name == propertyName && property.Type == type)
            {
                returnVal = property.Value;
            }
            DisposeComObject(property);
        }

        DisposeComObject(properties);

        return returnVal;
    }

    protected void SetDocumentProperty(string propertyName, string propertyValue)
    {
        DocumentProperties properties;
        properties = workBk.CustomDocumentProperties as DocumentProperties;

        bool propertyExists = false;
        foreach (DocumentProperty prop in properties)
        {
            if (prop.Name == propertyName)
            {
                prop.Value = propertyValue;
                propertyExists = true;
            }
            DisposeComObject(prop);

            if(propertyExists) break;
        }

        if (!propertyExists)
        {
            properties.Add(propertyName, false, MsoDocProperties.msoPropertyTypeString, propertyValue, Type.Missing);
        }

        DisposeComObject(propertyExists);

    }

Линия properties = workBk.CustomDocumentProperties as DocumentProperties; всегда устанавливайте свойства в null.

Это использует Microsoft.Office.Core v12.0.0.0 и Microsoft.Office.Interop.Excell v12.0.0.0 (Office 2007)

Ответы [ 4 ]

12 голосов
/ 06 июля 2012

Если вы ориентируетесь на .NET 4.0, вы можете использовать ключевое слово dynamic для позднего связывания

 Document doc = GetActiveDocument();
 if ( doc != null )
 {
     dynamic properties = doc.CustomDocumentProperties;
     foreach (dynamic p in properties)
     {
         Console.WriteLine( p.Name + " " + p.Value);
     }
 }
11 голосов
/ 16 июля 2009

Я посмотрел на свой собственный код и вижу, что я получаю доступ к свойствам с использованием позднего связывания. Я не могу вспомнить почему, но я выложу некоторый код на случай, если это поможет.

object properties = workBk.GetType().InvokeMember("CustomDocumentProperties", BindingFlags.Default | BindingFlags.GetProperty, null, workBk, null);

object property = properties.GetType().InvokeMember("Item", BindingFlags.Default | BindingFlags.GetProperty, null, properties, new object[] { propertyIndex });

object propertyValue = property.GetType().InvokeMember("Value", BindingFlags.Default | BindingFlags.GetProperty, null, propertyWrapper.Object, null);

РЕДАКТИРОВАТЬ : ах, теперь я помню почему . : -)

РЕДАКТИРОВАТЬ 2 : ответ Джимбоджона - использовать динамическое ключевое слово - является лучшим решением (если вы цените простоту использования над издержками производительности при использовании dynamic).

7 голосов
/ 16 июля 2009

Я нашел решение здесь .

Вот код, с которым я закончил:

    public void SetDocumentProperty(string propertyName, string propertyValue)
    {
        object oDocCustomProps = workBk.CustomDocumentProperties;
        Type typeDocCustomProps = oDocCustomProps.GetType();

        object[] oArgs = {propertyName,false,
                 MsoDocProperties.msoPropertyTypeString,
                 propertyValue};

        typeDocCustomProps.InvokeMember("Add", BindingFlags.Default |
                                   BindingFlags.InvokeMethod, null,
                                   oDocCustomProps, oArgs);

    }

    private object GetDocumentProperty(string propertyName, MsoDocProperties type)
    {
        object returnVal = null;

        object oDocCustomProps = workBk.CustomDocumentProperties;
        Type typeDocCustomProps = oDocCustomProps.GetType();


        object returned = typeDocCustomProps.InvokeMember("Item", 
                                    BindingFlags.Default |
                                   BindingFlags.GetProperty, null,
                                   oDocCustomProps, new object[] { propertyName });

        Type typeDocAuthorProp = returned.GetType();
        returnVal = typeDocAuthorProp.InvokeMember("Value",
                                   BindingFlags.Default |
                                   BindingFlags.GetProperty,
                                   null, returned,
                                   new object[] { }).ToString();

        return returnVal;
    }

Требуется некоторая обработка исключений, если свойство не существует при получении

3 голосов
/ 13 мая 2011

Поздний ответ на этот вопрос, но я разработал более простой способ добавления пользовательских свойств DocumentProperties, которые могут пригодиться кому-то в будущем.

Моя проблема заключалась в том, что вызов метода Add () с типом System, предоставленным System.String.GetType (), вызвал исключение COMException: Несоответствие типов. Ссылаясь на ссылку в предыдущих ответах, становится ясно, что этот метод ожидает специфичный для Office тип, поэтому код, который в итоге работал для меня, был:

var custProps = (Office.DocumentProperties)this.CustomDocumentProperties;
custProps.Add( "AProperty", false, MsoDocProperties.msoPropertyTypeString, "AStringProperty" );

Поскольку это CustomDocumentProperty, Office без труда добавит настраиваемое свойство, но если вам нужно проверить наличие или проверить значение, когда CustomDocumentProperty может не существовать, вам придется перехватывать исключение System.ArgumentException.

EDIT

Как отмечается в комментарии Оливера Бока, насколько мне известно, это решение Office 2007 и только для него.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...