Search code examples
ruby-on-railsrubyruby-on-rails-5prawn

Generate table in pdf with prawn


I have successfully generated pdf file using prawn pdf gem inside the controller , but I want to separate class files and call the method of the class to make the controller code look clean. Here is my in-controller method

  def download_pdf
if Subscriber.count<50
  addSubscribers()
else
  @subscribers=Subscriber.all.order("name ASC")
end
  respond_to do |format|
    format.pdf do
      pdf = Prawn::Document.new
      table_data = Array.new
      table_data << ["Name","E-mail","Phone"]
      @subscribers.each do |p|
        table_data << [p.name, p.email,p.phone]
      end
      pdf.table(table_data, :width => 500, :cell_style => { :inline_format => true })
      send_data pdf.render, filename: 'test.pdf', type: 'application/pdf', :disposition => 'inline'
    end
  end

end

But when I try to use the following code->

def download_pdf
  @subscribers=Subscriber.all.order("name ASC")
  PdfCreator.new(@subscribers)
end

And the PdfCreator class is ->

    class PdfCreator

  def initialize(subscribers)
    @subs=subscr
    download_pdf()
  end

  def download_pdf()
      pdf = Prawn::Document.new
      table_data = Array.new
      table_data << ["Name","E-mail","Phone"]
      @subs.each do |p|
        table_data << [p.name, p.email,p.phone]
      end
      pdf.table(table_data, :width => 500, :cell_style => { :inline_format => true })
    send_data pdf.render, filename: 'test.pdf', type: 'application/pdf', :disposition => 'inline'
  end

end

respond to is not resolving as a method. I found some codes on generating pdf from an outside class but only for normal texts not for tables- Any help regarding how to do it for tables , that will be a great help


Solution

  • send_data is a controller-level method, and won't work inside your custom class, and the respond_to might be needed for your route to respond appropriately.

    Let's try keeping what's needed in the controller and extract only PDF-generating logic to the new PdfCreator class:

    def download_pdf
      @subscribers=Subscriber.all.order("name ASC")
    
      respond_to do |format|
        format.pdf do
          pdf = PdfCreator.new(@subscribers)
          send_data pdf.render, filename: 'test.pdf', type: 'application/pdf', disposition: 'inline'
        end
      end
    end
    
    
    class PdfCreator
      def initialize(subscribers)
        @subs=subscribers
      end
    
      def render()
        pdf = Prawn::Document.new
        table_data = Array.new
        table_data << ["Name","E-mail","Phone"]
        @subs.each do |p|
          table_data << [p.name, p.email,p.phone]
        end
        pdf.table(table_data, :width => 500, :cell_style => { inline_format: true })
        pdf.render
      end
    end