简体   繁体   English

添加 CustomXmlPart 后 Word 无法打开文档

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

I'm trying to add a customxmlPart to a docm file without success.我正在尝试将 customxmlPart 添加到 docm 文件中,但没有成功。 Apparently the file is too big (more than 10mb) to be included in the package.显然该文件太大(超过 10mb),无法包含在包中。

If the xml file size is less than 7 mb the document can be opened successfully.如果 xml 文件大小小于 7 mb,则可以成功打开文档。

Any ideas ?有任何想法吗 ?

Thank you for your help.感谢您的帮助。

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

EDIT : I found the issue, the xml file contains lot of carriage return + line feed.编辑:我发现了这个问题,xml 文件包含很多回车 + 换行符。 After removing them i can embed the file as a CustomXmlPart.删除它们后,我可以将文件嵌入为 CustomXmlPart。

The following unit test demonstrates that you can add very large custom XML parts (up to 30MB in the example) to a Word document:以下单元测试演示了您可以向 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);
        }
    }
}

On my Windows 10 notebook, Microsoft Word for Office 365 opens the document with the 30MB custom XML part without any problems.在我的 Windows 10 笔记本上,Office 365 的 Microsoft Word 可以毫无问题地打开带有30MB自定义 XML 部分的文档。 Therefore, I'd say, your problem must be caused by other factors or a combination of factors, including any processing of the custom XML part performed by the VSTO add-in that was mentioned in a comment.因此,我想说,您的问题一定是由其他因素或多种因素引起的,包括评论中提到的 VSTO 加载项对自定义 XML 部分执行的任何处理。

I found the issue, the xml file contains lot of carriage return + line feed.我发现了这个问题,xml 文件包含很多回车 + 换行符。 After removing them i can embed the file as a CustomXmlPart.删除它们后,我可以将文件嵌入为 CustomXmlPart。

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

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