繁体   English   中英

添加 CustomXmlPart 后 Word 无法打开文档

[英]Word can't open document after adding CustomXmlPart

我正在尝试将 customxmlPart 添加到 docm 文件中,但没有成功。 显然该文件太大(超过 10mb),无法包含在包中。

如果 xml 文件大小小于 7 mb,则可以成功打开文档。

有任何想法吗 ?

感谢您的帮助。

using (WordprocessingDocument wordDoc = WordprocessingDocument.Open("doc.docm", true))
{
    MainDocumentPart mainPart = wordDoc.MainDocumentPart;

    if (wordDoc.MainDocumentPart.CustomXmlParts != null)
    {
        wordDoc.MainDocumentPart.DeleteParts<CustomXmlPart>(wordDoc.MainDocumentPart.CustomXmlParts);
    }

    CustomXmlPart myXmlPart = mainPart.AddCustomXmlPart(CustomXmlPartType.CustomXml);

    using (FileStream stream = new FileStream("10mbfile.xml", FileMode.Open))
    {
        myXmlPart.FeedData(stream);
    }

    wordDoc.Package.Flush();
}

编辑:我发现了这个问题,xml 文件包含很多回车 + 换行符。 删除它们后,我可以将文件嵌入为 CustomXmlPart。

以下单元测试演示了您可以向 Word 文档添加非常大的自定义 XML 部分(在示例中高达 30MB):

using System;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using Xunit;

namespace CodeSnippets.Tests.OpenXml.Wordprocessing
{
    public class LargeCustomXmlPartsTests
    {
        public static readonly XNamespace W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";

        [Theory]
        [InlineData(5)]
        [InlineData(10)]
        [InlineData(15)]
        [InlineData(20)]
        [InlineData(30)]
        public void CanCreateLargeCustomXmlParts(int size)
        {
            int desiredStreamLength = size * 1024 * 1024;
            string path = $"Document_{size:D2}MB.docm";

            // Create a macro-enabled Word document with a custom XML part having
            // at least the desired size in MB.
            CreateMacroEnabledWordDocument(path, size);

            // Assert that the document does have a custom XML part with at least
            // the desired size.
            using WordprocessingDocument wordDocument = WordprocessingDocument.Open(path, false);
            CustomXmlPart customXmlPart = wordDocument.MainDocumentPart.CustomXmlParts.First();
            using Stream stream = customXmlPart.GetStream(FileMode.Open, FileAccess.Read);
            Assert.True(stream.Length > desiredStreamLength);
        }

        private static void CreateMacroEnabledWordDocument(string path, int size)
        {
            const WordprocessingDocumentType type = WordprocessingDocumentType.MacroEnabledDocument;
            using WordprocessingDocument wordDocument = WordprocessingDocument.Create(path, type);

            // Create a main document part with an empty document.
            MainDocumentPart mainDocumentPart = wordDocument.AddMainDocumentPart();
            WriteRootElement(mainDocumentPart,
                new XElement(W + "document",
                    new XElement(W + "body",
                        new XElement(W + "p"))));

            // Create a custom XML part with the desired size in MB.
            CustomXmlPart customXmlPart = mainDocumentPart.AddCustomXmlPart(CustomXmlPartType.CustomXml);
            WriteRootElement(customXmlPart, CreatePartRootElement(size));
        }

        private static void WriteRootElement(OpenXmlPart part, XElement partRootElement)
        {
            using Stream stream = part.GetStream(FileMode.Create, FileAccess.Write);
            using XmlWriter writer = XmlWriter.Create(stream);

            partRootElement.WriteTo(writer);
        }

        private static XElement CreatePartRootElement(int size)
        {
            var random = new Random();

            return new XElement("root",
                Enumerable.Range(0, size).Select(paragraphIndex =>
                    new XElement("p",
                        new XAttribute("i", paragraphIndex),
                        Enumerable.Range(0, 1000).Select(runIndex =>
                            new XElement("r",
                                new XAttribute("i", runIndex),
                                new XElement("t", CreateRandomString(random)))))));
        }

        private static string CreateRandomString(Random random)
        {
            char[] value = Enumerable
                .Range(0, 930)
                .Select(i => Convert.ToChar(random.Next(33, 125)))
                .ToArray();

            return new string(value);
        }
    }
}

在我的 Windows 10 笔记本上,Office 365 的 Microsoft Word 可以毫无问题地打开带有30MB自定义 XML 部分的文档。 因此,我想说,您的问题一定是由其他因素或多种因素引起的,包括评论中提到的 VSTO 加载项对自定义 XML 部分执行的任何处理。

我发现了这个问题,xml 文件包含很多回车 + 换行符。 删除它们后,我可以将文件嵌入为 CustomXmlPart。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM