在将其标记为重复之前,请阅读。
我正在尝试学习如何与Microsoft的OpenXML SDK结合使用。我遵循了他们关于如何使用FileStream
创建word文档的步骤,并且效果很好。现在,我只想在内存中创建一个word文档,然后等待用户指定是否要保存文件。 Microsoft提供的这份文件
说如何使用MemoryStream
处理内存中的文档-但是,首先从现有文件中加载文档,然后将其“转储”到MemorySteam
中,我想要的是完全在内存中创建一个文档(不是基于驱动器中的文件)。我以为可以实现以下代码:
// This is almost the same as Microsoft's code except I don't
// dump any files into the MemoryStream
using (var mem = new MemoryStream())
{
using (var doc = WordprocessingDocument.Create(mem, WordprocessingDocumentType.Document, true))
{
doc.AddMainDocumentPart().Document = new Document();
var body = doc.MainDocumentPart.Document.AppendChild(new Body());
var paragraph = body.AppendChild(new Paragraph());
var run = paragraph.AppendChild(new Run());
run.AppendChild(new Text("Hello docx"));
using (var file = new FileStream(destination, FileMode.CreateNew))
{
mem.WriteTo(file);
}
}
}
但是结果是一个0Kb的文件,Word无法读取。起初我以为是因为MemoryStream
的大小,所以我给它提供了1024的初始大小,但结果却是相同的。另一方面,如果我将MemoryStream
更改为FileStream
,则效果很好。
我的问题是我想做的事是否可行,如果可以,怎么办?我想这一定有可能,而不仅仅是我做不到。如果不可能的话,我有什么选择?
我确信有人会将其标记为重复,因此在执行此操作之前,请确保所引用的问题确实涉及完全在内存中创建文档。我确实进行了搜索,但找不到任何东西,这就是为什么我问了一个新问题。
您正在将mem
传递给WordprocessingDocument.Create()
,后者是根据[现在为空] MemoryStream
创建文档的,但是,我不认为这会将MemoryStream
关联为C0的后备存储文献。也就是说,mem
只是文档的input,而不是output。因此,当您调用mem.WriteTo(file);
时,mem
仍为空(调试器将确认这一点)。
然后,链接文档确实说“您必须向[Open()
]提供可调整大小的内存流”,这意味着该流将被写入,因此mem
does可能成为后备存储但尚未写入任何内容,因为AutoSave
property(您在AutoSave
中指定了true
的目标)尚未生效(强调我的意思)...
获得一个标志,该标志指示是否应保存零件当处置时。
[看到Create()
有一个WordprocessingDocument
,我想您可以打电话...
SaveAs()
method
...而不是显式创建SaveAs()
,这会将文档的当前状态(无论是否还存在doc.SaveAs(destination);
中)串行化到磁盘。
我要注意的另一件事是,示例代码正在调用FileStream
,而您正在调用mem
。两种方法有何不同?该文档非常稀疏,因此我不知道该答案如何,但是您也可以尝试使用Open()
创建文档...
Open()