Вы передаете mem
в WordprocessingDocument.Create()
, который создает документ из (теперь пустого) MemoryStream
, однако я не думаю, что это связывает MemoryStream
как резервное хранилище документ. То есть mem
- это только ввод документа, но не вывод . Поэтому, когда вы вызываете mem.WriteTo(file);
, mem
все еще пуст (отладчик подтвердит это).
С другой стороны, связанный документ действительно говорит: «Вы должны предоставить поток памяти с изменяемым размером для [Open()
» ] ", что означает, что поток будет записан в, поэтому, возможно, mem
становится резервным хранилищем, но в него еще ничего не записано, потому что свойство AutoSave
( для которого вы указали true
в Create()
) еще не было возможности вступить в силу (выделено мое) ...
Получает флаг, который указывает, следует ли сохранять детали при утилизации.
Я вижу, что WordprocessingDocument
имеет SaveAs()
метод и заменяет его на FileStream
в исходном коде. .
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"));
// Explicitly close the OpenXmlPackage returned by SaveAs() so destination doesn't stay locked
doc.SaveAs(destination).Close();
}
... создает ожидаемый файл для меня. Интересно, что после вызова на doc.SaveAs()
и даже если я вставлю вызов на doc.Save()
, mem.Length
и mem.Position
оба по-прежнему 0
, что предполагает, что mem
используется только для инициализации.
Еще одна вещь, которую я хотел бы отметить, это то, что пример кода вызывает Open()
, тогда как вы звоните Create()
. Документация довольно скудная, поскольку эти два метода различаются, но я бы посоветовал вам попробовать создать документ с помощью Open()
вместо ...
using (MemoryStream mem = new MemoryStream())
using (WordprocessingDocument doc = WordprocessingDocument.Open(mem, true))
{
// ...
}
... однако когда я это делаю, Open()
выдает исключение, вероятно, потому что mem
не имеет данных. Таким образом, кажется, что названия несколько очевидны, так как Create()
инициализирует новые данные документа, тогда как Open()
ожидает существующие данные. Я обнаружил, что если я кормлю Create()
a MemoryStream
, заполненный случайным мусором ...
using (var mem = new MemoryStream())
{
// Fill mem with garbage
byte[] buffer = new byte[1024];
new Random().NextBytes(buffer);
mem.Write(buffer, 0, buffer.Length);
mem.Position = 0;
using (var doc = WordprocessingDocument.Create(mem, WordprocessingDocumentType.Document, true))
{
// ...
}
}
... он все равно выдает точно такой же документ XML как первый фрагмент кода выше, который заставляет меня задуматься, почему Create()
вообще нужен ввод Stream
.