如何将Rails的模板呈现为PDF,并使用FileMagic确保它为PDF?

时间:2018-08-09 16:42:01

标签: ruby-on-rails pdf libmagic

问题: 应用程序具有各种打印机的网络。其中一些通过PrintNode工作。他们应该接收编码为base64的字符串。接收我的文档的代码看起来像

PrintNode::PrintJob.new printer_id, 'PrinterClass', method, Base64.encode64(document), 'AppName'

method应该包含方法-在我的情况下为raw_base64或pdf_base64。所以我有下一个代码

case FileMagic.mime.buffer(document, true)
when 'text/plain'
  then method = 'raw_base64'
# when 'text/html' # this commented because I have to avoid it
#   then method = 'pdf_base64'
when 'application/pdf'
  then method = 'pdf_base64'
else
  raise InvalidDocumentError
end

我使用Controller.render方法渲染文档

document = InstanceController.render :label, { id: instance.id, formats: :pdf, locals: { instance: instance_note } }

我看到文档是一个字符串(包括html),因此FileMagic.mime返回text / html(我认为是)。这是个问题。我不在打印机附近,不能仅使用真正的打印机进行测试。另外,我们有5种打印机类型(条形码,a4等)。因此,我不确定是否可以使用注释方法(text/html)。

主要问题-我可以使用Controller.render方法渲染真实的PDF吗? (如果是,那么如何?)

注意:我们优先使用PrinceXML和gem。因此,当使用相同的控制器通过浏览器返回PDF时,我将获得有效的PDF。

1 个答案:

答案 0 :(得分:0)

好的。王子有问题。它重写了 instance 方法render,而不是类方法。因此,要以王子身份生成PDF,我必须调用InstanceController.new.render。但是它的签名不一样,因此不是很有用。

  1. InstanceController.new.render仅在第一个参数是哈希值时会优先调用,但在这种情况下,我们无法发送动作名称。
  2. 由于第一项优先尝试获得控制器名称action_name的动作名称,在本例中为nil并崩溃。

但是与此同时,我发现了从html显式地王子自动生成pdf的方法

princely = Princely::Pdf.new
document = princely.pdf_from_string(InstanceController.render action_name, options) # it generates valid PDF from html