Merge PDFs using ITextSharp

In response to my post on Generating a PDF from Reporting Services, someone asked how I would join two PDFs.  The problem is that I can't just take two PDF byte streams and run them together because there is PDF metadata that starts and ends each document.  The way that I have gotten around this is use the ITextSharp library.

Our PDFs were stored in the database, so we grabbed each PDF and appended it to the first PDF (I didn't put the code in for the data reader--an astute reader of this entry should be able to figure that out). Here is the code similar to what we used, but we put it in several different methods to make the code more readable (your mileage may vary)--don't forget to add a reference to the ITextSharp library and include the imports statements (iTextSharp.text, iTextSharp.text.pdf) as part of your class:

' First set up the response and let the browser know a PDF is coming
Response.Buffer = True
Response.ContentType = "application/pdf"
Response.AddHeader("Content-Disposition", "inline")

' Second, some setup stuff
Dim MemStream As New System.IO.MemoryStream
Dim doc As New iTextSharp.text.Document
Dim reader As iTextSharp.text.pdf.PdfReader
Dim numberOfPages As Integer
Dim currentPageNumber As Integer
Dim writer As iTextSharp.text.pdf.PdfWriter = iTextSharp.text.pdf.PdfWriter.GetInstance(doc, MemStream)
doc.Open()
Dim cb As iTextSharp.text.pdf.PdfContentByte = writer.DirectContent
Dim page As iTextSharp.text.pdf.PdfImportedPage
Dim rotation As Integer

' Third, append all the PDFs--THIS IS THE MAGIC PART
Do While dr.Read 
    If Not IsDBNull(dr("Report_pdf")) Then
        Dim sqlbytes() As Byte
        sqlbytes = dr("Report_pdf")
        reader = New iTextSharp.text.pdf.PdfReader(sqlbytes)
        numberOfPages = reader.NumberOfPages
        currentPageNumber = 0

        Do While (currentPageNumber < numberOfPages)
            currentPageNumber += 1
            doc.SetPageSize(PageSize.LETTER)
            doc.NewPage()
            page = writer.GetImportedPage(reader, currentPageNumber)
            rotation = reader.GetPageRotation(currentPageNumber)
            If (rotation = 90) Or (rotation = 270) Then
                cb.AddTemplate(page, 0, -1.0F, 1.0F, 0, 0, reader.GetPageSizeWithRotation(currentPageNumber).Height)
            Else
                cb.AddTemplate(page, 1.0F, 0, 0, 1.0F, 0, 0)
            End If
        Loop
    End If
Loop

' Finally Spit the stream out
If MemStream Is Nothing Then
    Response.Write("No Data is available for output")
Else
    Response.OutputStream.Write(MemStream.GetBuffer(), 0, MemStream.GetBuffer().Length)
    Response.OutputStream.Flush()
    Response.OutputStream.Close()
    MemStream.Close()
End If

NOTE: One thing that I have not checked is whether the ITextSharp team has removed the dependency on the gziplib, but if you are already using the gziplib in your project, you are going to have to do a little work so that you don't have two referenced versions in your app.

Print | posted on Friday, June 29, 2007 9:31 AM

Feedback

# re: Merge PDFs using ITextSharp

left by Tom Harney at 10/8/2007 9:34 AM Gravatar
I had some trouble getting this code to work. So I modified it closing the document and outputing the data using Response.BinaryWrite().

doc.Close();
Response.BinaryWrite(MemStream.GetBuffer());
Response.End();
MemStream.Close();

I'm sure there are other solutions but this one worked for me.

# re: Merge PDFs using ITextSharp

left by Sa at 5/17/2008 3:01 AM Gravatar
ting ting

# re: Merge PDFs using ITextSharp

left by Matt Kannard at 5/30/2008 12:20 PM Gravatar
When I used this code I found that the first page was not sized correctly. I fixed the problem by calling doc.SetPageSize(PageSize.LETTER) before I called doc.Open().

# re: Merge PDFs using ITextSharp

left by joaopsr at 7/7/2008 7:06 AM Gravatar
i'm a begginer... so, what's that:
Do While dr.Read? dr is not declared and got me kinda confused... sorry

# re: Merge PDFs using ITextSharp

left by Brian Sherwin at 7/8/2008 9:44 PM Gravatar
joaopsr:

Good question. After all this time, you are the first to ask that question. Basically, the dr was a SQLDataReader that was reading the PDFs from a SQL database as a BLOB. Maybe I ought to revisit this post and put up an example.

# re: Merge PDFs using ITextSharp

left by joaopsr at 7/9/2008 4:19 AM Gravatar
Thanks... i got there before the answer, but thanks anyway... i had to find another way because i'm building a web page (ASP.net) and no dataReaders... but i got it thanks to your guidelines

# re: Merge PDFs using ITextSharp

left by Suba at 7/18/2008 6:04 AM Gravatar
This code works fine. I have used the code in a method namly GeneratePDF(). I have called the method from Button_Click(). The rest of the code in Button_Click is not executed after calling the GeneratePDF() method. Could you please let me know how to resovle the problem?

# re: Merge PDFs using ITextSharp

left by Brian Sherwin at 7/22/2008 12:48 PM Gravatar
Suba:

This is probably because the code in the example above is closing the Response.Outputstream because the assumption was that this was sending just the PDF to the users browser.

# re: Merge PDFs using ITextSharp

left by Suba at 7/23/2008 1:01 AM Gravatar
Thanks for the update. I have resolved the problem using HttpContext.
Title  
Name
Email (never displayed)
Url
Comments   
Please add 6 and 3 and type the answer here: