Ruby on Rails & Prawn PDF - Create Customer List
Asked Answered
P

3

6

I'm trying to produce a PDF report with Prawn, I can get it to do a report on a show action easily enough by passing the single ID but I want to produce one with every record in it. Like a standard rails scaffold index page. Using rails it would look like this:

<% @customer.each do |customer| %>
<%= customer.id %>
<%= customer.name %>
<%end%>

Easy!

But I'm not sure how to do this with Prawn..

Something like:

def index
 @customer = Customer.all
  respond_to do |format|
  format.html
   Prawn::Document.generate("customer_list.pdf") do |pdf|
   pdf.text "#{@customer.id} "
    pdf.text "#{@customer.name} "  
       end
    end
end

Which clearly isn't right.

Any ideas? Thank you.

Pharmacopsychosis answered 2/4, 2012 at 18:42 Comment(1)
I realize you're asking about Prawn but I've had much better experience by generating my reports as HTML/CSS and then converting it to PDF, using the wkhtmltopdf app. There is a wrapper gem called PDFKit that makes working with it easy. wkhtmltopdf: code.google.com/p/wkhtmltopdf and pdfkit: github.com/pdfkit/PDFKit for generating complex reports i find it much easier to generate them in HTML instead of working with PDF/Prawn directly.Clayborn
H
6

It's easy to do with Prawn, Gemfile => gem 'prawn', bundle

lets say you have Customer model:

customers_controller.rb

def show
   @customer = Customer.find(params[:id])
   respond_to do |format|
     format.html
     format.pdf do
        pdf = CustomerPdf.new(@customer)
        send_data pdf.render, filename: "customer_#{id}.pdf",
                              type: "application/pdf",
                              disposition: "inline"
     end
   end
end

then just create pdfs folder under the apps directory, and create file customer_pdf.rb

class CustomerPdf< Prawn::Document

  def initialize(customer)
    super()
    @customer = customer
    text "Id\##{@customer.id}"
    text "Name\##{@customer.name}"
  end

end

show.html.erb

  <div class="pdf_link">
    <%= link_to "E-version", customer_path(@customer, :format => "pdf") %>
  </div>

EDIT:

and don't forget to include pdf to config/initializers/mime_types.rb

Mime::Type.register "application/pdf", :pdf
Heimlich answered 2/4, 2012 at 20:16 Comment(3)
Won't this display a PDF for just one customer from the show path? I'm trying to get a list of every customer in a table. Thanks.Pharmacopsychosis
Yes, this example more shows customers#show instead of customers#index but the idea is similar. Instead of taking a single customer object in the CustomerPdf just take your array of customers, iterate over each and call the same text() method, then append a newline.Clayborn
Awesome! I've been trying to figure this out for a while and I'm unfamiliar with ruby + prawn - this gave me everything I need to get started formatting my PDF. (I think you need a comma after filename: "customer_#{id}.pdf" though)Rawdon
G
2

I think the good solution of your problem is custom renderer. The best approach was described by Jose Valim (!Rails core developer) in his book. The beginning of the first chapter is available for free here. This chapter is really what you need.

Glorify answered 5/6, 2012 at 20:42 Comment(0)
C
1

This how I do it:

class CustomerPdf< Prawn::Document

 def initialize(customer)
  super(page_size: "A4", page_layout: :portrait)
  @customers = customer
  bullet_list
 end

 def bullet_list
  @customers.each do |customer|
      text "•#{customer.id}- #{customer.name} ", style: :bold
    move_down 5
  end
 end

end
Cran answered 17/8, 2016 at 17:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.