2011-12-05 8 views
6

Mam cztery strumienie danych, które chcę scalić, a następnie otwórz dokument pdfDocument, bez tworzenia pojedynczego pliku.Scalanie notatek do jednego dokumentu iText

Możliwe jest zapisanie ich w plikach, a następnie ich scalenie, ale to byłaby zła praktyka i może to również spowodować kilka problemów, więc chcę tego uniknąć.

Jednak nie mogę znaleźć sposobu na połączenie obiektów MemoryStream z iText5 dla .NET.

Teraz, to jak to zrobić z plikami:

private static void ConcatenateDocuments() 
    { 
     var stream = new MemoryStream(); 

     var readerFrontPage = new PdfReader(Folder + FrontPageName); 
     var readerDocA = new PdfReader(Folder + docA); 
     var readerDocB = new PdfReader(Folder + DocB); 
     var readerAppendix = new PdfReader(Folder + Appendix); 
     var pdfCopyFields = new PdfCopyFields(stream); 

     pdfCopyFields.AddDocument(readerFrontPage); 
     pdfCopyFields.AddDocument(readerDocA); 
     pdfCopyFields.AddDocument(readerDocB); 
     pdfCopyFields.AddDocument(readerAppendix); 
     pdfCopyFields.Close(); 

     SavePdf(stream, FilenameReport); 
    } 

Ponieważ muszę usunąć wykorzystanie plików, trzymam MemoryStream jako różne części są zbudowane z różnych zasobów. Mam więc odniesienia do tych memorystów.

Jak można tego dokonać?

+0

Nie możesz użyć var ​​readerFrontPage = new PdfReader (yourMemoryStream); – user629926

+1

To jest coś, nie mogę tego zrobić działa. Jednym z błędów, które napotkam, jest "nie znaleziono podpisu nagłówka PDF". Większość osób, które napotykają ten problem, używa jednak plików, a to nie jest opcja tutaj. – Johan

+0

Podczas gdy szwy PdfReader nie może wziąć strumienia, tablica strumienia działa. var readerFrontPage = new PdfReader (streamFrontPage.ToArray()); Nie mogę odpowiedzieć na moje własne pytanie ... – Johan

Odpowiedz

18

Błąd PDF header signature not found można w tym przypadku naprawić, ustawiając strumień Position z powrotem na 0. Ponieważ nie otrzymujesz błędu, zakładam, że już poprawnie ustawiłeś PdfWriter 's do false.

Poniżej znajduje się pełna działająca aplikacja WinForm WinForm C# 2010 iTextSharp 5.1.1.0, która tworzy trzy pliki PDF w MemoryStreams i łączy je. Ponieważ nie mam pod ręką serwera WWW, piszę je na dysk.

using System; 
using System.Text; 
using System.Windows.Forms; 
using System.IO; 
using iTextSharp.text; 
using iTextSharp.text.pdf; 

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      //Create three MemoryStreams 
      MemoryStream[] streams = { CreateDoc("Page 1"), CreateDoc("Page 2"), CreateDoc("Page 3") }; 

      //I don't have a web server handy so I'm going to write my final MemoryStream to a byte array and then to disk 
      byte[] bytes; 

      //Create our final combined MemoryStream 
      using (MemoryStream finalStream = new MemoryStream()) 
      { 
       //Create our copy object 
       PdfCopyFields copy = new PdfCopyFields(finalStream); 

       //Loop through each MemoryStream 
       foreach (MemoryStream ms in streams) 
       { 
        //Reset the position back to zero 
        ms.Position = 0; 
        //Add it to the copy object 
        copy.AddDocument(new PdfReader(ms)); 
        //Clean up 
        ms.Dispose(); 
       } 
       //Close the copy object 
       copy.Close(); 

       //Get the raw bytes to save to disk 
       bytes = finalStream.ToArray(); 
      } 

      //Write out the file to the desktop 
      string outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Combined.pdf"); 
      using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None)) 
      { 
       fs.Write(bytes, 0, bytes.Length); 
      } 

      this.Close(); 
     } 

     /// <summary> 
     /// Helper method to create temporary documents 
     /// </summary> 
     private MemoryStream CreateDoc(string name) 
     { 
      MemoryStream ms = new MemoryStream(); 
      using (Document doc = new Document(PageSize.LETTER)) 
      { 
       using (PdfWriter writer = PdfWriter.GetInstance(doc, ms)) 
       { 
        writer.CloseStream = false; 
        doc.Open(); 
        doc.Add(new Paragraph(name)); 
        doc.Close(); 
       } 
      } 
      return ms; 
     } 
    } 
} 
+1

Idealne. W moim przypadku robiłem 'stream.Position = 0', ale w niewłaściwym miejscu: wewnątrz instrukcji' using'. Po przeniesieniu go na zewnątrz działa świetnie. Przy okazji Chris: gratulacje za pomoc społeczności, jeśli chodzi o iTextSharp. Niech cię Bóg błogosławi! :) –

+0

Dziękuję, pracując dla mnie, pamiętając o ustawieniu CloseStream na wartość false na pisarzu i wywołanie bliskiego dokumentu przed użyciem strumienia. – Toft

+0

Jak otworzyć PDF zamiast zapisywać na pulpicie w swoim przykładzie? – Standage

0

Podczas gdy szwy PdfReader nie może wziąć strumień, tablica strumienia działa.

var readerFrontPage = new PdfReader (streamFrontPage.ToArray());