以下代码用于获取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'。此操作失败 因为QueryInterface调用COM组件的接口 与IID' {2DF8D04D-5BFA-101B-BDE5-00AA0044DE52}'由于失败而失败 以下错误:不支持此类接口(来自HRESULT的异常: 0x80004002(E_NOINTERFACE))。
我试图让它在没有VSTO的C#winforms项目上工作。很多示例和教程都使用new Application()
进行Excel互操作,但我注意到Microsoft.Office.Interop.Excel.Application
是一个接口,因此在接口上使用new
对我来说实际上很奇怪。如何创建可以获得CustomDocumentProperties
?
我正在使用的参考装配体:
答案 0 :(得分:2)
我注意到Microsoft.Office.Interop.Excel.Application是一个接口,因此使用new on interface对我来说实际上很奇怪。
确实很奇怪,但设计却如此。 Excel.Application
接口使用CoClass
属性进行修饰,告诉实际的类实例化'实例化'界面。关于它的更多信息here。
但在使用
new Application()
时,workbook.CustomDocumentProperties
行会引发InvalidCastException
:
确实很奇怪。我自己使用文档属性遇到了一些问题。似乎返回的实际类与规范不同,因此我转而使用dynamic
以防止类型转换问题。
所以不要这样:
Microsoft.Office.Core.DocumentProperties properties = workbook.CustomDocumentProperties;
使用:
dynamic properties = workbook.CustomDocumentProperties;
答案 1 :(得分: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 文章所示。
答案 2 :(得分: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);