How do I display a PDF in ROR (Ruby)?
Solution 1
In your controller:
def pdf
pdf_filename = File.join(Rails.root, "tmp/my_document.pdf")
send_file(pdf_filename, :filename => "your_document.pdf", :type => "application/pdf")
end
In config/environment/production.rb
:
config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
or
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
The config modification is required because it enables the web server to send the file directly from the disk, which gives a nice performance boost.
Update
If you want to display it instead of downloading it, use the :disposition
option of send_file
:
send_file(pdf_filename, :filename => "your_document.pdf", :disposition => 'inline', :type => "application/pdf")
If you want to display it inline, this question will be much more complete that I could ever be.
Solution 2
Basically you just need to write it in the html in your view. So this simple solution worked for me:
In the 'show.hmtl.erb'
<iframe src=<%= @certificate.certificate_pdf %> width="600" height="780" style="border: none;"> </iframe>
just putting the file location in embedded ruby as the source of the iframe tag worked for me after hours and hours of searching. 'certificate' is my model, and 'certificate_pdf' is my attachment file.
Solution 3
Depending where the PDF comes from, the following may help you. I have an application where I store a lot of things, and some of them have (additional) PDFs connected to the items. I store the items in the directory /public/res/<item_id>/
. res
means result, and item_id
is the numeric id of that item in Rails.
In the view, I provide a link to the PDFs by the following (pseudo-)code as a helper method, that may be used in the view:
def file_link(key, name = nil)
res= Ressource.find(:first, :conditions => ["key = ?", key])
list = Dir["public/res/#{res.id}/*"]
file= list.empty? ? "" : list[0]
return file if file.empty?
fn = name ? name : File.basename(file)
link_to fn, "/res/#{res.id}/#{File.basename(file)}", :popup => true
end
The relevant part here is the link_to name, "/res/#{res.id}/#{File.basename(file)}"
thing.
Solution 4
This may be too simple, but I had trouble finding a simple answer to my problem, so I'm posting it here. I really didn't want to add another action to my controller just to download a static file.
I just uploaded my file to S3 & used link_to referring to the path, which S3 provides after you upload the file and set the permissions (remember, everyone has to be able to upload and download it). I store lots of data for the app on S3 so it seemed like a fine choice.
<%= link_to "speaker registration form", "https://s3.amazonaws.com/gws_documents/speaker_registration.pdf" %>
Solution 5
def pdf
pdf_content = ...# create the pdf
send_data(pdf_content, :filename => "test.pdf", :type => "application/pdf")
end
Related videos on Youtube
IAmGroot
I graduated from The University of Sheffield, and am currently work as a software engineer.
Updated on January 14, 2020Comments
-
IAmGroot over 4 years
I have looked around on the internet, but do not seem able to find how to display a PDF in rails (I can only find info on how to create one).
Does anyone know what code/gem I need to display one?
-
lucapette over 12 yearsUse prawn is a sort of de-facto standard.
-
user1130176 over 5 yearsThe hall monitors strike again. As of today 29 of us think this is a good question and 1 know it all says it's not but somehow had the authority to close it. SO is broken.
-
-
IAmGroot over 12 yearshi, this looks promising but what if I just want to load and display from a file. I.e. I have no pdf_content variable.
-
Benoit Garret over 12 yearsTwo things to note about your solution: 1/ you can only display files that are in the
public
folder. 2/ You cannot change the name of the file in the browser save dialog. -
mliebelt over 12 yearsThat is true, but sometimes sufficient. Its a simple solution, I know :-)
-
Benoit Garret over 12 yearsYou're perfectly right, I just wanted to point out the restrictions which may (or not ;-) ) be deal-breakers.
-
Matt over 12 yearsIn that case take a look at Benoit's solution.
-
IAmGroot over 12 yearsHey this is great stuff. In terms of sending a pdf to the user. But what about displaying it on the website, before sending it ? :)
-
Benoit Garret over 12 yearsLooks like my answer doesn't satisfy you, could you tell me why?
-
IAmGroot over 12 yearssorry yes. Briefly adding the dispoition still wanted the user to download it. I havent added the iframe, but an example would be great on how to load a pdf inside such. :). I finished working yesterday not long after your reply, and was pre-engaged with a bug on other software since. Ive only very recently managed to successfully recieve the pdf over my webservice uncorrupted.
-
IAmGroot over 12 yearsThink ill stick to the easy, already implemented idea. for which you helped me with. thanks
-
JGutierrezC over 10 years@BenoitGarret sorry for bother you, but, looks like
File.join(Rails.root, "tmp/my_document.pdf")
returns a string with the absolute path, for example:/home/user/rubyprojects/proj/assets/file.pdf
, so, if it is an asset and i put 'assets/file.pdf' as the second parameter, It doesn't resolve it. How could i achieve that? Great answer by the way. -
Benoit Garret over 10 years@JGutierrezC The path is relative to the project root, does it work with
File.join(Rails.root, "app/assets/file.pdf")
? -
JGutierrezC over 10 years@BenoitGarret it works. But the path is
/home/user/...
, i think i didn't explain myself, my question is, shouldn't it be looking forhttp://127.0.0.1:3000/assets/file.pdf
instead of a local folder? Thanks in advance man -
Benoit Garret over 10 years@JGutierrezC The sendfile header tells your web server to look for the file locally and send it directly to the client. You don't send the url to the client. This allows you to serve files even though they're not available in a public folder.
-
Benjamin Crouzier over 7 yearsThis did it for me:
send_file(..., disposition: 'inline')
-
Junaid Atique almost 5 yearsthis worked for me. using
send_file(..., disposition: 'inline')
plus using the route which generates the pdf will show pdf in iframe.