2011-12-05 52 views
6

我有四個我想合併的數據的MemoryStreams,然後打開pdfDocument,而不創建單個文件。合併內存到一個iText文檔

將它們寫入文件然後合併它們是可能的,但那樣做可能是不好的做法,也會導致一些問題,所以我想避免這種情況。

但是,我找不到合併MemoryStreams和iText5 for .NET的方法。

現在,這是我要做的事與文件:

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

因爲我需要刪除文件的使用,我一直將MemoryStream的,因爲不同的部件由不同資源構建的。所以我引用了這些內存流。

這怎麼辦?

+0

你不能使用var readerFrontPage = new PdfReader(yourMemoryStream); – user629926

+1

就是這樣,我無法工作。我碰到的一個錯誤是「找不到PDF頭標籤」。大多數遇到這個問題的人會使用文件,但這不是一個選項。 – Johan

+0

雖然它接縫PdfReader不能採取流,流的數組作品。 var readerFrontPage = new PdfReader(streamFrontPage.ToArray());你不能回答我自己的問題... – Johan

回答

18

可以通過將流的Position設置回0來修復錯誤PDF header signature not found。由於您沒有收到錯誤Cannot access a closed Stream我假設您已將PdfWriterCloseStream正確設置爲false

下面是一個完整的C#2010 WinForm應用程序,針對iTextSharp 5.1.1.0,它在MemoryStreams中創建三個PDF並將它們組合在一起。由於我沒有方便的網絡服務器,我正在將它們寫入磁盤。

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

完美。在我的例子中,我正在做'stream.Position = 0',但是在錯誤的地方:在'using'語句中。將它移到外面後,效果很好。順便說一句Chris:祝賀iTextSharp幫助社區。上帝祝福你! :) –

+0

謝謝,當記得在使用流之前將CloseStream設置爲false時,爲我工作並調用關閉文檔。 – Toft

+0

您如何在您的示例中打開PDF而不是保存到桌面? – Standage

0

雖然它接縫PdfReader不能接受流,流的數組作用。

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