我正在使用 Ruby on Rails 3 开发一个 Web 应用程序。该应用程序的功能之一是使用 MySQL 数据库中的数据来填充在 Adobe LiveCycle Designer 中设计的 PDF 模板表单。
我正在使用使用数据生成 XFDF 文件的技术,并使用它来填写实际的 PDF 文件。我正在使用 PDFtk 来执行此操作,如果我从命令提示符(Windows 7 64 位)运行它,它工作正常。
我在http://bleep.lapcominc.com/2012/02/07/filling-pdf-forms-with-ruby-and-pdftk/使用 Greg Lappen 的代码在我的 Rails 应用程序中实现了这个过程,但它没有似乎工作
输出 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
我怀疑真正的问题出在下面的两个代码片段中。我刚开始学习 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 解释换行符或类似的方式有关?