Rails wicked_pdf file name in PDF reader - ruby-on-rails

In ma Rails app I have a route (download.pdf) that returns a PDF
format.pdf do
render pdf: "#{#sale.firstname}#{#sale.lastname}", dpi: 400
end
The PDF is opened in Chrome as download.pdf but when saving the file it gets saved with the correct file name.
But when opening directly with the PDF reader (instead of Chrome) the file gets downloaded as download.pdf
Any ideas how to solve this without changing the route?
Image: when opening with Chrome it works but when opening with the PDF reader the file name is wrong.

Browser uses Content-Disposition header to looking for the correct filename for the file. As you say the browser saving the file with the correct file name, it setting up correctly. But PDF reader doesn't check headers because it's not a browser.
You may try to check response.headers['Content-Disposition'] but looks like you need to change url.

Related

How to return a pdf file from a rest api?

I have setup a rest API inside a ruby on rails application, I now have a requirement to generate a PDF and return this PDF from a get request. I am looking for some advice on how to implement this feature.
Some of the requirements that I have are as follows: I can't save the file and give the end user a link to the file because the data in the file can be updated at any time. I am using the application as microservice so there isn't a front end that I can use to display the file.
So here is my thinking I would love some advice on how to implement this feature.
I would like to make a get request to a specific endpoint in the application. I expect a PDF file to be returned which I can then display to the end user.
I am currently using WickedPdf gem to generate a temporary PDF file, but I am really struggling with how the response should look.
Any advice would be much appreciated.
One way is to create a PDF file in memory and stream it to the client. I prefer this way, maybe later you will have to send PDF files via email, or just save them to some backup disk etc...
def get_pdf
pdf = WickedPdf.new.pdf_from_string('<h1>Hello There!</h1>')
send_data pdf, filename: 'file_name.pdf'
end
You can put the PDF generation to a different service and just call it in the controller. This provides isolation and you can test it separately.
Also you can debug the endpoint response with HTTPie http get http://localhost:3000/invoices/1/get_pdf
Rails will set all the necessary HTTP response headers:
Content-Disposition: attachment; filename="file_name.pdf"
Content-Length: 5995
Content-Transfer-Encoding: binary
Content-Type: application/pdf
So when the user clicks on a link that points to the endpoint, most probably the download dialog will pop up because of the Content-Disposition: attachment; header
Other solution is to render the get_pdf.html as PDF and send back to the client:
def get_pdf
render pdf: "file_name"
end
But in this case the Content-Disposition header will be inline, which means the browser will open the pdf (if it can read PDF format) instead of offering to download it.
Upload pdf to Amazon s3 and generate link then get pdf link in apis.
I don't know if you still need this, but for anyone in the future I found a nice solution:
pdf = WickedPdf.new.pdf_from_string(render_to_string "entradas/entradaspdf.pdf.erb")
send_data pdf, filename: "bergha.pdf", disposition: "inline"
I'm loading my pdf-html-view based template through "render_to_string" ruby method which returns the view contents in string. Then WickedPdf converts it to a pdf binary, and finally save that to "pdf" var.
Finally instead of "render" I use the "send_data" method, where first parameter is the output data (my pdf var), second is the filename of the output data, and third (optional) is to change Content-Disposition header to tell browser whether to load the file (inline) or just download it (attachment).
Hope it works, it does just fine for me

How do I use pdf.js close PDF?

I'm using pdf.js as an embedded PDF viewer in a web application I'm building. I have an iframe that I use as the 'viewer' by setting (via javascript) the SRC attribute to the following:
$('#fileViewer-1').find('iframe').attr('src', 'js/pdfjs-1.4.20/web/viewer.html?file%2FMYFOLDER%2FIMAGES%2FPDFdocs%2F' + filename + '#zoom=page-width');
so I'm basically just calling this URL as the SRC of my iframe:
js/pdfjs-1.4.20/web/viewer.html?file=MYFILENAMEHERE.pdf
and now I see memory increasing with each subsequent PDF load (where I change the SRC url attribute to a new PDF document).
QUESTION: how can I call the pdfViewClose() function / method I see on line #6432 of viewer.js?
As I understand it, without calling this, memory in the browser may not be de-allocated.
Currently I'm seeing memory increase steadily and eventually the browser (Firefox) crashes after a number of PDF changes.
EDIT
Here is a related answer: https://stackoverflow.com/a/16017576/6828657
Is this the pdf viewer you're using?
https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions#user-content-can-i-specify-a-different-pdf-in-the-default-viewer
As it says there, can you try to use PDFViewerApplication.open(file) to open a new pdf?

