0

我正在尝试使用纯 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();
        }
4

1 回答 1

1

抱歉,对 C# 了解不多,但这是在 VB.NET 中使用 Linq、XML Literals 和 IO.Packaging 完成的(即不需要 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>- 适用于“文本”类型的自定义属性。它只是直接改变值。如果您想查询确切的客户属性或更改自定义属性的名称或使用不同的类型,您必须在下面的代码中更改一些内容。

于 2012-08-15T22:23:03.883 回答