【问题标题】:Find PDF Form Field position查找 PDF 表单域位置
【发布时间】:2018-03-02 18:54:47
【问题描述】:

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

【问题讨论】:

    标签: ruby-on-rails pdf pdftk


    【解决方案1】:

    我最终使用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 上。但是 multistamp 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
    

    【讨论】:

      【解决方案2】:

      你可以使用这个 gem 'wicked_pdf.你只要写html,这个gem会自动转换成pdf 阅读更多https://github.com/mileszs/wicked_pdf

      【讨论】:

      • 这不起作用,因为我没有从 HTML 生成 PDF。我正在获取现有的 PDF(已上传),我想将图像添加到正确的表单字段。
      【解决方案3】:

      这是一个纯 ruby​​ 实现,它将使用 Origami 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>"
      

      我还没有特别彻底地对其进行过测试,但 sn-p 希望可以帮助您完成大部分工作。

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

      【讨论】:

        猜你喜欢
        • 2018-05-09
        • 2013-04-08
        • 2011-06-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多