title: Can't generate proper PDF files with PDFtk
body: <p>I am developing a web app using Ruby on Rails 3. One of the features of the app is to use data from a MySQL database to fill PDF template forms that have been designed in Adobe LiveCycle Designer.</p>
  
  <p>I am using the technique of generating an XFDF file with the data and use it to fill in the actual PDF file. I am using PDFtk to do this and if I run it from my command prompt (Windows 7 64bit) it works fine.</p>
  
  <p>I used code by Greg Lappen at <a href="http://bleep.lapcominc.com/2012/02/07/filling-pdf-forms-with-ruby-and-pdftk/" rel="nofollow">http://bleep.lapcominc.com/2012/02/07/filling-pdf-forms-with-ruby-and-pdftk/</a> to implement this process in my Rails app, but it does not seem to work</p>
  
  <p>The output PDF cannot be opened in Acrobat as it states the file has been damaged. If I open it using a normal text editor all it contains is <code>#&lt;StringIO:0x5958f30&gt;</code> with the HEX value changing after each output.</p>
  
  <p>The code generating the XML data is correct. I was able to save it to a file and run it through the command prompt myself.</p>
  
  <pre><code>def self.generate_xfdf(fields, filename)
      xml = Builder::XmlMarkup.new
      xml.instruct!
      xml.xfdf("xmlns" =&gt; "http://ns.adobe.com/xfdf/", "xml:space" =&gt; "preserve") {
        xml.f :href =&gt; filename
        xml.fields {
          fields.each do |field, value|
            xml.field(:name =&gt; field) {
              if value.is_a? Array
                value.each {|item| xml.value(item.to_s) }
              else
                xml.value(value.to_s)
              end
            }
          end
        }
      }
      xml.target!
    end
  </code></pre>
  
  <p>I suspect the real problem is in either of the two code snippets below. I just started learning Ruby on Rails and I am unable to debug this. I have tried various different methods but no success so far. I would really appreciate any help.</p>
  
  <pre><code>  def self.stamp(input_pdf, fields)
      stdin, stdout, stderr = Open3.popen3("pdftk #{input_pdf} fill_form - output - flatten")
      stdin &lt;&lt; generate_xfdf(fields, File.basename(input_pdf))     
      stdin.close
      yield stdout
      stdout.close
      stderr.close
    end
  
  PdfStamper.stamp('C:/clean-it-template.pdf', { 'LastName' =&gt; "Test Last Name", 'FirstName' =&gt; "Test First Name" }) do |pdf_io|
      pdf_content = StringIO.new
      pdf_content &lt;&lt; pdf_io.read
      send_data pdf_content.string, :filename=&gt;'output.pdf', :disposition=&gt;'inline', :type=&gt;'application/pdf'
  end
  </code></pre>
  
  <p>This is the full code in my controller class</p>
  
  <pre><code>require 'pdf_stamper'
  
  class FormPagesController &lt; ApplicationController
      def pdftest
          PdfStamper.stamp('C:/clean-it-template.pdf', { 'LastName' =&gt; "Test Last Name", 'FirstName' =&gt; "Test First Name" }) do |pdf_io|
              pdf_content = StringIO.new
              pdf_content &lt;&lt; pdf_io.read
              send_data pdf_content.string, :filename=&gt;'output.pdf', :disposition=&gt;'inline', :type=&gt;'application/pdf'
          end
      end
  end
  </code></pre>
  
  <p>This is the full code for the pdf_stamper class I am using</p>
  
  <pre><code>require 'builder'
  require 'open3'
  
  class PdfStamper
    def self.stamp(input_pdf, fields)
      stdin, stdout, stderr = Open3.popen3("pdftk #{input_pdf} fill_form - output - flatten")
      stdin &lt;&lt; generate_xfdf(fields, File.basename(input_pdf))     
      stdin.close
      yield stdout
      stdout.close
      stderr.close
    end
  
    def self.generate_xfdf(fields, filename)
  
      xml = Builder::XmlMarkup.new
      xml.instruct!
      xml.xfdf("xmlns" =&gt; "http://ns.adobe.com/xfdf/", "xml:space" =&gt; "preserve") {
        xml.f :href =&gt; filename
        xml.fields {
          fields.each do |field, value|
            xml.field(:name =&gt; field) {
              if value.is_a? Array
                value.each {|item| xml.value(item.to_s) }
              else
                xml.value(value.to_s)
              end
            }
          end
        }
      }
      xml.target!
      #file = File.new("C:/debug.xml", "w+")
      #file.write(xml_data)
      #file.close
    end
  
  end
  </code></pre>
  
  <p><strong>UPDATE #1:</strong></p>
  
  <p>I ran the web app on Ubuntu and I still get the same errors. After digging around on the web I changed the code in my controller to this:</p>
  
  <pre><code>def pdftest
      PdfStamper.stamp('/home/nikolaos/clean-it-template.pdf', { 'LastName' =&gt; "Test Last Name", 'FirstName' =&gt; "Test First Name" }) do |pdf_io|
          pdf_content = StringIO.new("", 'wb')
          pdf_content &lt;&lt; pdf_io.read
          send_data pdf_content.string, :filename=&gt;'output.pdf', :disposition=&gt;'inline', :type=&gt;'application/pdf'
      end
  end
  </code></pre>
  
  <p>I changed StringIO to be in binary write mode and it works in Ubuntu! The PDF opens correctly with all the fields filled in. I opened the same file on Windows using Acrobat and no problems, BUT if I run the web app on Windows, it still produces damaged PDF files.</p>
  
  <p>Does anyone have any solutions on how to get this working in Windows? I am guessing it has something to do with the way Windows and Linux interpret newlines or something similar to that?</p>