Render PDF in Browser (instead of download default) - ruby-on-rails

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

Related

RAILS - Generate PDF from HTML with GROVER

I want to use GROVER to export same ERB/HTML pages from my application as PDF.
It works, but the generated PDF seems to be missing the styles and formatting, no CSS seems to be processed.
Here my code within the controller:
html_string = render_to_string(
{
template: 'users/show.html.erb',
locals: { id: params[:id] }
})
pdf = Grover.new(html_string, format: 'A4').to_pdf
respond_to do |format|
format.html
format.pdf do
send_data(pdf, disposition: 'inline', filename: "Show_ID_#{params[:id]}", type: 'application/pdf')
end
end
My question is, how I can persuade GROVER also to process the CSS files ?
I had the same problem where my layout was rendered without the CSS. I was able to resolve the issue by adding the display_url option in Grover.
In local development this would be for example:
pdf = Grover.new(html_string, format: 'A4', display_url: "http://localhost:3000").to_pdf
You need to change your display_url depending on your environment.
If this does not work, make sure the html_string that you are rendering actually includes the correct markup. You can render out the html_string as HTML to verify all markup is included.

How to display the variant of an image with Active Storage in a JS box?

In my view, I can display my file attached to the model with Active Storage in a popup like this:
<%= image_tag #image.variant('small') %>
It's working well.
The problem is when I want to use a variant in the link:
<%= image_tag #image.variant('small') %>
The variant code used is:
file.variant(resize:size).processed.service_url
The link seems to be good, but when I click the image, the image is not opened in my JS popup as before but opened in a new browser window. This is very strange.
I shortened the link.
https://bucket.s3.eu-west-3.amazonaws.com/variants/MmsLY3rf8yR9/38a77a69d170464c472f6d36fb3fbc28b284af0cadaa533?response-content-disposition=inline%3B%20filename%3D%22chateau.jpeg%22%3B%20filename%2A%3DUTF-8%27%27chateau-lynch.jpeg&response-content-type=image%2Fjpeg&Signature=29fe7d85fe369ea2335fa8b333d4868d8c2f2c22e1efe
Is-it a "content-disposition" issue ?
Well, this is what I did:
In my Image model, I added an action and used the rails_representation_url() method from url_helpers:
include Rails.application.routes.url_helpers # need this for
include Rails.application.routes.url_helpers
def get_variant(version="high", disposition="attachment")
variant = file_variant(version)
return rails_representation_url(variant, only_path: true, disposition: disposition)
end
In my html, I can call my method with attachment disposition:
<a href="<%= #image.get_variant('high', 'attachment') %>" rel="example_group">
I can also download the image variant directly from my controller:
def download
redirect_to #image.get_variant('high', 'attachment')
end
If you want to only display the variant in the browser window, you can use 'inline':
redirect_to #image.get_variant('high', 'inline')
Not sure it's the best option, but it works.

Opening pdf data as image in rails views

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

Rails - Force XML template to be downloaded instead of rendered

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,

Rails prawn gem - multiple dispositions?

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'

Resources