Ruby on Rails 3 を使用して Web アプリを開発しています。このアプリの機能の 1 つは、MySQL データベースのデータを使用して、Adobe LiveCycle Designer で設計された PDF テンプレート フォームに入力することです。
データを含む XFDF ファイルを生成し、それを使用して実際の PDF ファイルに入力する手法を使用しています。これを行うために PDFtk を使用していますが、コマンド プロンプト (Windows 7 64 ビット) から実行すると正常に動作します。
このプロセスを Rails アプリに実装するために、 http: //bleep.lapcominc.com/2012/02/07/filling-pdf-forms-with-ruby-and-pdftk/ の Greg Lappen によるコードを使用しましたが、そうではありません。動作するようです
ファイルが破損していると表示されるため、出力 PDF を Acrobat で開くことができません。通常のテキスト エディターを使用して開くと#<StringIO:0x5958f30>
、出力ごとに HEX 値が変化するだけです。
XML データを生成するコードは正しいです。ファイルに保存して、コマンドプロンプトから自分で実行できました。
def self.generate_xfdf(fields, filename)
xml = Builder::XmlMarkup.new
xml.instruct!
xml.xfdf("xmlns" => "http://ns.adobe.com/xfdf/", "xml:space" => "preserve") {
xml.f :href => filename
xml.fields {
fields.each do |field, value|
xml.field(:name => 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
本当の問題は、以下の 2 つのコード スニペットのいずれかにあると思われます。Ruby on Rails の学習を始めたばかりで、これをデバッグできません。さまざまな方法を試しましたが、これまでのところ成功していません。助けていただければ幸いです。
def self.stamp(input_pdf, fields)
stdin, stdout, stderr = Open3.popen3("pdftk #{input_pdf} fill_form - output - flatten")
stdin << generate_xfdf(fields, File.basename(input_pdf))
stdin.close
yield stdout
stdout.close
stderr.close
end
PdfStamper.stamp('C:/clean-it-template.pdf', { 'LastName' => "Test Last Name", 'FirstName' => "Test First Name" }) do |pdf_io|
pdf_content = StringIO.new
pdf_content << pdf_io.read
send_data pdf_content.string, :filename=>'output.pdf', :disposition=>'inline', :type=>'application/pdf'
end
これは私のコントローラークラスの完全なコードです
require 'pdf_stamper'
class FormPagesController < ApplicationController
def pdftest
PdfStamper.stamp('C:/clean-it-template.pdf', { 'LastName' => "Test Last Name", 'FirstName' => "Test First Name" }) do |pdf_io|
pdf_content = StringIO.new
pdf_content << pdf_io.read
send_data pdf_content.string, :filename=>'output.pdf', :disposition=>'inline', :type=>'application/pdf'
end
end
end
これは、私が使用している pdf_stamper クラスの完全なコードです
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 << 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" => "http://ns.adobe.com/xfdf/", "xml:space" => "preserve") {
xml.f :href => filename
xml.fields {
fields.each do |field, value|
xml.field(:name => 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
更新#1:
Ubuntu で Web アプリを実行しましたが、それでも同じエラーが発生します。ウェブを掘り下げた後、コントローラーのコードを次のように変更しました。
def pdftest
PdfStamper.stamp('/home/nikolaos/clean-it-template.pdf', { 'LastName' => "Test Last Name", 'FirstName' => "Test First Name" }) do |pdf_io|
pdf_content = StringIO.new("", 'wb')
pdf_content << pdf_io.read
send_data pdf_content.string, :filename=>'output.pdf', :disposition=>'inline', :type=>'application/pdf'
end
end
StringIO をバイナリ書き込みモードに変更したところ、Ubuntu で動作しました。すべてのフィールドが入力された状態で PDF が正しく開きます。Acrobat を使用して Windows で同じファイルを開きましたが、問題はありませんでしたが、Windows で Web アプリを実行すると、依然として破損した PDF ファイルが生成されます。
Windowsでこれを機能させる方法について、誰かが解決策を持っていますか? WindowsとLinuxが改行を解釈する方法またはそれに類似したものと関係があると思いますか?