【问题标题】:How to render PDF without use respond_to format.pdf in Rails?如何在 Rails 中不使用 respond_to format.pdf 渲染 PDF?
【发布时间】:2011-07-24 20:25:28
【问题描述】:

如何在不渲染此文件的情况下渲染发送给客户的文件(PDF、CSV 等)?

例如,想象一个学生控制器(使用脚手架创建),我们有“新”表单和“创建”操作:

  def new
    @student = Student.new
    respond_to do |format|
      format.html # new.html.erb
    end
  end

  def create
    @student = Student.new(params[:student])
    respond_to do |format|
      if @student.save
        flash[:notice] = 'Student created'
        format.html { redirect_to(@student) }
      else
        format.html { render :action => "new" }
      end
    end
  end

成功创建学生后,它将重定向到“显示”模板。那没问题! 但我需要发送给客户 - 例如 - 一个 PDF 文件,然后呈现“显示”操作。

此 PDF 文件就像客户的创建收据。

额外信息:现在使用 Prawn 制作 PDF 并通过如下代码发送给客户:

    respond_to do |format|
      format.pdf { render :layout => false }
    end

简而言之,我需要填写表格、创建学生、将 PDF 发送到浏览器(作为创建收据)并呈现“显示”操作以显示创建的学生。

非常感谢。

【问题讨论】:

  • 让我看看我是否理解您要查找的内容,您想向用户显示“show.html.erb”文件,但您还希望用户下载静态 PDF 文件其他细节?
  • 是的。我如何使用 redirect_to format.pdf 将 PDF 发送给客户端,但我想 sned 这个并立即显示“show.html.erb”。
  • 您不能在控制器中同时进行两次渲染(一个 pdf 和一个页面)。要么发送 pdf,要么渲染另一个页面。
  • @apneadiving,非常感谢您的回答。我知道我只能调用一个渲染或重定向,但这是我的问题的目标:如何发送此 PDF 并显示此页面?
  • 发送 PDF == 渲染 1. 显示页面 == 渲染 2. 不能一次性完成。

标签: ruby-on-rails ruby-on-rails-3 pdf render prawn


【解决方案1】:

这是我使用 wicked_pdf 的解决方案。

这会创建 pdf,但不会下载它。将 PDF 保存到文件。将链接保存在数据库中,使用显示的链接重新渲染视图(视图正在显示@plan)。

    # create a unique PDF filename
    pdf_uuid = UUIDTools::UUID.timestamp_create().to_s
    pdf_uuid_filename = Rails.root.join('public/pdf', "#{pdf_uuid}.pdf").to_s

    # create a pdf but don't display it
    pdf_file = render_to_string :pdf => pdf_uuid_filename, 
                                :template  => 'plans/show.pdf.erb' ,
                                :layout    => 'pdf',
                                :save_only => true
    # save to a file
    File.open(pdf_uuid_filename, 'wb') do |file|
      file << pdf_file
    end
    # create full URL path to created file  
    @plan.url = request.url[0, request.url.index("plans")] +  'pdf/' + CGI::escape("#{pdf_uuid}.pdf")
    @plan.save!
    # render the page again with the link being displayed
    redirect_to :back

【讨论】:

  • 哦,我会测试它。非常感谢@marisa。
【解决方案2】:

到目前为止,最简单的方法是在显示页面上显示指向 PDF 的链接。 但如果你真的想一步完成,你可以使用 Javscript 和 prawnto 的 ':inline => false' 选项来完成。

确保您的 prawnto 选项具有 :inline => false 这将强制 PDF 请求呈现为下载附件而不是视图。

prawnto :prawn => {
          :left_margin => 48, 
          :right_margin => 48,
          :top_margin => 24,
          :bottom_margin => 24,
          :inline => false}

然后在 show.html.erb 视图的底部使用 JS 将窗口指向 pdf 版本。

<script language="JavaScript">

    window.location=<%=url_for :action=>"show", :format=>:pdf%>;

</script>

这将显示正常的 html 视图,然后会弹出一个下载对话框,要求用户保存 PDF,但不会将用户重定向到 show.html 页面。

希望对你有帮助

【讨论】:

    【解决方案3】:

    如果您想向用户显示一个 pdf,您可以在表单提交成功后在您的渲染视图中提供一个链接。然后用户可以点击链接下载并查看pdf。或者,如果您想在用户无需下载的情况下显示 pdf,您可以使用 pdf 网络阅读器:查看http://www.scribd.com/ 和 ttp://crocodoc.com/,两者都提供将 pdf 上传到他们的服务器并允许您的网络用户使用他们的查看器查看它。

    希望对您有所帮助。

    【讨论】:

    • 非常感谢,我会试试你的想法!
    • 如果您认为这是您的答案,您可以这样标记吗?谢谢
    • 谢谢@Matteo-Melani,但我正在寻找其他想法。
    猜你喜欢
    • 2015-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-04
    • 2021-05-23
    • 1970-01-01
    • 2013-03-22
    • 1970-01-01
    相关资源
    最近更新 更多