Rails Paperclip uploads numbers after url

Whenever I upload a file through paperclip the end of the URL gets kind of messed up, for instance, in stead of the expected URL
http://localhost:3000/assets/1/file.pdf
I get
http://localhost:3000/assets/1/file.pdf?1415287826
The url and path in my model are:
has_attached_file :file, url: "/assets/:id/:basename.pdf",
path: ":rails_root/public/assets/:id/:basename.pdf"
The actual file is not stored like this, this is only how the url looks using
<%= link_to "Open PDF", upload.file.url %>
It seems like an easy to fix problem but I just can't find the solution....
It's timestamp for your file. It holds the time when your file was uploaded to the server: in this case Time.at(1415287826) => 2014-11-06 15:30:26 +0000
When you will download that file, it will be cached by the browser (images are cached by default, pdfs can be cached now if browser supports pdf rendering). With that timestamp if you upload a file with exactly the same name (so the same url will be generated), browser will not highlight that link as visited. As a result, if it's an image with the same name, its cached version will not be rendered, because browser will considers such link as not visited therefore not cached.

Setting the name of a file downloaded from the browser

Disclaimer I am aware of the Content-Disposition header to send back to the client to set the downloaded file name - however my problem is a little more complicated than just that
I have an application (RubyOnRails using rails 3.1.3) that is essentially a document search/view application (search for documents and then render them in the browser). This is accomplished using an iframe.
<iframe src="<%= #frameURL %>" width="100%" height="100%">
#frameURL is a call to the plugin function of our Documents controller. The plugin function makes a RESTful call to our back end API to retrieve the referenced document, and then send the document contents back to the browser for rendering inside the iframe.
This works perfectly for documents like JPEG, PDF, TXT, etc. However, when the browser does not know how to handle the content-type (like a word document - we run Mac OS-X) - then the browser downloads the returned file as plugin.doc <- NOTE this is without setting the Content-Disposition header.
Since we want to name the file appropriately when it needs to be downloaded, we set the Content-Disposition header:
response.headers['Content-Disposition'] = "attachment; filename.extension"
Now the file gets downloaded as filename.doc - however, with this header set, even files like JPEG which the browser can render internally, get downloaded.
Questions:
Does anyone know where rails or the browser is getting the name of plugin.extension when we don't set the Content-Disposition header?
Is there a way to set Content-Disposition but have it only applied IF the browser can't render the document - so the default should be browser handles everything it can, and as a fallback, the browser uses the Content-Disposition content to name the downloaded file.
Thanks!
If you are calling some Rails function like "send_file", then search the source code of your version of Rails to find the source code of that function and see what headers it sets. You have to follow the call stack down a couple of levels but you should be able to find out how it sets the headers; I have done this before. As for the browser, I think if it doesn't find a file name in the Content-Disposition header it will more or less use the last portion of the URL for a filename.
Try using "inline" instead of "attachment" in the header.

Rails send_data() send_file() problem

I have a paperclip attachment in one model, but I`m not saving the file in /public, but /assets. And when the user what to open the file I use the send_data() function, which makes the user to download the file.
My question is how can I show the file in other way (not nessecery to download)? So if the file is a image, I will see it directly in the browser without download.
Thanks!
Try:
send_data foo, :disposition => 'inline'
This would tell the browser to just render the content, instead of prompting the user to save it.
… from http://apidock.com/rails/ActionController/Streaming/send_data

Resources