Поток в пакет, пакет в WordDocument, а затем снова обратно - PullRequest
7 голосов
/ 22 июля 2011

Я не понимаю всей механики, связанной с потоками, и еще меньше - с классом System.IO.Package.

У меня есть документ .docx в виде двоичного файла в базе данных, и я не хочу его извлекать,измените его и сохраните.

В настоящее время у меня есть метод, который изменяет документ в отдельной библиотеке, потому что он будет использоваться во многих местах.

Вот как я пытался это сделать:

byte[] doc = getDocFromDB();
using (MemoryStream mem = new MemoryStream())
{
    mem.Write(doc, 0, doc.Length);

    Package pack = Package.Open(mem, FileMode.Open, FileAccess.ReadWrite);
    filler.FillTemplate(ref pack, someIrreleventData);

    string filePath = Path.GetTempPath() + "docname.docx";

    using (FileStream file = new FileStream(filePath, FileMode.Create))
    {
        mem.WriteTo(file);
        file.Flush();
        file.Close();
    }

    Process.Start(filePath);
}

Код библиотеки выглядит примерно так:

public void FillTemplate(ref Package package, XElement data)
{
    WordprocessingDocument document = WordprocessingDocument.Open(package);

    //add the data to the document

    //should I do document.close() or document.dispose() here?

}

Документ просто выходит так же, как был сохранен в БД без добавления всех дополнительных данных.

Я предполагал, что при открытии пакета с потоком памяти все изменения в пакете также будут сохранены в потоке.

Что я делаю неправильно и как я могу сделать это лучше.

РЕДАКТИРОВАТЬ

Я ошибся, в моем коде ничего не сломано.Проблема заключалась в том, что часть someIrreleventData была нулевой, и и средство извлечения, и код внутри метода FillTemplate не обрабатывали исключение правильно.

1 Ответ

4 голосов
/ 25 июля 2011

Я не вижу места, где вы звоните Flush() и / или Close() в пакете, прежде чем пытаться сохранить его в файл ...попробуйте изменить

mem.Write(doc, 0, doc.Length);

mem.Position = 0; // new, perhaps this is relevant for Package.Open ?

Package pack = Package.Open(mem, FileMode.Open, FileAccess.ReadWrite);
filler.FillTemplate(ref pack, someIrreleventData);

pack.Flush(); pack.Close(); // new
mem.Position = 0;  // new

И: да, вам следует позвонить document.Close().

Вызов .Dispose() - хорошая идея, хотя было бы даже лучше, если бы вы использовали блок usingкоторый заботится об этом и нескольких других вещах ...

...