PDFBox how to import acrofield from another pdf
Asked Answered
H

2

1

I have a problem with import exist acrofield from a pdf into another pdf. The two pdf are similar. I tried to import and save the file (code below). if I open it from the file system I do not see the changes, but if I open it with pdfbox I see the acrofiles inserted earlier. I notice that the file size has increased, but when I open it I do not see the fields fillable.

Thank you in advance

        PDDocument documentSrc = PDDocument.load(new File(SRC));
        PDAcroForm acroFormSrc = documentSrc.getDocumentCatalog().getAcroForm();

        PDDocument documentDest = PDDocument.load(new File(DEST));
        PDAcroForm acroFormDest = new PDAcroForm(documentDest);

        System.out.println("\n\n\n----------> FIELDS OF DOC SOURCE");
        for(PDField field : acroFormSrc.getFields()) {
            System.out.println(field);
        }

        acroFormDest.setCacheFields(true);
        acroFormDest.setFields(acroFormSrc.getFields());
        documentDest.getDocumentCatalog().setAcroForm(acroFormDest);

        documentDest.save(DEST_MERGED);
        documentDest.close();
        documentSrc.close();

        PDDocument documentMERGED = PDDocument.load(new File(DEST_MERGED));
        PDAcroForm acroFormMERGED = documentMERGED.getDocumentCatalog().getAcroForm();

        System.out.println("\n\n\n----------> FIELDS OF DOC MERGED");
        for(PDField field : acroFormMERGED.getFields()) {
            System.out.println(field);
        }

        documentMERGED.close();
Howarth answered 25/1, 2018 at 11:46 Comment(7)
you need to copy the annotations too, and to fix the page references.Chord
You accidentally tagged your question with itext. I will remove the tag.Dykes
thanks for the intervention. when you talk about references, intent COSObject?Howarth
The widget annotations have getPage / setPage methods. I think the easiest would be to go through your pages, get the annotations, then update each one with the corresponding "new" page. There might be more that I am missing... e.g. the default resources of the acroform.Chord
It works, but when I insert the text it does not look like the original. Probably the resources you were saying. Could be? Do you have any other suggestions?Howarth
I would need the files to tell more.Chord
Don't worry. I have already solved thanks to your advice :)Howarth
H
2

i solved this way:

    try
    {

        PDDocument documentSrc = PDDocument.load(new File(SRC));
        PDAcroForm acroFormSrc = documentSrc.getDocumentCatalog().getAcroForm();

        PDDocument documentDest = PDDocument.load(new File(DEST));
        PDAcroForm acroFormDest = new PDAcroForm(documentDest);

        acroFormDest.setCacheFields(true);
        acroFormDest.setFields(acroFormSrc.getFields());
        documentDest.getDocumentCatalog().setAcroForm(acroFormDest);

        int pageIndex = 0;
        for(PDPage page: documentSrc.getPages()){
            documentDest.getPage(pageIndex).setAnnotations(page.getAnnotations());
            documentDest.getPage(pageIndex).setResources(page.getResources());
            pageIndex++;
        }

        documentDest.save(DEST_MERGED);
        documentDest.close();
        documentSrc.close();
    }
    catch (IOException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

Thanks for your support :)

Howarth answered 31/1, 2018 at 9:19 Comment(4)
documentDest.getPage(pageIndex).setResources(page.getResources()); might bring trouble because this means you're throwing away the page resources of the destination document. setAcroForm(acroFormDest); is OK but only if the destination file didn't have any Acroform stuff. Note that I mentioned "default resources of the acroform", not page resources. Your solution might still work if both files came from the same source, e.g. a mass mailing.Chord
I tried your code on this document source on output pdf acroform is moved a little bit to right outside to page. the difference is how I create destFile:PDDocument documentDest = new PDDocument(); for (PDPage page : documentSrc.getPages()) { documentDest.addPage(new PDPage(PDRectangle.A4)); } result result pdf @TilmanHausherr if you can too give your expertise here pleaseFalsity
finally I find I create destfile with setCropBox and setMediaBox from sourcefile pageFalsity
In addition to copying the wrong resources (page instead of form default), there is another issue with the code above: The annotations are copied as is, keeping all their properties. But one property of annotations is a reference back to their page. For most annotations this is optional, but if it's used , the original pages from which the annotations were copied are dragged along into the target file, making it larger than necessary.Arie
D
0

I have updated your code as :

    public static void copyAcroForm(
            String acroFormPathfile,
            String inPathfile,
            String outPathfile) 
        throws IOException {

        try (
            PDDocument acroFormDocument = PDDocument.load(new File(acroFormPathfile));
            PDDocument outDocument = PDDocument.load(new File(inPathfile));) 
        {
            PDAcroForm templateAcroForm = acroFormDocument.getDocumentCatalog().getAcroForm();
            PDAcroForm outAcroForm = new PDAcroForm(outDocument);
            
            outAcroForm.setCacheFields(true);
            outAcroForm.setFields(templateAcroForm.getFields());
            outDocument.getDocumentCatalog().setAcroForm(outAcroForm);
            
            int pageIndex = 0;
            for (PDPage page: acroFormDocument.getPages()) {
                outDocument.getPage(pageIndex).setAnnotations(page.getAnnotations());
                outDocument.getPage(pageIndex).setResources(page.getResources());
                pageIndex++;
            }

            outDocument.save(outPathfile);
        }
    }

and propose a simple Swing App using it here https://github.com/DavidRobertKeller/pdf-acroform-utils Screencap

Drily answered 7/1, 2021 at 15:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.