Wicked PDF generating pdf only on page refresh - ruby-on-rails

Am working on a web app and I have this "Registration" page. I want to render a pdf page when I visit the show page. But when i click on the show button a normal html page is loaded and the content is like a dump, all gibberish (here is a gist with the content: https://gist.github.com/anonymous/0806200b7ca31bba35d3a514a7ff90e6). However, when I refresh the page it renders the pdf perfectly.
I checked if there was any differences in the url and params but everything was the same. I also checked the instance variables and they were the same. And I googled the issue and didn't find anything on it.
here is the rendering code in the show action:
respond_to do |format|
format.html do
render pdf: 'customer_print_out.pdf',
file: "#{Rails.root}/app/views/pdf/customer_print_out.pdf.erb",
page_size: 'A4',
encoding: 'UTF-8'
end
end
I would like to note that I am generating a barcode in the pdf file. It is also loaded correctly when I refresh the page and when I remove the barcode generating code I still get the same issue.
am using:
Rails v4.2.6, wicked_pdf v1.1.0, puma v3.6.0
Any help or pointers are really appreciated.

In order to render pdf, do the following:
Register the PDF mime type in the config/initializers/mime_types.rb file:
Mime::Type.register "application/pdf", :pdf
In your controller do the following:
class YourController < ApplicationController
def show
#product = Product.first
respond_to do |format|
format.html
format.pdf do
render pdf: 'customer_print_out.pdf',
file: "#{Rails.root}/app/views/pdf/customer_print_out.pdf.erb",
page_size: 'A4', encoding: 'UTF-8'
end
end
end
end
The request should be in pdf format, for example: your_controller_path(format: :pdf)

I think you should use format.pdf instead of format.html
format.pdf do
render pdf: 'customer_print_out.pdf',
file: "#{Rails.root}/app/views/pdf/customer_print_out.pdf.erb",
page_size: 'A4',
encoding: 'UTF-8'
end
also don't forget to specify format as pdf in your button's code, something like
<%= link_to('Show', your_show_action_path(format: :pdf)) %>

Related

Rails Wicked PDF - How to download pdf file after a record is saved and continue redirecting as usual?

I'm having a form in which I want to force user to download a pdf file/version using wicked_pdf gem of that new record with some content with a submit button called Save and Download. For now, the file is downloaded once the user click Save and Download, but the page stands still and is not redirected to its show page as usual. I now it should be like this due to my code example below. Yet, I could not figure how to achieve what I want, Save -> Download PDF -> Redirect, or can be Save -> Redirect -> Download PDF.
Let say I'm having an orders_controller.rb with the following actions.
def create
#order = Order.new(order_params)
if #order.save
redirect_to order_path(#order, format: :pdf)
else
render :new
end
end
def show
respond_to do |format|
format.html do
#order = Order.find(params[:id])
end
format.pdf do
render pdf: 'New Order',
template: 'orders/show.pdf.haml',
page_size: 'A4',
layout: 'pdf_design.haml',
disposition: 'attachment'
end
end
end
Use the below bit of code and pass your instance variable in the locals.
ac = ActionController::Base.new()
pdf_string = ac.render_to_string pdf: 'New Order', template: 'orders/show.pdf.haml', encoding: "UTF-8", locals: {order: #order}
Tweak your view in order to assign your local order to the view instance variable or directly use order
Then assign file like this :
file = StringIO.new(pdf_string)
And then upload it with whatever gem ( Paperclip, Carrierwave...)

Rails 4 wicked pdf Issue

I'm trying to use wicked pdf to render a html page as pdf.
mime_types.rb
Mime::Type.register "application/pdf", :pdf
controller method
def invoice
respond_to do |format|
format.html
format.pdf do
render pdf: "invoice"
end
end
end
wicked_pdf.rb
:exe_path => '/usr/local/bin/wkhtmltopdf'
invoice.pdf.erb
<div id="test_pdf">
test data
</div>
I have added the above codes and added the following gems to my project.
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary'
When I try to render the page, i get Template is missing error. If i rename invoice.pdf.erb to invoice.html.erb i can bypass the error, but i will be getting a html page instead of pdf.
Do I miss something?
As mentioned in the document of wicked_pdf, you can use it like this. Its self explanatory. Don't forget to create "pdfs" directory
# or from your controller, using views & templates and all wicked_pdf options as normal
pdf = render_to_string pdf: "some_file_name", template: "templates/pdf.html.erb", encoding: "UTF-8"
# then save to a file
save_path = Rails.root.join('pdfs','filename.pdf')
File.open(save_path, 'wb') do |file|
file << pdf
end
send_file save_path, :type=>'text/pdf
This code will be more than enough if you just want to render the pdf:
def show
respond_to do |format|
format.html
format.pdf do
render pdf: 'file_name',
template: 'example/pdf_view.pdf.erb',
layout: 'layouts/application.pdf.erb'
end
end
end
If you want to save as pdf:
def save
pdf = WickedPdf.new.pdf_from_string(
render_to_string(
template: 'example/pdf_view.pdf.erb',
layout: 'layouts/application.pdf.erb'))
send_data(pdf,
filename: 'file_name.pdf',
type: 'application/pdf',
disposition: 'attachment')
end

Rails: wicked_pdf "file_name" option

I got wicked_pdf working, but one of the render options is file_name which as far as I can tell has no bearing at all on the PDF rendering. Can someone explain to me what exactly this is for?
class ThingsController < ApplicationController
def show
respond_to do |format|
format.html
format.pdf do
render :pdf => "file_name"
end
end
end
end
It is ultimately passed to Rails' send_data method as the filename option, which:
:filename - suggests a filename for the browser to use.
So when you say:
format.pdf { render pdf: 'the_answer' }
It becomes:
send_data(pdf_content, :filename => 'the_answer.pdf',..
The send_data method uses this (with other options) to set the Content-Disposition header in the response. If you inspect the response (e.g. in Chrome's Developer Tools) you will see:
Content-Disposition:inline; filename="the_answer.pdf"
How the browser implements this is ultimately up to it, but in Chrome you can see it by right clicking on the PDF and clicking 'Save as...'
Note: The presence of the :pdf key is used to decide whether wicked_pdf should handle it, so it must be specified if you wish you use this render helper.

How to render a PDF in the browser that is retrieve via rails controller

I have a rails app that uses Recurly. I am attempting to download a PDF and render it in the browser. I currently have a link:
link_to 'Download', get_invoice_path(:number => invoice.invoice_number)
The associated controller has the get_invoice method that looks like so:
def get_invoice
begin
#pdf = Recurly::Invoice.find(params[:number], :format => 'pdf')
rescue Recurly::Resource::NotFound => e
flash[:error] = 'Invoice not found.'
end
end
When I click the link I get the PDF rendered in my console in binary form. How do I make this render the PDF in the browser?
You don't render the PDF to the browser, you send it as a file. Like so:
# GET /something/:id[.type]
def show
# .. set #pdf variable
respond_to do |format|
format.html { # html page }
format.pdf do
send_file(#pdf, filename: 'my-awesome-pdf.pdf', type: 'application/pdf')
end
end
end
The HTML response isn't needed if you aren't supporting multiple formats.
If you want to show the PDF in the browser instead of starting a download, add disposition: :inline to the send_file call.
Assuming the PDF is saved in memory, use the send_data to send the data stream back in the browser.
def get_invoice
#pdf = Recurly::Invoice.find(params[:number], :format => 'pdf')
send_data #pdf, filename: "#{params[:number]}.pdf", type: :pdf
end
If the file is stored somewhere (but this doesn't seem to be your case), use send_file.

Using Prawn & Prawnto for Rails PDF generation

This is probably more a design or usage question but the main issue is using the Prawn plugin with Rails 2.3.4 and accessing the resulting PDF object to render it to a file.
The scenario is basically;
a controller with the respond_to block setup
a view with code for rendering the text, graphics etc to PDF
It looks like:
From Customer Controller
def show
#customer = Customer.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #customer }
format.pdf { render :layout => false }
end
From Customer View
pdf.text "Hello World"
pdf.text "Customer is #{#customer.name}"
This works fine, producing a PDF file in response to /customers/1.pdf, as expected with a PDF file being generated.
One of the other requirements is to render the pdf to a file and store a copy on the server. Prawn provides the method:
pdf.render_file {path_tofile}
So now if I include this in the View code I can of course save the file on the server. But I'd like to manage this in the controller, as it's related to logic, not view per se.
The first attempt was :
def show
#customer = Customer.find(params[:id])
#pdf = Prawn::Document.new()
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #customer }
format.pdf { render :layout => false }
pdf.render_file {path_to_file}
end
From Customer View
pdf.text "Hello World"
pdf.text "Customer is #{#customer.name}"
PROBLEM
The problem with this attempt is that the PDF is not rendered. I suspected the Controller instance variable is clashing with the Prawnto Plugin pdf variable. But even changing the PDF variable didn't work.
Any suggestions ?
This is how I use prawn in my rails app: http://yob.id.au/2009/05/30/prawn-and-x-accel-redirect.html - it doesn't use prawnto at all.
You can ignore the X-Accel-Redirect stuff unless you use nginx.
Alternatively, another one of the prawn core devs has put together this guide: http://wiki.github.com/sandal/prawn/using-prawn-in-rails

Resources