如何使用Excel Interop获取CustomDocumentProperties?

问题描述 投票:3回答:3

下面的代码用于获取Excel工作簿的自定义文档属性。

var xlApp = Globals.ThisAddIn.Application; // This works in VSTO Excel Add-in
var xlApp = new global::Microsoft.Office.Interop.Excel.Application(); // This doesn't work anywhere
xlApp.Visible = true;
global::Microsoft.Office.Interop.Excel.Workbook workbook = xlApp.Workbooks.Open(file, false, true, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, false, Type.Missing, Type.Missing);

global::Microsoft.Office.Core.DocumentProperties properties = workbook.CustomDocumentProperties; // Exception occurs here
global::Microsoft.Office.Core.DocumentProperty property = properties["propertyname"];

前两行是对Excel Application的引用。一个是从VSTO插件内部获取引用的,另一个是常规的new Application()

当使用VSTO内部的Application时,代码运行正常,没有任何问题。但是,当使用new Application()时,workbook.CustomDocumentProperties行将引发InvalidCastException

无法将类型为'System .__ ComObject'的COM对象转换为接口键入“ Microsoft.Office.Core.DocumentProperties”。该操作失败因为接口的COM组件上的QueryInterface调用IID为'{2DF8D04D-5BFA-101B-BDE5-00AA0044DE52}'的广告因以下错误:不支持这样的接口(HRESULT的异常:0x80004002(E_NOINTERFACE))。

我正在尝试使其在没有VSTO的C#winforms项目中工作。许多示例和教程都将new Application()用于Excel互操作,但是我注意到Microsoft.Office.Interop.Excel.Application是一个接口,因此在接口上使用new实际上对我来说很奇怪。如何创建可以获取CustomDocumentProperties的适当应用程序?

我正在使用的参考程序集:

  • Microsoft.Office.Interop.Excel v2.0.50727版本14.0.0.0
  • Microsoft.CSharp v4.0.30319版本4.0.0.0
c# excel interop vsto
3个回答
2
投票

[我注意到Microsoft.Office.Interop.Excel.Application是一个接口,因此实际上使用new on接口对我来说很奇怪。

确实很奇怪,但是是设计使然。 Excel.Application接口装饰有CoClass属性,该属性告诉实际的类在“实例化”该接口时实例化。有关它的更多信息here

但是使用new Application()时,workbook.CustomDocumentProperties行抛出InvalidCastException

确实再次奇怪。我自己在使用文档属性时遇到了一些问题。似乎返回的实际类与规范不同,因此我移至使用dynamic以防止类型转换问题。

所以代替这个:

Microsoft.Office.Core.DocumentProperties properties = workbook.CustomDocumentProperties;

用途:

dynamic properties = workbook.CustomDocumentProperties;

0
投票

如何创建可以获取CustomDocumentProperties的适当应用程序?

如果开发外接程序,则无需创建新的Excel应用程序实例。您应该使用VSTO运行时提供的Application属性:

var xlApp = Globals.ThisAddIn.Application; // This works in VSTO Excel Add-in

但是,如果您开发了一个自动化Excel的独立应用程序,则在这种情况下,您需要使用new运算符创建一个新的Application实例:

var xlApp = new global::Microsoft.Office.Interop.Excel.Application(); 

使用后期绑定技术(Type.InvokeMember)来获取或设置How To Use Automation to Get and to Set Office Document Properties with Visual C# .NET 文章所建议的文档属性。


0
投票

我遇到了同样的问题。今天,它已经解决。有另一种方法来得出结果。问题及其答案位于

How can I read excel custom document property using c# excel interop

这是我的实现。

public string CheckDocProp(string propName, object props)
        {
            Excel.Workbook workBk = Globals.ThisAddIn.Application.ActiveWorkbook;

            object customProperties = workBk.CustomDocumentProperties;
            Type docPropsType = customProperties.GetType();
            object nrProps;
            object itemProp = null;
            object oPropName;
            object oPropVal = null;

            nrProps = docPropsType.InvokeMember("Count",
                BindingFlags.GetProperty | BindingFlags.Default,
                null, props, new object[] { });
            int iProps = (int)nrProps;

            for (int counter = 1; counter <= ((int)nrProps); counter++)
            {
                itemProp = docPropsType.InvokeMember("Item",
                    BindingFlags.GetProperty | BindingFlags.Default,
                    null, props, new object[] { counter });

                oPropName = docPropsType.InvokeMember("Name",
                    BindingFlags.GetProperty | BindingFlags.Default,
                    null, itemProp, new object[] { });

                if (propName == oPropName.ToString())
                {
                    oPropVal = docPropsType.InvokeMember("Value",
                        BindingFlags.GetProperty | BindingFlags.Default,
                        null, itemProp, new object[] { });
                    return oPropVal.ToString();
                    break;
                }
                else
                {
                    return "Not Found.";
                }
            }
            return "Not Found.";
        }

用法:

object docProps = wb.CustomDocumentProperties;
            string prop1 = ExistsDocProp("<CustomProperty>", docProps);
© www.soinside.com 2019 - 2024. All rights reserved.