繁体   English   中英

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

[英]Word OpenXml Word Found Unreadable Content

我们正在尝试根据某些条件操作 word 文档以删除段落。 但是当我们尝试打开它并出现错误时,生成的单词文件总是最终被损坏:

Word 发现无法读取的内容

下面的代码会损坏文件,但如果我们删除该行:

Document document = mdp.Document;

文件被保存并打开没有问题。 是否有我遗漏的明显问题?

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

更新:

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

                document.Save();
            }

在物理文件上运行上面的代码,我们仍然可以打开 Original.docx 而不会出现错误,因此它似乎仅限于修改流。

这是一个将文档读入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;
}

注意MemoryStream是如何实例化的。 我传递的是容量而不是缓冲区(如您自己的代码)。 这是为什么?

使用MemoryStream()MemoryStream(int) ,您正在创建一个可调整大小的MemoryStream实例,以防您对文档进行更改。 当使用MemoryStream(byte[]) (如在您的代码中)时, MemoryStream实例不可调整大小,除非您不对文档进行任何更改,否则您的更改只会使其尺寸缩小,否则这将是有问题的。

现在,要将 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());

请注意,每当您的下一个操作取决于MemoryStream.Position属性(例如CopyToCopyToAsync )时,您都必须通过调用stream.Seek(0, SeekOrigin.Begin)来重置stream.Position属性。 在离开 using 语句之后,流的位置将等于其长度。

暂无
暂无

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

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