Word OpenXml Word发现不可读的内容

时间:2019-06-18 12:51:51

标签: ms-word openxml openxml-sdk

我们正在尝试根据特定条件来操纵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而不会出现错误,因此它似乎仅限于修改流。

1 个答案:

答案 0 :(得分:0)

这是一种将文档读入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());

请注意,只要您的下一个操作取决于该stream.Position属性(例如stream.Seek(0, SeekOrigin.Begin),{{1}),就必须通过调用MemoryStream.Position来重置CopyTo属性}。离开using语句后,流的位置将等于其长度。