Finding signature fields in a split page

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Finding signature fields in a split page

msinatl
Hi,

I have a multiple page PDF with embedded signature fields.  I am using some code based on http://www.rgagnon.com/javadetails/java-0647.html to split the PDF into individual pages.  I am then using the following Groovy code to find the names of the signature fields on each page so I can sign them.

    static List getSignatureFields(String inFile) {
        try {
            List fields = []
            // It seems necessary to load the file into the PdfReader this way to
            // avoid a java.io.IOException in sun.nio.ch.FileChannelImpl on AIX.
            byte[] content = new File(inFile).readBytes()
            assert content.size() == new File(inFile).size(), "Filesystem error"
            PdfReader reader = new PdfReader(content)
            AcroFields form = reader.getAcroFields()
            Map allFields = form.getFields()
            allFields.each{k, v->
                if (form.getFieldType(k) == AcroFields.FIELD_TYPE_SIGNATURE) {
                    if (k == 1 || k == '') {
                      throw new Exception("PDF signature field name undefined: '${k}'")
                    }                                                                  
                    fields << k
                }
            }
            return fields
        } catch (Throwable t) {
            log.error(t)
        }
    }

It appears that when I split the pages, I am losing the catalog, so finding the names of the signature fields is failing.

I need a new approach - either a way to parse the new page to find the signature fields without consulting the catalog, or a way to read the catalog before splitting and copy the relevant entries into the new pages. Could someone give me a pointer in the right direction?

Thanks!
mkl
Reply | Threaded
Open this post in threaded view
|

Re: Finding signature fields in a split page

mkl
msinatl,
msinatl wrote
I am then using the following Groovy code to find the names of the signature fields on each page so I can sign them.

[...]
As you already access reader.getAcroFields(), is there a special reason you don't use the AcroFields methods getBlankSignatureNames() and getSignatureNames()?

And you should use a different tool to split the PDF as the signature fields should be accessible via the catalog.

Regards,   Michael.

Reply | Threaded
Open this post in threaded view
|

Re: Finding signature fields in a split page

msinatl
Hm, my code was based on a very old example. getSignatureNames() is certainly easier!

When you suggest a different tool, is there a class or method you have in mind? The only examples I can find via Google are based on PdfImportedPage.  Or do you mean something other than iText?
mkl
Reply | Threaded
Open this post in threaded view
|

Re: Finding signature fields in a split page

mkl
msinatl wrote
Hm, my code was based on a very old example. getSignatureNames() is certainly easier!
Don't forget getBlankSignatureNames(); as you want to sign, you most likely want to find blank fields which getSignatureNames() filters.
msinatl wrote
When you suggest a different tool, is there a class or method you have in mind?
I have nothing special in mind. But whichever tool you choose, it should properly handle fields. Maybe someone else knows which iText classes are best to use for this.

Regards,   Michael.
Reply | Threaded
Open this post in threaded view
|

Re: Finding signature fields in a split page

iText mailing list
In reply to this post by msinatl
msinatl wrote:
> The only examples I can find via Google are based on PdfImportedPage.

You could use PdfStamper.
--
This answer is provided by 1T3XT BVBA
http://www.1t3xt.com/ - http://www.1t3xt.info

------------------------------------------------------------------------------
ThinkGeek and WIRED's GeekDad team up for the Ultimate
GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the
lucky parental unit.  See the prize list and enter to win:
http://p.sf.net/sfu/thinkgeek-promo
_______________________________________________
iText-questions mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/itext-questions

Buy the iText book: http://www.itextpdf.com/book/
Check the site with examples before you ask questions: http://www.1t3xt.info/examples/
You can also search the keywords list: http://1t3xt.info/tutorials/keywords/
Reply | Threaded
Open this post in threaded view
|

Re: Finding signature fields in a split page

msinatl
Thank you - that seems to have been the solution!

This is the code I split the pages with:

  static List splitByPages(String inFile, String destinationDir, String prefix) {
      List outFiles = []
      try {
        PdfReader readPages = new PdfReader(inFile)
        int n = readPages.getNumberOfPages()
        int i = 0
        while ( i < n ) {
          String outFile = "${destinationDir}/${prefix}${String.format('%03d', ++i)}.pdf"
          PdfReader reader = new PdfReader(inFile)
          FileOutputStream fout = new FileOutputStream(outFile)
          PdfStamper stamp = new PdfStamper(reader, fout)
          reader.selectPages("${i}")
          stamp.close()
          outFiles << outFile
        }
        return outFiles
    } catch (Throwable t) {
        log.error(t)
    }
  }

This is the code I read the field names with:

    static List getSignatureFields(String inFile) {
        try {
            List fields = []
            // It seems necessary to load the file into the PdfReader this way to
            // avoid a java.io.IOException in sun.nio.ch.FileChannelImpl on AIX.
            byte[] content = new File(inFile).readBytes()
            assert content.size() == new File(inFile).size(), "Filesystem error"
            PdfReader reader = new PdfReader(content)
            AcroFields form = reader.getAcroFields()
            fields = form.getBlankSignatureNames()
            log.debug("Found signature field names: ${fields}")
            return fields
      } catch (Throwable t) {
            log.error(t)
      }
    }