如何使用c#excel互操作读取excel自定义文档属性
我正在尝试检查是否为excel文件设置了自定义文档属性。如果设置了,则读取值 这是我正在使用的代码,但到目前为止运气不好。它没有进入foreach循环,而是出来了如何使用c#excel互操作读取excel自定义文档属性,c#,excel,office-interop,C#,Excel,Office Interop,我正在尝试检查是否为excel文件设置了自定义文档属性。如果设置了,则读取值 这是我正在使用的代码,但到目前为止运气不好。它没有进入foreach循环,而是出来了 var propval = ReadDocumentProperty("TestProp"); private string ReadDocumentProperty(string propertyName) { Office.DocumentProperties properties; Excel.Workbook
var propval = ReadDocumentProperty("TestProp");
private string ReadDocumentProperty(string propertyName)
{
Office.DocumentProperties properties;
Excel.Workbook Wb = Globals.ThisAddIn.Application.ActiveWorkbook;
properties = (Office.DocumentProperties)Wb.CustomDocumentProperties;
foreach (Office.DocumentProperty prop in properties)
{
if (prop.Name == propertyName)
{
return prop.Value.ToString();
}
}
return null;
}
更新1:
我找到了设置自定义属性的代码
Excel.Workbook workBk = Globals.ThisAddIn.Application.ActiveWorkbook;
object oDocCustomProps = workBk.CustomDocumentProperties;
Type typeDocCustomProps = oDocCustomProps.GetType();
object[] oArgs = {propertyName,false,
Microsoft.Office.Core.MsoDocProperties.msoPropertyTypeString,
propertyValue};
typeDocCustomProps.InvokeMember("Add", BindingFlags.Default |
BindingFlags.InvokeMethod, null,
oDocCustomProps, oArgs);
这可以很好地设置自定义属性。我不知道如何修改它来读取属性值。原理是一样的。一些关于如何使用PInvoke的研究将有助于在办公“互操作”中使用PInvoke。为了使用它,有必要充分了解Office对象模型中需要处理的部分:对象、属性或方法,以及需要哪些参数,因为没有IntelliSense可以提供帮助。首先在VBA接口中进行测试可以使这更容易 我在一个测试项目中使用的以下代码片段演示了如何处理单个文档属性并读取然后写入其值。请注意,示例代码与
内置文档属性
一起使用。如果需要,可以将其更改为CustomDocumentProperties
private void btnUpdateCustomDocProp_Click(object sender, EventArgs e)
{
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
Excel.Application xlApp = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.application");
Excel.Workbook wb = xlApp.ActiveWorkbook;
object docProps = wb.BuiltinDocumentProperties;
object prop = ExistsDocProp("Author", docProps);
if (prop!=null)
{
object oProp = prop;
Type oPropType = oProp.GetType();
//read current value
string propValue = oPropType.InvokeMember("Value",
BindingFlags.GetProperty | BindingFlags.Default,
null, oProp, new object[] { }).ToString();
object oPropValue = "new test author";
//write new value
oPropType.InvokeMember("Value",
BindingFlags.SetProperty | BindingFlags.Default,
null, oProp, new object[] {oPropValue});
MessageBox.Show(propValue + ", " + oPropValue.ToString());
}
}
private object ExistsDocProp(string propName, object props)
{
Office.DocumentProperty customDocProp = null;
Type docPropsType = props.GetType();
object nrProps;
object itemProp = null;
object oPropName;
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())
{
break;
}
}
return itemProp;
}
private void btnUpdateCustomDocProp\u单击(对象发送方,事件参数e)
{
System.Threading.Thread.CurrentThread.CurrentCulture=新系统.Globalization.CultureInfo(“en-US”);
Excel.Application xlApp=(Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject(“Excel.Application”);
Excel.Workbook wb=xlApp.ActiveWorkbook;
对象docProps=wb.BuiltinDocumentProperties;
object prop=ExistsDocProp(“作者”,docProps);
如果(prop!=null)
{
对象oProp=prop;
类型oPropType=oProp.GetType();
//读取当前值
string propValue=oPropType.InvokeMember(“值”,
BindingFlags.GetProperty | BindingFlags.Default,
null,oProp,新对象[]{}.ToString();
对象oPropValue=“新测试作者”;
//写新值
oPropType.InvokeMember(“值”,
BindingFlags.SetProperty | BindingFlags.Default,
null,oProp,新对象[]{oPropValue});
Show(propValue+,“+oPropValue.ToString());
}
}
私有对象ExistsDocProp(字符串propName,对象props)
{
Office.DocumentProperty customDocProp=null;
类型docPropsType=props.GetType();
对象属性;
objectitemprop=null;
对象名称;
nrProps=docPropsType.InvokeMember(“计数”,
BindingFlags.GetProperty | BindingFlags.Default,
null,props,新对象[]{});
int iProps=(int)nrProps;
对于(int counter=1;counter如果它没有进入循环,则没有自定义属性。正常情况下。@HansPassant,但文档有一个自定义属性。@Hesoti代码在我运行它时起作用,可能是您如何测试它的问题。添加属性后是否保存生成的脏工作簿?您应该能够simp同样要确保添加成功—下面是两个都有效的示例:第一组代码是特定于VSTO的,并且只有在使用“工具”时才有效@MikeJ如果你仔细阅读了这个问题,你会发现第二组代码确实有效,只是没有达到要求。该代码添加了文档属性,但OP想要读取它们。这不是一种尝试…@Cindymister我的评论与读取属性的代码片段有关-对我来说,它在他发布时起作用。阅读彻底提问:第一个代码块对他不起作用-第二个代码块中没有循环。这解决了我的问题。非常感谢。为了获得自定义文档属性,我根据您的建议对其进行了一些更改。object customProperties=workBk.CustomDocumentProperties;Type docPropsType=customProperties.GetType()
@Cindymister我很好奇为什么你需要使用system.runtime方法而不是简单地直接使用接口?@MikeJ我不确定system.runtime方法和接口是什么意思?你的意思是,为什么需要PInvoke?@Cindymister你所做的不是PInvoke。你正在使用.net运行时绑定到C#接口s、 我想知道为什么这是必要的。@MikeJDocumentProperties
实际上是一个Office,而不是Word对象。Word将其内置文档属性
和自定义文档属性
建立在其对象模型中,并提供这些属性,就好像它们是“本机的”一样这在VBA中很好用。但是C#因为更严格,所以无法访问这些东西,只能通过“后期绑定”,而不能通过单词PIAs访问。使用WordBasic
“名称空间”的任何东西也是如此(这至少给了你一个线索,因为VBA中甚至没有智能感知).我在MS文档中查找了一篇使用“更好”术语的文章,但是。。。