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();
Tilman Hausherr
  • 17,731
  • 7
  • 58
  • 97
mikch
  • 31
  • 5

2 Answers2

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 :)

mikch
  • 31
  • 5
  • 1
    `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. – Tilman Hausherr Jan 31 '18 at 11:16
  • I tried your code on this [document source](https://drive.google.com/uc?id=1Ln1tp5A4nQ84Z1vjTHYnbzZjycO9NDbg&export=download) 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](https://drive.google.com/uc?id=1WUGLgtwGml627Piph6t31lekbPvX0Qzt&export=download) @TilmanHausherr if you can too give your expertise here please – ebeg Mar 27 '19 at 13:14
  • finally I find I create destfile with setCropBox and setMediaBox from sourcefile page – ebeg Mar 27 '19 at 13:53
  • 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. – mkl Mar 29 '19 at 18:07
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

David KELLER
  • 464
  • 4
  • 8