开发者

How to render PDF without use respond_to format.pdf in Rails?

开发者 https://www.devze.com 2023-03-22 09:43 出处:网络
How can I render send to a c开发者_Python百科lient a file (PDF, CSV, etc) without render this file?

How can I render send to a c开发者_Python百科lient a file (PDF, CSV, etc) without render this file?

For example, imagine a Students controller (created using scaffold), we have 'new' form and 'create' action:

  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

When a student is successfully created it will redirect to 'show' template. That is OK! But I need to send to client -for example- a PDF file and then render 'show' action.

This PDF file is like a creation receipt for client.

Extra info: now use Prawn to make PDF and sending to client by code like this:

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

In brief, I need get filled form, create student, send PDF to browser (as a creation receipt) and render 'show' action to display student created.

Thank you very much.


Here is my solution using wicked_pdf.

This creates the pdf but doesn't download it. Saves PDF to a file. Saves the link in the database, rerenders the view with the link displayed (view is displaying the @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


The easiest way, by far is to just display a link to the PDF on the show page. But if you really want to do both in one step you could do it using Javscript and the ':inline => false' option for prawnto.

make sure your prawnto options has :inline => false this will force the PDF request to render as download attachemnt not a view.

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

then at the bottom of your show.html.erb view point the window to the pdf version using JS.

<script language="JavaScript">

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

</script>

This will show the normal html view and then a download dialog popup will show asking the user to save the PDF but will not redirect the user away from the show.html page.

Hope this helps


If you want to display a a pdf to the user you can make a link available in your rendered view upon successful form submission. Then the user can click on the link and download and view the pdf. Or if you want to display the pdf without the user having to download it you can use a pdf web reader: take a look at http://www.scribd.com/ and ttp://crocodoc.com/, both offer the ability to upload a pdf to their servers and to allow your web user to see it using their viewer.

Hope this help.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号