查找PDF表单字段位置

时间:2018-03-02 18:54:48

标签: ruby-on-rails pdf pdftk

我意识到这个问题已被问到很多,但我找不到任何关于如何在RoR中执行此操作的信息。我使用pdf-forms填写带有表单文本字段的PDF,但这不支持添加图像,我需要能够将客户签名的图像添加到PDF中。我使用prawn在现有PDF上渲染图像,但我需要知道在签名行上添加图像的确切位置。所以我的问题是如何查看任意PDF并找到“签名”表单字段的确切位置?

2 个答案:

答案 0 :(得分:0)

我最终使用pdf2json来查找表单字段的x,y位置。我使用以下命令生成原始pdf的JSON文件:

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

JSON文件与form_path在同一目录中生成。我使用这些命令找到了我想要的字段:

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

我可以使用prawn首先使用图片创建新的PDF。然后使用pdf-forms,我multistamp将图像pdf放到我想要添加图像的原始PDF上。但是多字段applies each page of the stamp PDF to the corresponding page of the input PDF因此请确保您的图片PDF具有正确的页数,否则您的图片将在每个页面上标记。我只希望将图像标记在第一页上,所以我执行以下操作:

  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

答案 1 :(得分:0)

这是一个纯红宝石实现,它将使用折纸https://github.com/gdelugre/origami

返回字段的名称,页面,x,y,高度和宽度
require "origami"

def pdf_field_metadata(file_path)
  pdf = Origami::PDF.read file_path

  field_to_page = {}
  pdf.pages.each_with_index do |page, page_index|
    (page.Annots || []).each do |annot|
      field_to_page[annot.refno] = page_index
    end
  end

  field_metas = []
  pdf.fields.each do |field|
    field_metas << {
      name: field.T,
      page_index: field_to_page[field.no],
      x: field.Rect[0].to_f,
      y: field.Rect[1].to_f,
      h: field.Rect[3].to_f - field.Rect[1],
      w: field.Rect[2].to_f - field.Rect[0]
    }
  end

  field_metas
end

pdf_field_metadata "<path to pdf>"

我还没有对它进行特别彻底的测试,但是该代码片段有望带给您大部分帮助。

此外-请记住,以上计算的坐标是从pdf页面左下角而不是右上角开始的点(并且不是以像素为单位)。我相信每英寸总有72点,您可以通过在上面的page.MediaBox循环中调用pdf.pages来获得总的页面点数。如果要查找像素坐标,则需要知道生成的渲染文档的DPI。