0

I'm inserting pages pages into pdf doc. The pages don't get added at the end or begining they need to be inserted in the middle somewhere (I have a way to determine the insert location with bookmarks).

The key is not to loose bookmarks. So I'm using PdfStamper to insert the pages. The problem is pdfs that are being inserted have form fields and those fields are not coming through.

The code that does inserting

for (int pageNum = 1; pageNum <= readerPdfToAdd.NumberOfPages; pageNum++)
{
    PdfImportedPage page = pdfStamper.GetImportedPage(readerPdfToAdd, pageNum);
    pdfStamper.InsertPage(filesByCategory[i].PageOfInsert + pageNum, readerPdfToAdd.GetPageSizeWithRotation(pageNum));

    var rotation = readerPdfToAdd.GetPageRotation(pageNum);
    if (rotation == 90 || rotation == 270) 
    {
        pdfStamper.GetUnderContent(filesByCategory[i].PageOfInsert + pageNum)
                  .AddTemplate(page, 0, -1f, 1f, 0, 0, readerPdfToAdd.GetPageSizeWithRotation(pageNum).Height);                                          
    }
    else 
    {
        pdfStamper.GetUnderContent(filesByCategory[i].PageOfInsert + pageNum).AddTemplate(page, 1f, 0, 0, 1f, 0, 0);


    }
}

I tried something like this to copy the fields but this doesn't copy exactly.

foreach (KeyValuePair<string, AcroFields.Item> kvp in pdfFormFields.Fields)
{
    var s = pdfFormFields.GetFieldPositions("Date");

    PdfArray r = kvp.Value.GetWidget(0).GetAsArray(PdfName.RECT);
    var name = kvp.Value.GetWidget(0).GetAsArray(PdfName.NAME);
    Rectangle rr = new Rectangle(r.GetAsNumber(0).FloatValue, r.GetAsNumber(1).FloatValue, r.GetAsNumber(2).FloatValue, r.GetAsNumber(3).FloatValue);
    TextField field = new TextField(pdfStamper.Writer, rr, kvp.Value.GetWidget(0).Get(PdfName.T).ToString());

    if (kvp.Value.GetWidget(0).Get(PdfName.V) != null)
        field.Text = kvp.Value.GetWidget(0).Get(PdfName.V).ToString();
    // add the field here, the second param is the page you want it on
    pdfStamper.AddAnnotation(field.GetTextField(), filesByCategory[i].PageOfInsert + pageNum);

    fields.SetField(kvp.Key, kvp.Value.ToString());
}

Is there a better way to do this? I've tried PdfCopy that looses bookmarks on the source document.

Tigran
  • 872
  • 1
  • 9
  • 25
  • Oh man, you might be in a world of hurt. Check out the PDF specification section on interactive elements. Hopefully the library you're using has some nice low level support, so you can just manipulate the PDF objects and page trees directly. – jjm Oct 25 '14 at 00:41
  • Well iTextsharp is capable of copying the form data I think GetImportedPage doesn't bring in the fields. – Tigran Oct 25 '14 at 01:04
  • This is a case of wrong use of the library. You need to combine `PdfStamper` with `PdfCopy`. – Bruno Lowagie Oct 26 '14 at 08:30

1 Answers1

0

Please use PdfCopy or PdfSmartCopy to assemble documents. As documented in chapter 6 of my book a PdfImportedPage only copies what is in the content stream.

You probably need PdfStamper to stamp some extra content on the original document, and that is fine, but you need to combine this with PdfCopy or PdfSmartCopy to assemble the final document.

Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
  • Thanks for the helop Bruno. The problem with PdfCopy and PdfSmartCopy is bookmarks get lost and bookmarks are integral to my document. I've seen your answer here http://stackoverflow.com/questions/14729237/add-file-with-bookmark So instead of bring the bookmarks over. I decided to pass the reader through PdfStamper and flatten the file. This way I get the form data. For my application it's ok that the forms are not there. The content is what's important. – Tigran Oct 27 '14 at 02:44
  • OK, that's an other alternative. For the sake of completeness: it is possible to combine the bookmarks of the different documents that are being merged and to apply those bookmarks to your `PdfCopy` and `PdfSmartCopy` instance. – Bruno Lowagie Oct 27 '14 at 07:15