8

I'm able to download pdf file with:

curl google.com | wkhtmltopdf - test.pdf

so it means, wkhtmlpdf installation was successful.

But, when I try to generate pdf file by accessing http://localhost:3000/contacts/1.pdf it hangs. In the status bar it shows: Waiting for localhost...

Rails server output:

Started GET "/contacts/1.pdf" for 127.0.0.1 at 2013-07-28 21:45:06 +0900
  ActiveRecord::SchemaMigration Load (0.1ms)  SELECT "schema_migrations".* FROM "schema_migrations"
Processing by ContactsController#show as HTML
  Parameters: {"id"=>"1"}
  Contact Load (0.3ms)  SELECT "contacts".* FROM "contacts" WHERE "contacts"."id" = ? LIMIT 1  [["id", "1"]]
  Rendered contacts/show.html.erb within layouts/application (1.4ms)
Completed 200 OK in 99ms (Views: 57.0ms | ActiveRecord: 0.7ms)

Gemfile:

gem 'pdfkit'

application.rb:

config.middleware.use "PDFKit::Middleware"

According to the PDFKit railscast this should be enough for generating pdf files just by adding .pdf ...


UPDATE:

show.html.erb:

<p id="notice"><%= notice %></p>

<p>
  <strong>Name:</strong>
  <%= @contact.name %>
</p>

<p>
  <strong>Age:</strong>
  <%= @contact.age %>
</p>

<%= link_to 'Edit', edit_contact_path(@contact) %> |
<%= link_to 'Back', contacts_path %>

layouts/application.html.erb:

<!DOCTYPE html>
<html>
<head>
  <title>Pdftest</title>
  <%= stylesheet_link_tag    "application", media: "all", "data-turbolinks-track" => true %>
  <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
  <%= csrf_meta_tags %>
</head>
<body>

<%= yield %>

</body>
</html>

UPDATE 2:

Thanks to @Arman H for helping me to figure out that I have to specify absolute path for assets instead of a relative ones. When I removed the following lines I was able to generate PDF file:

<%= stylesheet_link_tag    "application", media: "all", "data-turbolinks-track" => true %>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>

Now, I can't get how to substitute this with an absolute paths. It seems this post is what I need, but I still can't figure out how this would look like for my case.

Community
  • 1
  • 1
Askar
  • 5,784
  • 10
  • 53
  • 96
  • How long does it hang for? Do you get any errors from `wkhtmltopdf` in Rails' console? Sometimes it appears to hang, but it's really just taking a long time to process the PDF. How long have you had it running for before cutting the request off? – Arman H Jul 28 '13 at 23:59
  • The issue above I had on Mac OS x. Now I'm having the same on Linux Mint. It's still "Waiting for localhost..." for 20 min and it seems this is going to be endless. I just have to cancel server by Ctrl + c. – Askar Jul 29 '13 at 02:19
  • When I shutdown server after 40 min, it generated pdf file for me. I tried again to shutdown server after 1 min, in this case it showed: command failed: /usr/bin/wkhtmltopdf --page-size Letter --margin-top 0.75in --margin-right 0.75in --margin-bottom 0.75in --margin-left 0.75in --encoding UTF-8 --quiet - - – Askar Jul 29 '13 at 02:44
  • Try running `wkhtmltopdf` from terminal, outside of Rails, with the same parameters, and see if it gives you any errors. That is, run `/usr/bin/wkhtmltopdf --page-size Letter --margin-top 0.75in --margin-right 0.75in --margin-bottom`... – Arman H Jul 29 '13 at 02:46
  • it's also hanging when I run: /usr/bin/wkhtmltopdf --page-size Letter --margin-top 0.75in --margin-right 0.75in --margin-bottom 0.75in --margin-left 0.75in --encoding UTF-8 --quiet - - – Askar Jul 29 '13 at 02:49
  • Are you loading assets in HTML (CSS, JavaScript, etc) from the same server that's generating the PDF? I've had similar issues when asset paths were relative, and `wkhtmltopdf` couldn't find/load them. Try removing all assets, and rendering bare HTML. If that's the issue, rewrite your paths with absolute values. – Arman H Jul 29 '13 at 03:11
  • I've updated my post with show.html.erb and application.html.erb. Is there anything wrong? – Askar Jul 29 '13 at 03:16
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/34341/discussion-between-arman-h-and-oscar) – Arman H Jul 29 '13 at 03:17

3 Answers3

8

The issue was due to stylesheet_link_tag and javascript_include_tag using relative URLs, which often causes wkhtmltopdf to hang when loading assets from the same server that wkhtmltopdf is running on.

Using absolute URLs for assets solved the problem.

Set asset_host in Rails' config, which also affects stylesheet_link_tag and javascript_include_tag:

# Modify asset host config setting in `config/application.rb`
# Or create a new initializer: `config/initializers/wkhtmltopdf.rb`
config.action_controller.asset_host = "http://mysite.com"

# Or you can have different hosts for development (local) and production (CDN):
# In `config/environments/development.rb`
config.action_controller.asset_host = "http://localhost"
# In `config/environments/production.rb`
config.action_controller.asset_host = "http://d111111abcdef8.cloudfront.net"
Arman H
  • 5,488
  • 10
  • 51
  • 76
  • Thanks! In the config, which file should I edit? I don't have any host name, I'm running the app localy. What should I specify in this case instead of "http://mysite.com" ? – Askar Aug 01 '13 at 03:24
  • Either `localhost` or `127.0.0.1` (or whatever local IP you get from Rails console). – Arman H Aug 01 '13 at 03:25
  • which file should I edit to add config.action_controller.asset_host = "http://mysite.com" ? – Askar Aug 01 '13 at 03:27
  • I updated answer. You can set it in either `config/application.rb` or `config/initializers/wkhtmltopdf.rb` (you have to create this file). You can also set different hosts for development/production by assigning different values in `config/environments/development.rb` and `config/environments/production.rb` (see update). – Arman H Aug 01 '13 at 03:37
  • The problem is different, it's because in Rails 4 WEBrick in development env is indeed single threaded. It can't serve images from the localhost anymore. In Rails 3 somehow it worked. Probably by setting the asset_host you indirectly resolved your problem. But the root of it is WEBrick and threads. http://stackoverflow.com/questions/14027151/how-rails-resolve-multi-requests-at-the-same-time and http://stackoverflow.com/questions/20377401/pdfkit-hangs-when-generating-a-pdf-with-an-image – januszm Sep 26 '15 at 20:05
3

Setting config.action_controller.asset_host = "http://localhost" in development.rb actually didn't work for me. That is, the PDF generation would work, but then assets wouldn't come through when rendering HTML.

I followed the method here: http://jguimont.com/post/2627758108/pdfkit-and-its-middleware-on-heroku

and it worked like a charm for me. Hope this helps someone. Just throw assets.rb in config/intializers and you're good to go.

Greg Blass
  • 3,523
  • 29
  • 42
0

I had the same issue in which my log showed the page had rendered however no pdf was generated and the browser would hang. It ended up having nothing to do with OS compatability, missing librariers, gems nor dependencies but instead I needed to raise the max allowable thread count for my Puma server (which had been set to 1) upto 2 or more. This then generated pdf's as normal.

bkunzi01
  • 4,504
  • 1
  • 18
  • 25