![](/img/trans.png)
[英]Word found unreadable content in xxx.docx after split a docx using openxml
[英]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
属性(例如CopyTo
、 CopyToAsync
)时,您都必须通过调用stream.Seek(0, SeekOrigin.Begin)
来重置stream.Position
属性。 在离开 using 语句之后,流的位置将等于其长度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.