简体   繁体   English

Word OpenXml Word 发现无法读取的内容

[英]Word OpenXml Word Found Unreadable Content

We are trying to manipulate a word document to remove a paragraph based on certain conditions.我们正在尝试根据某些条件操作 word 文档以删除段落。 But the word file produced always ends up being corrupted when we try to open it with the error:但是当我们尝试打开它并出现错误时,生成的单词文件总是最终被损坏:

Word found unreadable content Word 发现无法读取的内容

The below code corrupts the file but if we remove the line:下面的代码会损坏文件,但如果我们删除该行:

Document document = mdp.Document;

The the file is saved and opens without issue.文件被保存并打开没有问题。 Is there an obvious issue that I am missing?是否有我遗漏的明显问题?

 var readAllBytes = File.ReadAllBytes(@"C:\Original.docx");


    using (var stream = new MemoryStream(readAllBytes))
    {
    using (WordprocessingDocument wpd = WordprocessingDocument.Open(stream, true))
    {
        MainDocumentPart mdp = wpd.MainDocumentPart;
        Document document = mdp.Document;

    }
}

File.WriteAllBytes(@"C:\New.docx", readAllBytes);

UPDATE:更新:

using (WordprocessingDocument wpd = WordprocessingDocument.Open(@"C:\Original.docx", true))
            {
                MainDocumentPart mdp = wpd.MainDocumentPart;
                Document document = mdp.Document;

                document.Save();
            }

Running the code above on a physical file we can still open Original.docx without the error so it seems limited to modifying a stream.在物理文件上运行上面的代码,我们仍然可以打开 Original.docx 而不会出现错误,因此它似乎仅限于修改流。

Here's a method that reads a document into a MemoryStream :这是一个将文档读入MemoryStream

public static MemoryStream ReadAllBytesToMemoryStream(string path)
{
    byte[] buffer = File.ReadAllBytes(path);
    var destStream = new MemoryStream(buffer.Length);
    destStream.Write(buffer, 0, buffer.Length);
    destStream.Seek(0, SeekOrigin.Begin);
    return destStream;
}

Note how the MemoryStream is instantiated.注意MemoryStream是如何实例化的。 I am passing the capacity rather than the buffer (as in your own code).我传递的是容量而不是缓冲区(如您自己的代码)。 Why is that?这是为什么?

When using MemoryStream() or MemoryStream(int) , you are creating a resizable MemoryStream instance, which you will want in case you make changes to your document.使用MemoryStream()MemoryStream(int) ,您正在创建一个可调整大小的MemoryStream实例,以防您对文档进行更改。 When using MemoryStream(byte[]) (as in your code), the MemoryStream instance is not resizable, which will be problematic unless you don't make any changes to your document or your changes will only ever make it shrink in size.当使用MemoryStream(byte[]) (如在您的代码中)时, MemoryStream实例不可调整大小,除非您不对文档进行任何更改,否则您的更改只会使其尺寸缩小,否则这将是有问题的。

Now, to read a Word document into a MemoryStream , manipulate that Word document in memory, and end up with a consistent MemoryStream , you will have to do the following:现在,要将 Word 文档读入MemoryStream ,在内存中操作该 Word 文档,并最终获得一致的MemoryStream ,您必须执行以下操作:

// Get a MemoryStream.
// In this example, the MemoryStream is created by reading a file stored
// in the file system. Depending on the Stream you "receive", it makes
// sense to copy the Stream to a MemoryStream before processing.
MemoryStream stream = ReadAllBytesToMemoryStream(@"C:\Original.docx");

// Open the Word document on the MemoryStream.
using (WordprocessingDocument wpd = WordprocessingDocument.Open(stream, true)
{
    MainDocumentPart mdp = wpd.MainDocumentPart;
    Document document = mdp.Document;
    // Manipulate document ...
}

// After having closed the WordprocessingDocument (by leaving the using statement),
// you can use the MemoryStream for whatever comes next, e.g., to write it to a
// file stored in the file system.
File.WriteAllBytes(@"C:\New.docx", stream.GetBuffer());

Note that you will have to reset the stream.Position property by calling stream.Seek(0, SeekOrigin.Begin) whenever your next action depends on that MemoryStream.Position property (eg, CopyTo , CopyToAsync ).请注意,每当您的下一个操作取决于MemoryStream.Position属性(例如CopyToCopyToAsync )时,您都必须通过调用stream.Seek(0, SeekOrigin.Begin)来重置stream.Position属性。 Right after having left the using statement, the stream's position will be equal to its length.在离开 using 语句之后,流的位置将等于其长度。

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

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