2011-07-22 8 views
7

No entiendo todas las mecánicas que rodean a Streams y mucho menos en la clase System.IO.Package.Transmitir en paquete, paquete en WordDocument y luego nuevamente

Tengo un documento .docx como un binario en una Base de datos y no quiero buscarlo, modificarlo un poco y luego guardarlo.

Actualmente tengo el método que modifica el documento en una biblioteca separada porque se usará en muchos lugares.

Esta es la forma en que traté de hacer esto:

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); 
} 

Con el código de la biblioteca va algo como esto:

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? 

} 

El documento sólo sale del mismo modo que se guarda en la base de datos sin todos los datos adicionales agregados en.

Supuse que al abrir el paquete con una secuencia de memoria, todos los cambios en el paquete se guardarían también en la transmisión.

¿Qué estoy haciendo mal y cómo puedo hacerlo mejor?

EDITAR

que estaba equivocado, no hay nada roto con mi código. El problema era que alguna parte deIrreleventData era nula y tanto el buscador como el código dentro del método FillTemplate no manejaban la excepción correctamente.

+0

lo que es str en Package.Open (str ...) ? ¿Debería leer eso? ¿Es este tu código real o lo has modificado antes de pegarlo? – Eddy

+0

Lo modifiqué de str a mem con la intención de hacerlo más legible. Supongo que eso falló:/Lo he arreglado. –

Respuesta

4

no veo ningún lugar en el que se llama a Flush() y/o Close() en el paquete antes de tratar de guardarla en un archivo ...
intente cambiar

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 

Y: Sí, debe llamar document.Close().

Calling .Dispose() es una buena idea, aunque incluso sería mejor si usted utiliza como using bloque que se encarga de eso y varias otras cosas ...

+0

OK Estoy otorgando a su respuesta la respuesta correcta por su intento de ayudarme. Tu respuesta no es incorrecta y tampoco lo es mi código original. Tuve dos capas de mal manejo de excepciones que no me permitieron saber que la parte someIrreleventData era en realidad nula y no me di cuenta. Debería haberlo depurado un poco mejor antes de convertirme en SO. Gracias. –

Cuestiones relacionadas