我正在尝试将自定义属性添加到我以编程方式创建的工作簿中。我有一个方法来获取和设置属性,但问题是工作簿为CustomDocumentProperties属性返回null。我无法弄清楚如何初始化此属性,以便我可以从工作簿中添加和检索属性。 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)
答案 0 :(得分:12)
如果您的目标是.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);
}
}
答案 1 :(得分:11)
我查看了自己的代码,可以看到我使用后期绑定访问属性。我不记得为什么,但我会发布一些代码以防万一。
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);
编辑:啊,现在我记得why。 : - )
编辑2 :Jimbojones的回答 - 使用动态关键字 - 是一个更好的解决方案(如果您重视使用dynamic
的性能开销的易用性。< / p>
答案 2 :(得分:7)
我找到了解决方案here。
以下是我最终得到的代码:
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 :(得分:3)
对这个问题的回答很晚,但我找到了一种更简单的方法来添加可能对将来有用的自定义DocumentProperties。
我的问题是使用System.String.GetType()提供的System类型调用Add()方法会触发COMException:类型不匹配。参考前面答案中的链接,很明显这种方法需要特定于Office的类型,因此最终为我工作的代码是:
var custProps = (Office.DocumentProperties)this.CustomDocumentProperties;
custProps.Add( "AProperty", false, MsoDocProperties.msoPropertyTypeString, "AStringProperty" );
因为它是一个CustomDocumentProperty Office会毫无困难地添加自定义属性,但如果你需要检查是否存在或者在CustomDocumentProperty可能不存在时验证该值,则必须捕获System.ArgumentException。
修改强>
正如Oliver Bock的评论所指出的,据我所知,这是一个Office 2007及以上的唯一解决方案。