What I want to do is, generate a PDF file from my current page. (HTML)
I call a controller function which generates my page, it fetches data from database and so on.
Now I want a button which saves the current rendered page as a PDF file on the visitors machine. How can I do that?
If I use your code like this:
respond_to do |format|
format.html { render :template => "user/settings" }
format.pdf {
kit = PDFKit.new('http://google.com')
kit.stylesheets << "#{Rails.root}/public/stylesheets/pdf.css"
send_data(kit.to_pdf, :filename=>"sdasd.pdf",
:type => 'application/pdf', :disposition => 'inline')
}
end
and reload the page ... nothing gonna be downloaded as a pdf ... why?
You can create a similar template for pdf of your current page. Then you can use pdfkit gem.
Add this gems to your gemfile:
gem "pdfkit"
gem "wkhtmltopdf-binary"
Add something like this at your controller:
def show
#user= User.find(params[:id])
respond_to do |format|
format.html { render :template => "users/show" }
format.pdf {
html = render_to_string(:layout => false , :action => "show.pdf.erb") # your view erb files goes to :action
kit = PDFKit.new(html)
kit.stylesheets << "#{Rails.root}/public/stylesheets/pdf.css"
send_data(kit.to_pdf, :filename=>"#{#user.id}.pdf",
:type => 'application/pdf', :disposition => 'inline')
}
end
end
Now you can download pdf by adding .pdf to your controller route. eg: controller/routes/path/1.pdf
Or if you don't like it you can do
kit = PDFKit.new('http://google.com')
Related
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.
sorry for my english.
I am trying to user prawn and prawnto on my application. I have a pdf file to use as template, the pdf file has only one page and that page just has a header and a footer, then, I have this on my controller:
def index
#search = User.search(params[:search])
#users = #search.paginate(:page => params[:page])
respond_to do |format|
format.html # index.html.erb
format.json { render json: #users }
format.xml { render xml: #users }
format.xlsx { export2xlsx(#search.relation.to_xlsx :columns => [:cod_cia, :cod_emp, :login, :email]) }
format.pdf { render :layout => false }
prawnto :prawn => { :template => "#{Rails.root}/app/assets/pdfs/template1.pdf" }
end
end
All good, except that the template is rendered only at the first generated page, the other pages has not the template.
Somebody know how I can get the template repeat in my all generated pages?
Thk in advance.
Regards.
Not sure about prawnto, but with prawn you can tell it to not auto create the first page. Then add each page manually with a template.
filename = "/path/to/template.pdf"
Prawn::Document.generate("output.pdf", :skip_page_creation => true) do
start_new_page(:template => filename)
text "First page"
start_new_page(:template => filename)
text "Second page"
end
I currently run Rails 3.1 and am using the latest version of Wicked_pdf for PDF generation.
I have set everything up correctly, and PDFs are generated just fine.
However, I want the user to be able to click a button to DOWNLOAD the pdf. At the present time, when clicked, the browser renders the pdf and displays it on the page.
<%= link_to "Download PDF", { :action => "show", :format => :pdf }, class: 'button nice red large radius', target: '_blank'%>
My Controller.
def show
#curric = Curric.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #curric }
format.pdf do
render :pdf => #curric.name + " CV",
:margin => {:top => 20,
:bottom => 20 }
end
end
end
I have been pointed towards send_file, but have absolutely no idea how to use it in this scenario.
Any help is appreciated.
Decomposition the config you need to set as 'attachment', example:
respond_to do |format|
format.pdf do
render pdf: #curric.name + " CV",
disposition: 'attachment'
end
end
I am doing it that way:
def show
#candidate = Candidate.find params[:id]
respond_to do |format|
format.html
format.pdf do
#pdf = render_to_string :pdf => #candidate.cv_filename,
:encoding => "UTF-8"
send_data(#pdf, :filename => #candidate.cv_filename, :type=>"application/pdf")
end
end
end
and it works for me ;-)
Let's try:
pdf = render_to_string :pdf => #curric.name + " CV",
:margin => {:top => 20,
:bottom => 20 }
send_file pdf
//Download pdf generated from html template using wicket_pdf gem
pdf = render_to_string :template => "simple/show" // here show is a show.pdf.erb inside view
send_data pdf
I have configured a custom mime type:
ActionController::Renderers.add :csv do |csv, options|
self.content_type ||= Mime::CSV
self.response_body = csv.respond_to?(:to_csv) ? csv.to_csv : csv
end
and a respond_to block in my controller:
respond_to do |format|
format.html
format.csv { render :csv => csv_code}
end
Using Firefox and Chrome, the .csv renders to a file which is downloaded. Using Safari the .csv is rendered as a view: How can I change this and force it to download as a file?
See a screen shot of the problem:
Try
respond_to do |format|
format.html
format.csv do
response.headers['Content-Type'] = 'text/csv'
response.headers['Content-Disposition'] = 'attachment; filename=thefile.csv'
render :csv => csv_code
end
end
if this doesn't work, try using
send_file "path/to/file.csv", :disposition => "attachment"
The way I have this working in an old Rails 2 app is using send_data instead of render in the controller. E.g.:
def csv
... # build data
send_data csv_data_as_string, :filename => "#{filename}.csv", :type => 'text/csv'
end
What i have is the controller action responding to html and pdf file format like this:
def detail
#record = Model.find(params[:id])
respond_to do |format|
format.html # detail.html.erb
format.pdf { render :layout => false } #detail.pdf.prawn
end
end
but when i get the file it comes with the name: 1.pdf 2.pdf depending on the params[:id] how do i set the filename to myfile.pdf
--UPDATE--
Example of my detail.pdf.prawn file
pdf.font "Helvetica"
pdf.image open("http://localhost:3000/images/myImage.png"),:position => :left,:width=>100
pdf.text "some text"
pdf.table(someData,:cell_style => { :border_width => 0.1,:border_color=> 'C1C1C1' }) do |table|
table.row(0).style :background_color => 'D3D3D3'
table.column(0..1).style(:align => :left)
table.column(2..4).style(:align => :center)
table.column(0).width = 100
table.column(1).width = 250
table.column(3..4).width = 68
table.row(2).column(0..2).borders = []
table.row(2).column(3).style(:font_style => :bold, :align => :right)
end
and the format.pdf { render :layout => false } in the controller renders de pdf file with the instructions on detail.pdf.prawn
To elaborate on fl00r's answer, If your using prawnto, the pdf setup params can go in your controller, including the filename.
def detail
#record = Model.find(params[:id])
prawnto :prawn => { :page_size => 'A4',
:left_margin => 50,
:right_margin => 50,
:top_margin => 80,
:bottom_margin => 50},
:filename => #record.name, :inline => true #or false
respond_to do |format|
format.html # detail.html.erb
format.pdf { render :layout => false } #detail.pdf.prawn
end
end
If you are creating lot's of different pdf's with prawnto, you would probably move the config out into it's own method. but if your only doing the one, in the controller is fine.
NOTE: the PDF url will still display e.g. 1.pdf But when they save the PDF the filename param will show up in the save box dialog.
prawnto :filename => "myfile", :prawn => {
...
}
Really thanks, this post really help my old pdf way. There is another way to using prawn of Rails. You can check oh this link. Not mine, but a good tutorial for making it. Just saying probably for anyone that still confuse how to make it.
I was using this method before, then I moved on method from that link. Really fun for doing some research about it.
If prawn-rails or prawn_plus you may do following in controller.
headers["Content-Disposition"] = "attachment; filename=\"myfile.pdf\""