如何在不使用Rails中的respond_to format.pdf的情况下呈现PDF?

时间:2011-07-24 20:25:28

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

如何在不渲染此文件的情况下向客户端发送文件(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文件,然后呈现'show'动作。

此PDF文件类似于客户的创建收据。

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

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

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

非常感谢。

3 个答案:

答案 0 :(得分:5)

这是我使用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

答案 1 :(得分:1)

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

确保您的prawnto选项包含:inline =&gt; 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页面。

希望这有帮助

答案 2 :(得分:0)

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

希望得到这个帮助。