1
votes

I need to print an order into PDF. I am using pdfkit gem. Absolutely exhausted but its just not printing any css.

application.html.erb:

<%= stylesheet_link_tag    "application", :media => "all"%>

order_controller.rb

 respond_to do |format|
  format.html
  format.pdf {
    html = render_to_string(:template => "show.html.erb")
    kit = PDFKit.new(html)
    kit.stylesheets << "http://localhost:3000/stylesheets/application.css" <-- hardcoded this 
    send_data(kit.to_pdf, :filename => "test_pdf", :type => "application/pdf", :disposition => 'attachment')

    return
  }

config/initializers/pdfkit.rb

  PDFKit.configure do |config|
  config.wkhtmltopdf = 'Gem/Path/to/wkhtmltopdf'
  config.default_options = {
     :page_size => 'Legal',
     :print_media_type => true
  }
  # Use only if your external hostname is unavailable on the server.
  config.root_url = "http://localhost"
  config.verbose = false
end

application.rb

   config.middleware.use "PDFKit::Middleware", :print_media_type => true

mime_types.rb

   Mime::Type.register 'application/pdf', :pdf

I simply go to the page like http://localhost:3000/orders/4 and append a .pdf (as per Railscasts). http://localhost:3000/orders/4.pdf shows a pdf but no css. Same with Browser's print preview.

Does anyone know how I can debug this further?

1

1 Answers

1
votes

The problem is that you're trying to load the stylesheet via HTTP. However, the PDFKit requires a File.

This is taken from the PDFKit source code:

  def style_tag_for(stylesheet)
    "<style>#{File.read(stylesheet)}</style>"
  end

See the rest of the code at:

https://github.com/pdfkit/pdfkit/blob/master/lib/pdfkit/pdfkit.rb#L105

My suggestion would try edit the show.html.erb with adding:

<style> <%= Rails.application.assets['application.css'].to_s %> </style>

Or loading it from file. Change your code to this:

temp = Tempfile.new("pdf_css_temp")
temp.write(Rails.application.assets['application.css'].to_s)
temp.close
kit.stylesheets << temp.path

other_controller.rb

respond_to do |format|
  format.html
  format.pdf {
    html = render_to_string(:template => "show.html.erb")
    kit = PDFKit.new(html)
    temp = Tempfile.new("pdf_css_temp")
    temp.write(Rails.application.assets['application.css'].to_s)
    temp.close
    kit.stylesheets << temp.path
    send_data(kit.to_pdf, :filename => "test_pdf", :type => "application/pdf", :disposition => 'attachment')
    temp.unlink
    return
  }

However, the downside of this is that it will write a temporary file each time you generate a PDF. In a production environment you probably want to solve this by using a static file generated by rails.