2
votes

I'm currently in the process of creating (what I thought would have been) a really simple method to append two PDF files.

Firstly, my method creates a page that has all of the clients details on it as a digital signature. I had this working fine and saving to a single page PDF file.

However, I now want to append the terms & conditions that they're signing to the bottom of the PDF. The solution I'm coding in uses VB.NET, but you can provide the answer in C# if you prefer because I'm familiar with both. I just seriously cannot get my head around iTextSharps process.

Here is my code currently:

Public Sub CreateDocument() Handles btnCreate.ServerClick

    Dim path As [String] = Server.MapPath("PDFs")
    Dim document As New Document()
    Dim writer As PdfWriter = PdfWriter.GetInstance(document, New FileStream(path + "/" + _AccountNo + "-RegAgreement.pdf", FileMode.Create))

    'Removed chunk of code here, just defining content chunks and paragraphs
     for the dynamically created page, left in the construction
     part which you can see below'


    'Construct digitally signed agreement page'
    document.Open()
    document.NewPage()
    document.Add(pHeader)

    table.SpacingBefore = 30.0F
    table.SpacingAfter = 60.0F
    document.Add(table)

    pAgreement.SpacingAfter = 20.0F
    document.Add(pAgreement)

    document.Add(pSignedBy)
    document.Add(imgSig)
    document.Add(pFooter1)
    document.Add(pFooter2)
    document.Add(pFooter3)

    writer.Close()
    document.Close()

Now this is the bit I've added to the end of the above sub to append the PDF. As far as I'm aware, you need to use the PdfCopy to transfer the information from the PDF to a new Document object (In this case, doc). But then, I can't find a way to add these to the dynamically created PDF.

Is there perhaps a way to open it within the copier and then start copying from page 2?

    Dim terms As New PdfReader(path + "/termsconditions.pdf")
    Dim doc As New Document()
    Dim copier As New PdfCopy(doc, New FileStream(path + "/" + _accountNo + "-RegAgreement2.pdf", FileMode.Create))

    'Append Ts & Cs'
    For i As Integer = 1 To terms.NumberOfPages
        Dim importedPage As PdfImportedPage = copier.GetImportedPage(terms, i)
        copier.AddPage(importedPage)
    Next

    terms.Close()
    terms.Close()

End Sub

Every solution I've seen so far has used different methods like page stamps or memory streams, but none of them have worked or given me the result I need.

Any help is greatly appreciated!

UPDATE

Okay so after @mkl's suggestion, I have now brought the dynamically generated document back with a reader, however it's returning a null value suggesting that the .PDF is blank, but it isn't. (I have the file in my directory with all the content filled)

        Dim copier As New PdfCopy(document, New FileStream(path + "/" + _distNo + "-RegAgreement2.pdf", FileMode.OpenOrCreate))
    Dim reader As New PdfReader(path + "/" + _distNo + "-RegAgreement.pdf")

    'retrieve dynamic document
    Dim dynamicPage As PdfImportedPage = copier.GetImportedPage(reader, 1)
    copier.AddPage(dynamicPage)

    'Append Ts & Cs
    For i As Integer = 1 To terms.NumberOfPages
        Dim importedPage As PdfImportedPage = copier.GetImportedPage(terms, i)
        copier.AddPage(importedPage)
    Next

Is this because it's being done within the same subroutine?

1
Create your dynamic PDF as you already do in your first code block. Then create a new PDF using PdfCopy to which you add your freshly created dynamic PDF and the PDF with all those terms. - mkl
@mkl I tried that but I can't do anything with the "document" object because it's locked into the PdfWriter, which if I close I then get another error because the document is still being used by something. - SamBC
@SamBC No, not the document object. A Document instance can only be used for one task. Thus, having created your initial dynamic PDF, you have a PDF file on disk. Now create a PdfReader instance from that file and in your second code block import all pages from that reader before importing the pages from the PdfReader terms. - mkl
I don't see any trace of a digital signature in your code. I hope you are talking about an electronic signature because once you've digitally signed a PDF, the digital signature shall break if you try appending extra pages. - Bruno Lowagie
however it's returning a null value - what is null? The reader? The dynamicPage? As far as I remember VB, neither should be possible unless you do something like On Error Resume Next which should not be used anyways. - mkl

1 Answers

0
votes

Solved, big thanks to @mkl on this one.

The issues I was facing were because I wasn't creating a Document object for the copier to write to.

    Dim doc As New Document()
    Dim copier As New PdfCopy(doc, New FileStream(path + "/" + _distNo + "-RegAgreement.pdf", FileMode.Create))
    'Open PDF created earlier in subroutine'
    Dim reader As New PdfReader(path + "/" + _distNo + "-Signed.pdf")

    doc.Open()
    'Copy first (And only) page of dynamic PDF'
    Dim dynamicPage As PdfImportedPage = copier.GetImportedPage(reader, 1)
    copier.AddPage(dynamicPage)

    'Append Ts & Cs'
    For i As Integer = 1 To terms.NumberOfPages
        Dim importedPage As PdfImportedPage = copier.GetImportedPage(terms, i)
        copier.AddPage(importedPage)
    Next

    doc.Close()
    terms.Close()
    reader.Close()
    copier.Close()

    'For temporary purposes, delete local file'
    'This will be done in output stream in end release'
    File.Delete(path + "/" + _distNo + "-Signed.pdf")

Thanks for the help guys. Think I've got the basic procedures of this iTextSharp thing down now!