web-dev-qa-db-fra.com

PDFsharp enregistrer sur MemoryStream

Je veux enregistrer un PdfSharp.Pdf.PdfDocument par sa méthode Save dans un Stream, mais il n'y attache pas les paramètres d'en-tête PDF. Donc, quand je relis le Stream et le renvoie pour l'utilisateur, il voit que le fichier PDF PDF n'est pas valide. Existe-t-il une solution pour attacher les paramètres d'en-tête PDF lorsque PDFsharp enregistre en mémoire?)

30
misnyo

Donc la solution:

MigraDoc.DocumentObjectModel.Document doc = new MigraDoc.DocumentObjectModel.Document();
MigraDoc.Rendering.DocumentRenderer renderer = new DocumentRenderer(doc);
MigraDoc.Rendering.PdfDocumentRenderer pdfRenderer = new MigraDoc.Rendering.PdfDocumentRenderer();
pdfRenderer.PdfDocument = pDoc;
pdfRenderer.DocumentRenderer = renderer;
using (MemoryStream ms = new MemoryStream())
{
  pdfRenderer.Save(ms, false);
  byte[] buffer = new byte[ms.Length];
  ms.Seek(0, SeekOrigin.Begin);
  ms.Flush();
  ms.Read(buffer, 0, (int)ms.Length);
}

Il y a ce truc MigraDoc qui vient avec PdfSharp, mais je n'ai pratiquement pas trouvé de doc/faq approprié. Après des heures de recherche sur Google, j'ai trouvé un extrait qui ressemblait à ceci. Maintenant ça marche.

25
misnyo

Si vous pensez qu'il y a un problème avec PdfDocument.Save, veuillez le signaler sur le forum PDFsharp (mais veuillez être plus précis avec votre description d'erreur). Votre "solution" ressemble à un hack pour moi. "pdfRenderer.Save" appelle "PdfDocument.Save" en interne. Quel que soit le problème, votre "solution" appelle toujours la même routine de sauvegarde.

Edit: Pour obtenir un octet [] contenant un PDF, il suffit d'appeler:

MemoryStream stream = new MemoryStream();
document.Save(stream, false);
byte[] bytes = stream.ToArray();

Les premières versions de PDFsharp ne réinitialisent pas la position du flux.

Vous devez donc appeler

ms.Seek(0, SeekOrigin.Begin); 

pour réinitialiser la position du flux avant de lire le flux; ce n'est plus nécessaire pour les versions actuelles.

L'utilisation de ToArray peut souvent être utilisée au lieu de lire à partir du flux.

Edit 2: au lieu de stream.ToArray() il peut être plus efficace d'utiliser stream.GetBuffer(), mais ce tampon est généralement plus grand que le fichier PDF PDF et vous n'avez que pour utiliser stream.Length octets de ce tampon. Très utile pour une méthode qui prend un byte[] avec un paramètre de longueur.

41
Vive la déraison

J'ai trouvé une solution plus simple:

byte[] fileContents = null; 
using(MemoryStream stream = new MemoryStream()) 
{ 
    pdfDoc.Save(stream, true); 
    fileContents = stream.ToArray(); 
}

Source: http://usefulaspandcsharp.wordpress.com/2010/03/09/save-a-pdf-to-a-byte-array-using-pdf-sharpmigradoc/

12
eCorke

Pour MigraDoc (ver 1.30), je pouvais l'enregistrer avec

PdfDocumentRenderer renderer = new PdfDocumentRenderer(true, PdfSharp.Pdf.PdfFontEmbedding.Always);
renderer.Document = report.m_Document;

renderer.RenderDocument();


using (MemoryStream stream = new MemoryStream())
{
    renderer.PdfDocument.Save(stream, false);
    ... your code in here

}
6
Alex G