I am using the prawn gem in Rails to generate a PDF. Currently I am using disposition: "inline" to render the PDF in the browser (and in my view: <%= link_to "PDF", product_path(#product, format: "pdf") %>. Is there any way that I can have multiple dispositions so that in my view I could have one link that renders the PDF in the browser and a separate link that will automatically download the PDF?
You can insert link as you've specified to render the .pdf, and call to a specific action of a controller, in which you have to send the .pdf as a file, for example with #send_file method:
send_file '/path/to.pdf', type: 'document/pdf'
Related
I have a link that downloads a dynamically generated file. The way I have it functioning is the following:
I created a custom controller action on a resource (created a custom route in routes.rb)
Clicking the link (non-ajax at this point) directs to this custom Controller action
The file is generated, and the last line in the custom controller action is send_data which streams the document to the user.
Update: It was recommended to include code. Here is the code in that custom controller action:
class MyController < ApplicationController
def custom_action_sending_pdf
pdf = InitMyPdf.new(#user)
send_data pdf.render, filename: "complete_report.pdf", type: "application/pdf"
end
end
The issue is that request.referrer for the next request will now reference this custom controller action, and I do not want it to do that. This is also reflected in the url.
This specifically becomes an issue when later in my app I redirect back to request.referrer. When the request.referrer is this custom controller action: it does not redirect to an actual page but instead just re-downloads the document all over again.
Instead I try this:
I make the link to that custom action an ajax request via the remote: true option
On one hand: the request.referrer now properly seems to not be referencing that controller action. However, now the file is not downloading!
I have done some looking around:
This question does not have an answer that can be immediately applied.
This question applies to downloading a static file which does not work for me because my file is dynamically generated, so I use send_data to send the generated file to the user as opposed to send_file.
Question: Ultimately I am trying to let a user download a dynamically generated file, all while NOT changing the page (keeping the request.referrer the same). Is this possible?
Update
I am aware of this question but the issue with it is that it's accepted answer is using send_file, and since my file is dynamically generated: send_file will not work for me here.
This works. use button_to
Example:
<%= button_to(<custom_action_sending_pdf_path>, method: :get, class: 'btn btn-primary') do %>
<i class="fa fa-print" aria-hidden="true"></i></i> Print PDF
<% end %>
Let that button go to that custom action which downloads the pdf (same code as in original question):
class MyController < ApplicationController
def custom_action_sending_pdf
pdf = InitMyPdf.new(#user)
send_data pdf.render, filename: "complete_report.pdf", type: "application/pdf"
end
end
What happens now is when that button is clicked:
The pdf downloads and pops up adobe (at least it does this in safari)
The url of the page does not change to the custom action which prints the pdf. So for the next request: request.referrer will not be that custom action for the pdf, which is the desired behavior here.
I store PDF receipts in S3. I use WickedPDF for generating the PDF files. Via the admin area of our app, there is a "Download" link, that is simply a direct link to the S3 path:
link_to "Download", order.receipt.url unless order.receipt.blank?
Any idea on how I can have it default to opening in a browser window instead of direct download?
The trick is to change the headers, if you link to a static file your webserver (S3) will add a header Content-Disposition: attachment; filename="name.pdf" without this header the browser will try to render this inline (same window).
To solve this issue you could have an action on your controller that downlaods the file itself and steams it to the user
require "open-uri"
class OrderController
def receipt
#order=Order.find(....)
render text: open(#order.receipt.url).read, content_type=>'application/pdf'
end
end
Obviously add a route to it identifying the order and link to this new action, this will render the pdf downloaded by rails without the 'attachment' header.
Render pdf:
render pdf: "Invoice",
orientation: 'Portrait',
template: "Invoice/download",
page_size: 'Letter'
If the PDF should be shown in a part of the page, you could use the following code on your page
<object data="<%= upload.file.url %>" width="100%" height="100%" style="min-height: 100%; height:100%; width:100%" type="<%= upload.mime_type %>">
<p>No PDF render functionality on your device...</p>
</object>
If you just want to show the PDF as a full page file, use this in your controller (creating a pdf on the fly)
pdf = #sales_invoice.pdf
send_data pdf.render, filename: "sales_invoice.pdf",
type: "application/pdf",
disposition: "inline"
use send_file method. This is the link that may help you.
http://apidock.com/rails/ActionController/Streaming/send_file
I have used Rails 4,
views
<div>
<%=image_tag(some_method_path), class: 'image-view' %>
</div>
controller method
def some_method
#label_image = Base64_incoded image hex
send_data #label_image, :type => 'application/pdf', :disposition => 'inline'
end
The image is not opening in view but it is opening as pdf if we run the url in window.
How to display the pdf as image in the div ?
Any help appreciated
As far as I understood, what you are trying to do is to render a preview into an image tag of a PDF document. However, this is not an automatic task, and your browser won't magically perform the conversion for you.
You need a library to render the PDF and capture a preview. This is not a Rails problem, it's a generic PDF conversion problem.
Note. This question is very similar to How to have pdf viewer in ruby
My question is very similar to this question but that answer does not work for me. I have a custom xml file that I want downloaded instead of rendered by the browser. I've tried the send_file method like the answer to the question I linked above, but I also get an error can't convert Hash into String.
Controller:
respond_to do |format|
format.tmx
end
Template: show.tmx.erb
<?xml version="1.0"?>
<tmx xmlns="http://www.gala-global.org/oscarStandards/tmx/tmx14b.html" version="1.4b">
</tmx>
View (I want this link to download a document instead of render in the browser):
<%= link_to "Download", document_path(#document, format: "tmx") %>
You can use the send_file, however it would need to refer to another endpoint already setup supplying the content. Or if you don't use the xml in any other context you can use the following:
format.tmx { send_data render_to_string(:show), filename: 'file.tmx', type: 'application/xml', disposition: 'attachment' }
HTH,
In my rails app I have a STATIC pdf here "../public/camp.pdf" visitors can download it, but when they do the file size is extremely small and the pdf wont open. I think my rails app is sending a blank pdf. Any ideas?
def download_1
send_data '/camp.pdf', :type => 'application/pdf', :filename => "camp.pdf"
end
View:
<%= link_to 'PDF', home_download_1_path %>
EDIT: contents of the pdf is only this "/REGLAS_DE_CARBONO_MEXICO2.pdf"
Edit:
The answer is to use an HTML5 download attribute: