如何使用 Excel Interop 获取 CustomDocumentProperties?
How to get CustomDocumentProperties using Excel Interop?
以下代码用于获取 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
:
Unable to cast COM object of type 'System.__ComObject' to interface type 'Microsoft.Office.Core.DocumentProperties'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{2DF8D04D-5BFA-101B-BDE5-00AA0044DE52}' failed due to the following error: No such interface supported (Exception from 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
I noticed that Microsoft.Office.Interop.Excel.Application is an interface, so using new on interface is actually strange to me.
这确实很奇怪,但这是设计使然。 Excel.Application
接口用 CoClass
属性修饰,告诉实际的 class 在 'instantiating' 接口上实例化。更多信息 here.
But when using
new Application()
, theworkbook.CustomDocumentProperties
line throwsInvalidCastException
:
果然又奇怪了。我自己在使用文档属性时遇到了一些问题。似乎返回的实际 class 与规范不同,所以我转而使用 dynamic
以防止类型转换问题。
所以不是这个:
Microsoft.Office.Core.DocumentProperties properties = workbook.CustomDocumentProperties;
使用:
dynamic properties = workbook.CustomDocumentProperties;
How can I create a proper Application that can get the CustomDocumentProperties?
如果您开发外接程序,则无需创建新的 Excel 应用程序实例。您应该使用 VSTO 运行时提供的应用程序 属性:
var xlApp = Globals.ThisAddIn.Application; // This works in VSTO Excel Add-in
但是如果您开发一个独立的应用程序来自动化 Excel,在这种情况下您需要使用新的运算符创建一个新的应用程序实例:
var xlApp = new global::Microsoft.Office.Interop.Excel.Application();
按照 How To Use Automation to Get and to Set Office Document Properties with Visual C# .NET 文章的建议,使用后期绑定技术 (Type.InvokeMember) 获取或设置文档 属性。
我遇到了同样的问题。今天已经解决了。有不同的方法来得出结果。问题及其答案位于
这是我的实现。
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);