19

I have a rails 3.1 app that creates pdf documents using pdfkit, and everything works as specified, except for the fact that the generated pdfs don't have any styling. I am assuming that wkhtmltopdf doesn't have access to my stylesheets and that it is not a larger issue than that. Would anyone have a clue as to how you would allow access to these stylesheets? I have basically followed railscast #220 on the subject, however I have had to create a new initializer to get pdfkit to work with rails 3.1.

This is the initializer that I had to use to get pdfkit to work with rails 3.1

ActionController::Base.asset_host = Proc.new { |source, request|
  if request.env["REQUEST_PATH"].include? ".pdf"
    "file://#{Rails.root.join('public')}"
  else
    "#{request.protocol}#{request.host_with_port}"
  end
 } 

The link to the pdf looks like this:

<%= link_to 'Download PDF', load_path(@load, :format => "pdf") %>

This will give me a link to the pdf that has no styling.

In my application.rb I have configured pdfkit as such:

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

I have also added this to my layouts/application.html.erb file:

<%= stylesheet_link_tag    "application", :media => "all" %>
tomciopp
  • 2,602
  • 2
  • 31
  • 60
  • I have added some more code, if you need a visual or any other information, I would be happy to oblige. – tomciopp Nov 08 '11 at 01:03
  • I'm having the same issue. Using Rails 3.1 and asset pipeline renders all the above initializers and hacks useless. Can't figure out a way around it. – Nuby Nov 22 '11 at 18:08
  • Are you sure that `:media => "all"` is specified? I was surprised to see that the default is 'screen' only. Another way to check: if you ask your browser to print, is the page styled? – Marc-André Lafortune Nov 22 '11 at 22:21
  • @tomciopp Did you get this sorted out? I've been wrestling with it for a few days now... – Tony Tambe Oct 06 '14 at 17:10
  • This isn't really a "solution" - but a workaround, since it has been years since this was initially reported and may never be fixed. Put your styles in an ordinary view file, written as inline with – JosephK Apr 24 '17 at 13:50

6 Answers6

6

Stealing a couple of lines from the middleware code found at https://github.com/pdfkit/pdfkit/blob/master/lib/pdfkit/middleware.rb

You can use:

root = PDFKit.configuration.root_url || "#{env['rack.url_scheme']}://#{env['HTTP_HOST']}/"
html.gsub!(/(href|src)=(['"])\/([^\"']*|[^"']*)['"]/, '\1=\2' + root + '\3\2')

My example is:

html = render_to_string #render current action to string
root = PDFKit.configuration.root_url || "#{env['rack.url_scheme']}://#{env['HTTP_HOST']}/"
html.gsub!(/(href|src)=(['"])\/([^\"']*|[^"']*)['"]/, '\1=\2' + root + '\3\2')
kit = PDFKit.new(html, :print_media_type => true)
user2185938
  • 97
  • 1
  • 6
2

For me it was problem with installation for ubuntu. I just reinstalled from source:

# first, installing dependencies
sudo aptitude install openssl build-essential xorg libssl-dev

# for 64bits OS
wget http://wkhtmltopdf.googlecode.com/files/wkhtmltopdf-0.9.9-static-amd64.tar.bz2 
tar xvjf wkhtmltopdf-0.9.9-static-amd64.tar.bz2
mv wkhtmltopdf-amd64 /usr/local/bin/wkhtmltopdf
chmod +x /usr/local/bin/wkhtmltopdf

# for 32bits OS
wget http://wkhtmltopdf.googlecode.com/files/wkhtmltopdf-0.9.9-static-i386.tar.bz2 
tar xvjf wkhtmltopdf-0.9.9-static-i386.tar.bz2
mv wkhtmltopdf-i386 /usr/local/bin/wkhtmltopdf
chmod +x /usr/local/bin/wkhtmltopdf

And everything works now for me. So my advice is do not install wkhtmltopdf by this command sudo apt-get install wkhtmltopdf and install it from sources. Full instructions for installation process

ka8725
  • 2,788
  • 1
  • 24
  • 39
2

I know you're looking for solution that will render whole page, just reminder for googling people that there is still problem free workaround

class DocumentController < ApplicationController

  def show
    @document = Document.last
    # ... implement your respond_to

    kit = PDFKit.new(@document.content, :page_size => 'Letter')
    kit.stylesheets << "#{Rails.root}/app/assets/stylesheets/pdf.css"
    send_data kit.to_pdf, :filename => "#{@document.title}.pdf", :type => 'application/pdf'
  end

end

now the pdf.css must be css, so teoretically if you need to load sass load it from pre-compiled public/assets/

equivalent8
  • 13,754
  • 8
  • 81
  • 109
2

I ran into this problem as well, and it appears that when the asset pipeline was added in Rails 3.1, pdfkit has a problem with the stylesheet links. See the GitHub issue about this problem.

I ended up switching to wicked_pdf and am really happy with it. They've solved this problem and it works nicely on Rails 3.2.x (haven't tried 3.1.x).

LukeR
  • 220
  • 1
  • 3
  • 10
1

I have used gem 'wicked_pdf' and its helpers to include CSS into pages. Internally that helpers just read all CSS files and include into the page itself. So if you prefer to use PdfKit try to investigate how to include non-inline stylesheets.

Mark Huk
  • 2,379
  • 21
  • 28
0

I have successfully run PDFKit on Rails 3.1. I have used a different setup though.

At first I had the same problem you did but that was because stylesheet_link_tag has a default set to media => "screen"; specifying explicitely media => "all" fixed it.

Community
  • 1
  • 1
Marc-André Lafortune
  • 78,216
  • 16
  • 166
  • 166
  • 2
    I have specified media => "all" in the layouts/application.html.erb file so that shouldn't be the problem. Can you elaborate further on your different setup so I can see if that will make this work? Have you checked to see if this will also work in a production setting since you have only altered the development environment? – tomciopp Nov 23 '11 at 22:11
  • @demondeac11: I saw you specified it, but maybe you're using another layout? Did you check if asking Chrome to print your page will have it styled? Follow the link to my different setup. Setups for production will depend on your environment and typically you'll have your assets served statically, maybe from a CDN, or load balancers, etc... – Marc-André Lafortune Nov 24 '11 at 16:10