如何在不使用Ooxml SDK的情况下更新Word文档的自定义属性?

时间:2012-08-10 03:01:39

标签: c# ms-word openxml

我正在尝试使用普通C#和XLinq而不是Ooxml SDK来更改包(Word或Excel文档)的自定义属性的值。但是,它会破坏文件并且不会反映程序包中的更改。

有人可以在这里建议不正确的内容吗?

        Package package = null;
        try
        {
            package = Package.Open("NewCustomProp.docx", FileMode.OpenOrCreate, FileAccess.ReadWrite);
            foreach (var packagePart in package.GetParts())
            {
                if (packagePart.ContentType == "application/vnd.openxmlformats-officedocument.custom-properties+xml")
                {
                    var packageStream = packagePart.GetStream(FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    using (StreamReader streamReader = new StreamReader(packageStream))
                    {
                        try
                        {
                            string ns = "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties";
                            XDocument xDocument = XDocument.Parse(streamReader.ReadToEnd());
                            var properties = xDocument.Descendants(XName.Get("property", ns)).Where(x => x.Attribute(XName.Get("name")).Value == "NewCustomProp").ToList();
                            if (properties.Count > 0)
                            {
                                foreach (var currentProperty in properties)
                                {
                                    var valueNode = currentProperty.Descendants().First();
                                    valueNode.Value = "This is new value of Custom Property";
                                }

                                StringBuilder innerXmlSB = new StringBuilder();
                                xDocument.Nodes().ToList().ForEach(node => innerXmlSB.Append(node.ToString()));
                                string innerXml = innerXmlSB.ToString();
                                byte[] buffer = Encoding.UTF8.GetBytes(innerXml);
                                packageStream.Write(buffer, 0, buffer.Length);

                                //tried this as well
                                //xDocument.Save(packageStream);
                            }
                        }
                        catch (Exception ex)
                        {
                            Debug.WriteLine(ex.ToString());
                        }
                    }
                }
            }
            package.Flush();
        }
        finally
        {
            package.Close();
        }

1 个答案:

答案 0 :(得分:1)

很抱歉,对C#了解不多,但这就是在使用Linq,XML Literals和IO.Packaging的VB.NET中完成的工作(即不需要SDK)。

Imports System.IO
Imports System.IO.Packaging
Imports <xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">
Imports System.Xml

Module Module1
    Sub Main()
        Dim docFilePath = "C:\Users\you\Documents\Doc2.docx"
        Using presentationPackage As Package = Package.Open(docFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite)
            Dim uriCustom = New Uri("/docProps/custom.xml", UriKind.Relative)
            Dim customPart = presentationPackage.GetPart(uriCustom)
            Dim customStream = New StreamReader(customPart.GetStream)

            Dim custom = XDocument.Load(customStream)
            Dim customProperties = custom.Root.Elements.<vt:lpwstr>

            For Each prop In customProperties
                prop.Value = "My New Custom Value"
            Next

            Using xw As XmlWriter = XmlWriter.Create(customPart.GetStream(FileMode.Create, FileAccess.Write))
                custom.Save(xw)
            End Using
        End Using
    End Sub

End Module

请注意,这个 - <vt:lpwstr> - 是“Text”类型的自定义属性。它只是直接改变了价值观。如果您想查询确切的客户属性或更改自定义属性的名称或使用其他类型的内容,您将不得不在下面的代码中更改一些内容。