【问题标题】:Downloading PDF's using PDFkit error on Rails在 Rails 上使用 PDFkit 错误下载 PDF
【发布时间】:2017-05-03 05:50:20
【问题描述】:

我正在尝试将 Rails5 中的 HTML 视图下载为 PDF,但是,每当我下载 PDF 时,我都会收到错误消息:无法加载 PDF 文档。我正在使用以下宝石:

gem 'pdf 套件' gem 'wkhtmltopdf-binary'

这是我的控制器:

class InputController < ApplicationController

def index
    @inputs = Input.all
end


def show
    @input = Input.find_by(id: params[:id])

            send_data @pdf, :filename => @input.company + ".pdf",
                                    :type => "application/pdf",
                                    :disposition => "attachment"
end


end

当我输入下载 URL 即:localhost:3000/input/1.pdf 时,我得到一个下载的 pdf 文件,但出现错误:

我的show view很简单:

<ul>
<li><%= @input.company %></li>
<li><%= @input.position %></li>
<li><%= @input.date %></li>
</ul>

任何帮助将不胜感激。

最好, 阿亚兹

更新

我也刚刚尝试取出@pdf 并放入@input:

    def show
    @input = Input.find_by(id: params[:id])
            send_data @input, :filename => @input.company + ".pdf",
                                    :type => "application/pdf",
                                    :disposition => "attachment"
    end

结果没有变化

【问题讨论】:

  • @input = 行之后,写p "---&gt;#{@input}&lt;---",然后检查服务器窗口中两个箭头之间的内容。
  • 我得到了对象:“--->#<0x007fcbb8cce0d0>

标签: ruby-on-rails ruby pdf-generation wkhtmltopdf pdfkit


【解决方案1】:

你的代码没有给实例变量@pdf赋值:

def show
  @input = Input.find_by(id: params[:id])

  send_data @pdf, :filename => @input.company + ".pdf",
                  :type => "application/pdf",
                  :disposition => "attachment"
end

实例变量的默认值为nil。您需要执行以下操作:

input = Input.find_by(id: params[:id])

html = %Q{
<ul>
<li>#{input.company}</li>
<li>#{input.position}</li>
<li>#{input.date}</li>
</ul>
}

kit = PDFKit.new(html, :page_size => 'Letter')
pdf = kit.to_pdf


send_data pdf, :filename => input.company + ".pdf",
               :type => "application/pdf",
               :disposition => "attachment"

或者,如果您想读取视图文件,然后通过 ERB 引擎运行它,如下所示:

file_path = File.expand_path("../views/input/show.html.erb", __FILE__)
erb_template = File.read(file_path)

@input = Input.find_by(id: params[:id])
renderer = ERB.new(erb_template)
html = renderer.result()

#As above...

来自Rails Guide

默认情况下,Rails 中的控制器会自动渲染带有名称的视图 对应于有效路线。
...
...
规则是,如果你没有在最后显式渲染一些东西 控制器动作,Rails 会自动寻找 action_name.html.erb 模板在控制器的视图路径和渲染 它。

来自send_data() 的文档:

此方法类似于render plain: data,但也允许您 指定浏览器是否应将响应显示为文件 附件(即在下载对话框中)或作为内联数据

因此,当您在控制器中调用 send_data() 时,您正在显式渲染某些内容,因此不会发生 action_name.html.erb 文件的默认渲染。

【讨论】:

  • @AyazUddin,看看我的补充。
  • @AyazUddin 据我所知,send_data() 会中断正常的事件序列,即通常执行操作,然后渲染相应的视图并将其发送到浏览器。 send_data() 告诉 rails 不要渲染相应的视图。
  • @AyazUddin,我从 rails 文档中添加了一些引号,解释了发送回浏览器的内容。
  • 非常感谢您的帮助!现在一切正常。你发过来的信息很有帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多