Search code examples
ruby-on-railspdfpdftk

Find PDF Form Field position


I realize this question has been asked a lot, but I could not find any information about how to do this in RoR. I am filling a PDF with form text fields using pdf-forms but this does not support adding images, and I need to be able to add an image of a customer's signature into the PDF. I have used prawn to render the image on the existing PDF, but I need to know the exact location to add the image on the signature line. So my question is how can I look at an arbitrary PDF and find the exact position of the "Signature" form field?


Solution

  • I ended up using pdf2json to find the x,y position of the form field. I generate a JSON file of the original pdf using this command:

    %x{ pdf2json -f "#{form_path}" }
    

    The JSON file is generated in the same directory as form_path. I find the field I want using these commands:

    jsonObj = JSON.parse(File.read(json_path))
    signature_fields = jsonObj["formImage"]["Pages"].first["Fields"].find_all do |f|
        f["id"]["Id"] == 'signature'
    end
    

    I can use prawn to first create a new PDF with the image. Then using pdf-forms, I multistamp the image pdf onto the original PDF that I want to add the image to. But multistamp applies each page of the stamp PDF to the corresponding page of the input PDF so make sure your image PDF has the correct number of pages or else your image will get stamped on every page. I only want the image stamped onto the first page, so I do the following:

      num_pages = %x{ #{Rails.configuration.pdftk_path} #{form_path} dump_data | grep "NumberOfPages" | cut -d":" -f2 }.to_i
      signaturePDF = "/tmp/signature.pdf"
      Prawn::Document.generate(signaturePDF) do
        signature_fields.each do |field|
          image Rails.root.join("signature.png"), at: [field["x"], field["y"]], 
                                                      width: 50
        end
        [0...num_pages - 1].each{|p| start_new_page }
      end
    
      outputPDF = "/tmp/output.pdf"
      pdftk.multistamp originalPDF, signaturePDF, outputPDF