如何使用 c# excel 互操作读取 excel 自定义文档 属性

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

我正在尝试检查是否为 excel 文件设置了自定义文档 属性。如果设置,则读取值。

这是我正在使用的代码,但到目前为止还没有成功。不进foreach循环就出来了

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);

这可以很好地设置自定义 属性。我不知道如何修改它以读取 属性 值。

原理是一样的。当需要使用 Office "interop" 时,对如何使用 PInvoke 的一些研究会有所帮助。为了使用它,有必要完全理解 您需要解决的 Office 对象模型部分:对象、属性 或方法以及确切需要的参数因为没有可以提供帮助的 IntelliSense。首先在 VBA 界面中进行测试可以使这更容易。

我在测试项目中的以下代码片段演示了如何处理单个文档 属性 并读取,然后写入其值。请注意,示例代码适用于 BuiltInDocumentProperties。如果需要,可以将其更改为 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; 
    }