Giter Site home page Giter Site logo

pdfkit's Introduction

PDFKit

Create PDFs using plain old HTML+CSS. Uses wkhtmltopdf on the back-end which renders HTML using Webkit.

Supported versions

  • Ruby 2.5, 2.6, 2.7, 3.0, 3.1
  • Rails 4.2, 5.2, 6.0, 6.1, 7.0

Install

PDFKit

gem install pdfkit

wkhtmltopdf

  1. Install by hand (recommended):

    https://github.com/pdfkit/pdfkit/wiki/Installing-WKHTMLTOPDF

  2. Try using the wkhtmltopdf-binary-edge gem (mac + linux i386)

gem install wkhtmltopdf-binary

Note: The automated installer has been removed.

Usage

# PDFKit.new takes the HTML and any options for wkhtmltopdf
# run `wkhtmltopdf --extended-help` for a full list of options
kit = PDFKit.new(html, :page_size => 'Letter')
kit.stylesheets << '/path/to/css/file'

# Get an inline PDF
pdf = kit.to_pdf

# Save the PDF to a file
file = kit.to_file('/path/to/save/pdf')

# PDFKit.new can optionally accept a URL or a File.
# Stylesheets can not be added when source is provided as a URL or File.
kit = PDFKit.new('http://google.com')
kit = PDFKit.new(File.new('/path/to/html'))

# Add any kind of option through meta tags
PDFKit.new('<html><head><meta name="pdfkit-page_size" content="Letter"')
PDFKit.new('<html><head><meta name="pdfkit-cookie cookie_name1" content="cookie_value1"')
PDFKit.new('<html><head><meta name="pdfkit-cookie cookie_name2" content="cookie_value2"')

Resolving relative URLs and protocols

If the source HTML has relative URLs (/images/cat.png) or protocols (//example.com/site.css) that need to be resolved, you can pass :root_url and :protocol options to PDFKit:

PDFKit.new(html, root_url: 'http://mysite.com/').to_file
# or:
PDFKit.new(html, protocol: 'https').to_file

Using cookies in scraping

If you want to pass a cookie to pdfkit to scrape a website, you can pass it in a hash:

kit = PDFKit.new(url, cookie: {cookie_name: :cookie_value})
kit = PDFKit.new(url, [:cookie, :cookie_name1] => :cookie_val1, [:cookie, :cookie_name2] => :cookie_val2)

Configuration

If you're on Windows or you would like to use a specific wkhtmltopdf you installed, you will need to tell PDFKit where the binary is. PDFKit will try to intelligently guess at the location of wkhtmltopdf by running the command which wkhtmltopdf. If you are on Windows, want to point PDFKit to a different binary, or are having trouble with getting PDFKit to find your binary, please manually configure the wkhtmltopdf location. You can configure PDFKit like so:

# config/initializers/pdfkit.rb
PDFKit.configure do |config|
  config.wkhtmltopdf = '/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

Middleware

PDFKit comes with a middleware that allows users to get a PDF view of any page on your site by appending .pdf to the URL.

Middleware Setup

Non-Rails Rack apps

# in config.ru
require 'pdfkit'
use PDFKit::Middleware

Rails apps

# in application.rb(Rails3) or environment.rb(Rails2)
require 'pdfkit'
config.middleware.use PDFKit::Middleware

With PDFKit options

# options will be passed to PDFKit.new
config.middleware.use PDFKit::Middleware, :print_media_type => true

With conditions to limit routes that can be generated in pdf

# conditions can be regexps (either one or an array)
config.middleware.use PDFKit::Middleware, {}, :only => %r[^/public]
config.middleware.use PDFKit::Middleware, {}, :only => [%r[^/invoice], %r[^/public]]

# conditions can be strings (either one or an array)
config.middleware.use PDFKit::Middleware, {}, :only => '/public'
config.middleware.use PDFKit::Middleware, {}, :only => ['/invoice', '/public']

# conditions can be regexps (either one or an array)
config.middleware.use PDFKit::Middleware, {}, :except => [%r[^/prawn], %r[^/secret]]

# conditions can be strings (either one or an array)
config.middleware.use PDFKit::Middleware, {}, :except => ['/secret']

With conditions to force download

# force download with attachment disposition
config.middleware.use PDFKit::Middleware, {}, :disposition => 'attachment'
# conditions can force a filename
config.middleware.use PDFKit::Middleware, {}, :disposition => 'attachment; filename=report.pdf'

Saving the generated .pdf to disk

Setting the PDFKit-save-pdf header will cause PDFKit to write the generated .pdf to the file indicated by the value of the header.

For example:

headers['PDFKit-save-pdf'] = 'path/to/saved.pdf'

Will cause the .pdf to be saved to path/to/saved.pdf in addition to being sent back to the client. If the path is not writable/non-existent the write will fail silently. The PDFKit-save-pdf header is never sent back to the client.

Troubleshooting

  • Single thread issue: In development environments it is common to run a single server process. This can cause issues when rendering your pdf requires wkhtmltopdf to hit your server again (for images, js, css). This is because the resource requests will get blocked by the initial request and the initial request will be waiting on the resource requests causing a deadlock.

    This is usually not an issue in a production environment. To get around this issue you may want to run a server with multiple workers like Passenger or try to embed your resources within your HTML to avoid extra HTTP requests.

    Example solution (rails / bundler), add unicorn to the development group in your Gemfile gem 'unicorn' then run bundle. Next, add a file config/unicorn.conf with

     worker_processes 3
    

    Then to run the app unicorn_rails -c config/unicorn.conf (from rails_root)

  • Resources aren't included in the PDF: Images, CSS, or JavaScript does not seem to be downloading correctly in the PDF. This is due to the fact that wkhtmltopdf does not know where to find those files. Make sure you are using absolute paths (start with forward slash) to your resources. If you are using PDFKit to generate PDFs from a raw HTML source make sure you use complete paths (either file paths or urls including the domain). In restrictive server environments the root_url configuration may be what you are looking for change your asset host.

  • Mangled output in the browser: Be sure that your HTTP response headers specify "content-type: application/pdf"

Note on Patches/Pull Requests

  • Fork the project.
  • Setup your development environment with: gem install bundler; bundle install
  • Make your feature addition or bug fix.
  • Add tests for it. This is important so I don't break it in a future version unintentionally.
  • Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
  • Send me a pull request. Bonus points for topic branches.

Copyright

Copyright (c) 2010 Jared Pace. See LICENSE for details.

pdfkit's People

Contributors

cdwort avatar danbernier avatar devn avatar dmeremyanin avatar geetarista avatar gi avatar grosser avatar huerlisi avatar jarthod avatar jdpace avatar jgehtland avatar joaovitor avatar jteneycke avatar leonyip avatar luan avatar maneyko avatar mdeering avatar midnightmonster avatar miry avatar mnoack avatar nicpillinger avatar nikolai-b avatar nwiebe avatar rojotek avatar serene avatar sigmavirus24 avatar steventux avatar thomasdarde avatar tricknotes avatar tyleritp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pdfkit's Issues

rack middleware doesn't check that the response body exists

I must be doing something wrong in my setup that the response body is empty. Would be nice if the middleware checked for this condition and gave a meaningful error message.

Completed in 635ms (View: 225, DB: 15) | 200 OK [http://localhost/orders/26.pdf?edtr_client=true]
/!\ FAILSAFE /!\ Fri Jun 18 10:37:00 -0700 2010
Status: 500 Internal Server Error
undefined method bytes' for nil:NilClass /home/greg/proj/eDTR_Master/vendor/rails/activesupport/lib/active_support/whiny_nil.rb:52:inmethod_missing'
/home/greg/.gem/ruby/1.8/gems/pdfkit-0.3.3/lib/pdfkit/middleware.rb:30:in call' /home/greg/proj/eDTR_Master/vendor/rails/actionpack/lib/action_controller/string_coercion.rb:25:incall'
/home/greg/proj/eDTR_Master/vendor/gems/rack-1.0.1/lib/rack/head.rb:9:in call' /home/greg/proj/eDTR_Master/vendor/gems/rack-1.0.1/lib/rack/methodoverride.rb:24:incall'
/home/greg/proj/eDTR_Master/vendor/rails/actionpack/lib/action_controller/params_parser.rb:15:in call' /home/greg/proj/eDTR_Master/vendor/rails/actionpack/lib/action_controller/session/cookie_store.rb:93:incall'
/home/greg/proj/eDTR_Master/vendor/rails/actionpack/lib/action_controller/failsafe.rb:26:in call' /home/greg/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/lock.rb:11:incall'
/home/greg/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/lock.rb:11:in synchronize' /home/greg/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/lock.rb:11:incall'
/home/greg/proj/eDTR_Master/vendor/rails/actionpack/lib/action_controller/dispatcher.rb:114:in call' /home/greg/proj/eDTR_Master/vendor/rails/actionpack/lib/action_controller/reloader.rb:34:inrun'
/home/greg/proj/eDTR_Master/vendor/rails/actionpack/lib/action_controller/dispatcher.rb:108:in call' /home/greg/proj/eDTR_Master/vendor/rails/railties/lib/rails/rack/static.rb:31:incall'
/home/greg/proj/eDTR_Master/vendor/gems/rack-1.0.1/lib/rack/urlmap.rb:46:in call' /home/greg/proj/eDTR_Master/vendor/gems/rack-1.0.1/lib/rack/urlmap.rb:40:ineach'
/home/greg/proj/eDTR_Master/vendor/gems/rack-1.0.1/lib/rack/urlmap.rb:40:in call' /home/greg/proj/eDTR_Master/vendor/rails/railties/lib/rails/rack/log_tailer.rb:17:incall'
/home/greg/.gem/ruby/1.8/gems/unicorn-0.95.2/lib/unicorn.rb:571:in `process_client'

Print as landscape with middleware

Hello,

I'm using PDFKit on my rails application and I need to set the pdf as landscape but I'm using the middleware.

Is this possible?

I tried this css but doesn't work (maybe wkhtmltopdf issue?):

@page {
  size: landscape; }

Support for multiple pages

I don't see any support for multi-page PDF output files.

For more than trivial one-page PDFs, I would like the ability to begin the creation and call for successive page additions. I would expect headers, footers and page numbers to all be managed in the HTML.

Is this functionality already there? I didn't see anything for it.

Controller action vs middleware result

When I use the middleware, I am able to get my desired result, which is to have my layout, css, javascript, etc. execute and render. However, if I need to do something with the pdf (say, a mailer), I need to do that within a controller action. However, the only way I've seen to handle that is to use render_to_string and use PDFKit to generate the file.

However, when I use render_to_string, it doesn't do what the middleware does. I'm assuming this is because the middleware captures the entire response whereas render_to_string just gives the html. My question is if there is any way that I can use this in a controller action and be able to do use the pdf the way I want. Essentially I just want to be able to get a generated pdf like the middleware does and be able to attach it to a mailer.

defining layout gives nil

Looks like when you define a different layout on your action, pdfkit renders a pdf with content nil .

Tested this on Rails 3 beta 4 using Pdfkit middleware

PDFKit::ImproperSourceError: Improper Source: Stylesheets may only be added to an HTML source

Hi there,

I suddenly get this error on my production site:

PDFKit::ImproperSourceError: Improper Source: Stylesheets may only be added to an HTML source

On my staging and development site everything works fine. Any ideas why this happens only on my production app?

Gem and rails versions are the same (pdfkit: 0.4.6, rails 2.3.5) in all environements.

Help is highly appreciated.
Nico

Generating PDF of protected pages

Hi,

I'm trying to use PDFKit on my Rails2 app but I'm getting an error. I believe it is caused by another middleware, warden, which is used the auth gem Devise.

The response of the request is a 500 error with this body:
Failed to load source for: http://localhost:3000/campanhas/436452125.pdf

On the server (WEBrick), I see:
ActionView::MissingTemplate (Missing template campanhas/show.erb in view path app/views:/Users/felipekk/.bundle/ruby/1.8/gems/devise-1.0.7/app/views):
warden (0.10.7) lib/warden/manager.rb:35:in call' warden (0.10.7) lib/warden/manager.rb:34:incatch'
warden (0.10.7) lib/warden/manager.rb:34:in call' pdfkit (0.3.1) lib/pdfkit/middleware.rb:15:incall'

The page that I'm trying to generate the PDF requires login. I believe PDFKit won't work because wkhtmltopdf won't be able to access the resource. Am I correct or is this being caused by another issue?

Thanks

utf8 handling issue

I'm working on an application that's entirely utf8 based and uses a wide range of non-ascii characters.

When using wkhtmltopdf on the command line my pages are cleanly converted to PDF with the characters render appropriately, but when I request them through my rails app/pdfkit the characters are being mangled (eg. "Tröhler" is becoming "Tröhler")

I'm using Ruby Enterprise Edition 1.8.7 (2010.02 - can't switch to 1.9 yet), I've checked the locale on my system and it's set to en_GB.UTF8. Is there anything else I should be exploring?

Rails 3 - wkhtmltopdf command failed:

Hello,

I have setup PDFKit in my Rails 3 application, using RVM (had to manually copy the wkhtmltopdf binary). When I try to render the PDF version of a page, I get this error:

RuntimeError in AgenciesController#show

command failed: ["lib/wkhtmltopdf/wkhtmltopdf", "--disable-smart-shrinking", "--page-size", "Letter", "--margin-top", "0.75in", "--margin-right", "0.75in", "--margin-bottom", "0.75in", "--margin-left", "0.75in", "--encoding", "UTF-8", "--quiet", "\n.......\n", "-"]

The following is in my applicaition.rb:

    config.middleware.use "PDFKit::Middleware"
    PDFKit.configure do |config|
    config.wkhtmltopdf = 'lib/wkhtmltopdf/wkhtmltopdf' 

    end

An ideas why this is happening? how can I fix it?

In the console, I noticed this message:

 (sometimes it will work just to ignore this error with --ignore-load-errors)

Where do I invoke that switch?
wkhtmltopdf seems to be working fine on the command line, I can do something like "./wkhtmltopdf http://www.google.com google.pdf" and generate a PDF.

Thanks for your help,

Peter

Ubuntu LTS shows wrong host_os in Config::CONFIG

Hi,

i love the simplicity of this program, so i want to help out with issues I've been running into.

http://github.com/jdpace/PDFKit/blob/master/bin/pdfkit#L9

This line returns something different which mucks up the rest of the install process on my Slicehost ubuntu slice using x86_64. Here is some console output.

$ irb
ruby-1.8.7-p249 > require 'rbconfig'
 => true 
ruby-1.8.7-p249 > Config.class
 => Module 
ruby-1.8.7-p249 > Config::CONFIG['host_os']
 => "linux-gnu" 
ruby-1.8.7-p249 > case Config::CONFIG['host_os']
ruby-1.8.7-p249 ?>  when /linux/i
ruby-1.8.7-p249 ?>  'i386'
ruby-1.8.7-p249 ?>  when /x86_64-linux/i
ruby-1.8.7-p249 ?>  'amd64'
ruby-1.8.7-p249 ?>  end
 => "i386" 

What if we used Config::CONFIG['arch'] or Config::CONFIG['build']... which will pull from the build arch of what ruby was built on... and not rely on some sort of label, as host is, or appears to be.

I can write up a patch if you want or pull request... but didn't know if you tried this before or if you had a reason to use 'host_os'?

pdfkit --install-wkhtmltopdf doesn't work well with rvm (no patch included... yet)

Issue

rvm helps you set up and manage several different installs of ruby and multiple sets of different gems under each. This is quite common for Rails 3 web developers to use right now, while they're still maintaining legacy apps on Rails 2.

It does this by maintaining different environment variables and such pointing to different path, gem, binary, lib, include, etc etc etc locations (more than I normally care to know what they all are), and changing them all at a simple command. It does not work with sudo and does not install these in a system location, it installs all these in your home directory in a hidden directory.

the pdfkit wkhtmltopdf install helper assumes a system location for the binary, and requires running ruby under sudo. not a compatible combination for an rvm-ified ruby.

Workaround

Reading the source I figured out how to install the same thing manually for now for my architecture:

  1. downloading latest static binary version from http://code.google.com/p/wkhtmltopdf/downloads/list
  2. uncompressing it if it was compressed (it's not for macos)
  3. copying to system location of /usr/local/bin/wkhtmltopdf

Solutions

  1. One way could be to figure out what environment variables or any other configs Ruby gems uses for such things like binary install locations (that rvm also uses) and use those... I haven't taken the time to figure out what those are yet.
  2. Or maybe there's a way to integrate the wkhtmltopdf binary requirement more into gem installation directly... again haven't taken the time to figure that out yet.

Encoding issues

I'm getting things like "CaptaciÃ3n" on the PDF when I should be getting "Captación". It's ok if I escape everything buy it's a little painful when the website works in perfect utf-8. Any hint on this?

Security issue with shell injection, explanation, patch with specs included

Example of issue

I have a use case where I'm letting some of my registered web site users generate some simple pre-formatted PDFs using some data they've entered. One of the features is that they can enter a page header. If they enter a header of:

some header"; rm -rf / #

then bad things happen. Files get deleted, PDFKit fails to generate a PDF, and some error is printed on standard error by wkhtmltopdf. Underneath this is passed to the header-center parameter, which is quoted and passed through the shell to wkhtmltopdf. PDFKit is not escaping nor dealing with any such "dangerous to shell" characters or sequences in any way.

Potential Solutions

  1. Not PDFKit's fault - web developers should know better than to accept content from users without validating it. True, but there's nothing inherently bad about any of these characters that really shouldn't be allowed in a page header. I can imagine people wanting the double quote character especially, and the way PDFKit is now that causes errors even without considering security. And it's not really necessarily the library user's place to know the underlying implementation to supply their own quoting.
  2. Escape all the "bad to shell" characters in PDFKit. This would work, or seem to... but can you be sure you got them all? Even for future shells that keep adding more features?
  3. Ruby does provide ways to not pass arguments through the shell, when executing external commands. It's not too difficult to use these features, and then there would be no shell involved to interpret any special characters.

My Patch

I've done a patch that uses method 3 above here:

http://github.com/dburry/PDFKit
[email protected]:dburry/PDFKit.git
http://github.com/dburry/PDFKit/commit/f82e6b3d04f510ff2dc0f7a2f0943b409d0e0826

This replaces all calls to #system and #popen with the multi-parameter #system and fork-then-#exec versions that do the same functionality, but don't pass parameters through the shell for interpretation on the shell. This doesn't completely stop the potential for security issues downstream in the wkhtmltopdf executable itself of course, but it completely stops any ability to have any shell injection issues in the PDFKit code that we control.

The fix I've written does alter the behavior of parameters throughout the system. There is no more double-quoting of parameters with spaces, and no more joining everything together into one string before passing it to wkhtmltopdf. It keeps them all in array form now, for passing to #exec or #system.

I've altered all specs necessary to account for this change, and also added a new spec to specifically test for this shell injection issue. This new spec fails on the current head version, and passes on my forked version.

So what does everyone think?

Breaks on placeholders like [page] in :header_center

This breaks:

kit = PDFKit.new(html, :page_size => 'A4', :header_center => "foo [page]")

with "Error: Failed loading page (sometimes it will work just to ignore this error with --ignore-load-errors)".

Works fine without placeholders:

kit = PDFKit.new(html, :page_size => 'A4', :header_center => "foobar")

Also works fine to specify :header_html and get the page number in that file.

Maybe an escaping issue?

no such file or directory

i have been using PDFKit with middleware for awhile, and it works great, but i wanted to give my invoices a custom file name. so now i have this...

 def to_pdf
   @invoice = Invoice.find(params[:id])
   pdf = PDFKit.new(:html, :title => "Invoice_#{@invoice.id}").to_file(invoice_path)
 end

when i hit that controller, i get:
No such file or directory - /en/invoices/1

however if i browse to that url, i see my invoice just fine. any thoughts?

PDFKit usage..

I'm sure this is not a bug and just something I am doing wrong, but I can't seem to figure out how to use PDFKit...

irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'pdfkit'
=> true
irb(main):003:0> PDFKit.new('http://google.com')
NameError: uninitialized constant PDFKit

Very slow pdf generation and missing style/images

I'm running Ubuntu 10.04 server, Passenger 2.1.5, Nginx --with ssl add on, Rails 2.3.8, ruby 1.9.1 and wkhtmltopdf-0.10.0_beta4_static (complied the long way).

When I generate a pdf from PDFkit on rails deployed on the server it takes over a minute to generate the pdf and does not include any of the styles or images. If I use wkhtmltopdf from the command line on that server and attempt to create a pdf from one of the sites run locally, it simply times out at 10% of the first step and suggest using the --load-error-handling ignore. If I include the include the --load-error-handling ignore option it get to 55% of the first step but again it times out and suggest using the --load-error-handling ignore option. From the servers command line I can generate pdfs from any website not hosted locally. One my dev-laptop running OSX I can generate PDFs from the sites hosted on the offending server from the terminal just fine and in development (on the laptop running mongrel) everything performs as it should.

I've tried the PDFkit version of wkhtmltopdf and all the various manual installations with out any change in performance or rendering.This appears to be wkhtmltopdf and Passenger issue but I'm not sure and would really appreciate some help as to where I should start looking for a possible solution.

Thanks

Add blankslate as a dependency

When I first used the gem, after installation:

[macbook] fcoury:~ → ruby test_new.rb
/Users/fcoury/.rvm/rubies/ree-1.8.7-2010.01/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in gem_original_require': no such file to load -- blankslate (MissingSourceFile) from /Users/fcoury/.rvm/rubies/ree-1.8.7-2010.01/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:inrequire'
from /Users/fcoury/.rvm/gems/ree-1.8.7-2010.01/gems/activesupport-2.3.8/lib/active_support/basic_object.rb:21

Installing blankslate fixed it:

[macbook] fcoury:~ → gem install blankslate
Successfully installed blankslate-2.1.2.3
1 gem installed

Probably shouldn't bundle wkhtmltopdf binaries

Hi,

I don't think the binaries should be bundled with this gem. The gem includes 16MB of binaries, 8MB of which I am most definately not going to use, and the other 8MB will only sometimes be usable (when I am on i386 Linux).

I understand the convenience that some users will gain from this being included in the gem, but I would say it is not really best practice. It would be more appropriate to provide instructions on how to install the binary yourself.

wrong architecture dectection when trying to pdfkit --install-wkhtmltopdf

Hi!

I have a MacMini with Ubuntu 10.04 x64, and when I try to launch pdfkit --install-wk it tries to install i386 version; I think because in bin/pdfkit:line 9 you use Config::CONFIG['host_os'] , that in my OS returns 'linux-gnu', and therefore it tilts the switch. I think it'better if you use 'host_cpu', and change the switch into something like this:

def detect_architecture
case Config::CONFIG['host_cpu']
when /x86_64/i
'amd64'
when /x86/i # I don't know which string returns an i386 architecture
'i386'
when /darwin/i
'OS-X.i368'
else
raise "No binaries found for your system. Please install wkhtmltopdf by hand."
end
end

It works for me... I'm sorry, I don't know how to write with markdown syntax!

amd64 arch detection is broken

the pdfkit binary has this code:

def detect_architecture
  case Config::CONFIG['host_os']
  when /x86_64-linux/i
    'amd64'

This does not seem to be the proper way to detect amd64. This is on a console of a amd64 machine:

>> Config::CONFIG['host_os']
=> "linux-gnu"
>> Config::CONFIG['arch']
=> "x86_64-linux"

Engine Yard and pdfkit --install-wkhtmltopdf problem && solution

so, the comand

pdfkit --install-wkhtmltopdf

This command, for some reason, does not install wkhtmltopdf as an 'executable' binary (whatever the technical term is). No, it only installs it as:

file /usr/local/bin/wkhtmltopdf => /usr/local/bin/wkhtmltopdf: data

WTF is data? but anyways, here is a solution that works if you are in a bind and need it to just work for now, whilst we get it fixed. (I'll add to the wiki too, cause I don't enjoy that entry so much for the engineyard)
Start with:
cd /usr/local/bin/
If you have ran the pdfkit --install-wkthmlpdf already and it isn't working do:
sudo rm wkhtmltopdf
Now do:
curl http://wkhtmltopdf.googlecode.com/files/wkhtmltopdf-0.10.0_beta5-static-i386.tar.lzma | lzcat - | tar xfv -
sudo mv wkhtmltopdf-i386 wkhtmltopdf

That should get you up and running.

When you do
$ file wkhtmltopdf-i386
=> wkhtmltopdf-i386: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, stripped

Notice that you don't see :data, so we can curl the correct file, but somehow it gets botched up and becomes a data file.

smart-shrinking option

In some complex cases, disabled smart-shrinking disables hyperlinks. Enable option by default.

Problem customizing rendering. Can't render in action

This is a two-part issue that is related.

I got PDFKit to work by using it as middleware. However, when I do that, I don't know of any way to have a per-action customization. In one action I might want it Landscape but the default be Portrait. Other configurations like header/footer things might need to change on a per-action basis. Is there a way to do this? I don't think so if it is running as middleware.

I would like to render from any given action. But I can't. My problem is related to this wkhtmltopdf issue (http://code.google.com/p/wkhtmltopdf/issues/detail?id=152). If I pass a URL to the process, it won't work because the content is behind a login which requires a cookie. Also, because in development it is single-threaded, the process just hangs.

My alternative was to render the action to get the HTML and pass that. However, I can't do that either because it would cause the "double-render" in an action problem.

How can I get per-action customization and return the PDF in the same request? Is there a way?

Sample code I want:

  def list
    @employees = Employee.active.scoped(:order => 'first_name ASC')
    respond_to do |format|
      format.html  # list.html.erb
      format.pdf { render :text => render_report_to_pdf() }
    end
  end
  private
  def render_report_to_pdf()
    report_request = request.params
    # Delete the "format" entry from the hash. That is just used to determine PDF printing.
    report_request.delete(:format)
    kit = PDFKit.new(url_for(report_request), print_settings)
    # add stylesheets here....
    kit.to_pdf
  end

Security fix broke non-string parameter values (patch and specs included)

Issue

The security fix I recently submitted (see #16) broke the ability to send non-string parameter values to PDFKit#new.

This was reported in the comments by JackDanger here: http://github.com/jdpace/PDFKit/commit/f82e6b3d04f510ff2dc0f7a2f0943b409d0e0826

Workaround

In the mean time a workaround could be to make sure you convert all your parameter values to strings before sending them to PDFKit. Example, change:
pdfkit = PDFKit.new('html', :header_spacing => 1)
to:
pdfkit = PDFKit.new('html', :header_spacing => '1')

Fix

This is now fixed by adding the appropriate #to_s in the right place to make it behave like it used to. Appropriate specs modified/added. New pull request submitted.

You can see my fix here:
http://github.com/dburry/PDFKit/commit/37864e09187e9e933b2264d1c0e0314734022ca7

command failed: /usr/local/bin/wkhtmltopdf

hi everybody,

i am having issue as following,

"command failed: /usr/local/bin/wkhtmltopdf--margin-right0.75in--page-sizeA4--margin-top0.75in--margin-bottom0.75in--disable-smart-shrinking--encodingUTF-8--margin-left0.75in--quiet--"

actually i am working on ubuntu version 10.04. everything works fine. but one of my team mate using version 9.10 and getting above exception. when i went through the source its raising from pdfkit.rb file in the following line
raise "command failed: #{command}" if result.to_s.strip.empty?. that means the result is empty(result = pdf.gets(nil)).

Please can you help on this issue to overcome as soon as possible?

Thanks
Nishandan

rails middleware install

I have:

config.gem "pdfkit"

require 'pdfkit'
config.middleware.use PDFKit::Middleware

Now I am getting:

.gem/ruby/1.8/gems/builder-2.1.2/lib/builder/xchar.rb:14:in check_for_name_collision': Name Collision: Method 'to_xs' is already defined in String (RuntimeError) from /home/greg/.gem/ruby/1.8/gems/builder-2.1.2/lib/builder/xchar.rb:21 from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:ingem_original_require'
from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in require' from /home/greg/.gem/ruby/1.8/gems/builder-2.1.2/lib/builder/xmlbase.rb:113 from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:ingem_original_require'
from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in require' from /home/greg/.gem/ruby/1.8/gems/builder-2.1.2/lib/builder/xmlmarkup.rb:14 from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:ingem_original_require'
from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in require' from /home/greg/.gem/ruby/1.8/gems/builder-2.1.2/lib/builder.rb:12 from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:ingem_original_require'
from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in require' from /home/greg/proj/eDTR_Master/vendor/rails/activesupport/lib/active_support/vendor.rb:9 from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:ingem_original_require'
from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in require' from /home/greg/proj/eDTR_Master/vendor/rails/activesupport/lib/active_support.rb:54 from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:ingem_original_require'
from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in require' from /home/greg/proj/eDTR_Master/vendor/rails/actionpack/lib/action_controller.rb:25 from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:ingem_original_require'
from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in require' from ./config/../vendor/rails/railties/lib/initializer.rb:941:inmiddleware'
from ./config/environment.rb:90

popen("-") is unimplemented

Hi,

I do my first steps with pdfkit. I installed "pdfkit (0.4.6)" and wkhtmltoimage-0.10.0_beta5 on linux.

When I call

send_data(kit.to_pdf, :filename => "/tmp/verwertung.pdf", :type => 'application/pdf')

I get an NotImplementedError in my controller which says:

popen("-") is unimplemented.

Is this problem known and can how can I solve it?
The same problem occurs with: wkhtmltopdf-0.9.9

Best regards
Thomas

Can't print a pdf - no error - no return from webserver

Hi,

I use the pdfkit like this:
kit = PDFKit.new(my_object_url(@object.id))
send_data(kit.to_pdf, :filename => filename, :type => 'application/pdf')

After clicking my pdf button, I can see that the wkhtmltopdf command is released with the right arguments (i checked the process). Then the webserver is in idle state and nothing happens anymore.
So, i tried to use the command with the same arguments (except --quiet, and - at the end, i replaced with a filename like test.pdf) and this was working (if the server is running and not in that curious idle state after clicking pdf print).

So, I tried the kit.to_file(filename), it doesn't work too. That's normal because the to_file method calls the to_pdf method. But i saw the argument isn't right. The argument - for wkhtmltopdf won't be replaced with the given filename. In my case, maybe that will be the solution.

Then I would try with stylesheet like this:
kit.stylesheets << 'path/to/my/file.css'
But an error was occured: Improper Source: Stylesheets may only be added to an HTML source.
I know why this is. My url looks like: http://localhost:3000/my_object/1547895134
and pdfkit checks the file ending. So that can't work.

Thanks for your help

Landscape size for the PDF

Hi,

Thanks for the Gem.
Not really an issue but is there any way to force landscape mode for the PDF. I use a print media css file and unfortunately @page { size: landscape;} does not work...

caches_action doesn't play nice with middleware

I have a rails 2.3.5 app running ruby 1.8.7 on Ubuntu server 10.04.

All works well until I use caches_action in my controller, then use the pdf format to invoke the middleware, at which point I receive the following message:

Processing PeopleController#show (for 90.195.62.70 at 2010-09-01 19:55:00) [GET]
Parameters: {"action"=>"show", "id"=>"2", "controller"=>"people"}
Filter chain halted as [#<ActionController::Filters::AroundFilter:0xb6251500 @Identifier=nil, @method=#Proc:0xb6463960@/home/guy/cv/releases/20100901195419/vendor/rails/actionpack/lib/action_controller/caching/actions.rb:64, @kind=:filter, @options={:unless=>nil, :only=>#<Set: {"show", "index"}>, :if=>nil}>] did_not_yield.
Completed in 11ms (View: 0, DB: 1) | 200 OK [http://cv.weblitz.me.uk/people/2]
/!\ FAILSAFE /!\ Wed Sep 01 19:55:00 +0000 2010
Status: 500 Internal Server Error
can't modify frozen string
/var/lib/gems/1.8/gems/pdfkit-0.4.5/lib/pdfkit/middleware.rb:45:in gsub!' /var/lib/gems/1.8/gems/pdfkit-0.4.5/lib/pdfkit/middleware.rb:45:intranslate_paths'
/var/lib/gems/1.8/gems/pdfkit-0.4.5/lib/pdfkit/middleware.rb:20:in call' /home/guy/cv/releases/20100901195419/vendor/rails/actionpack/lib/action_controller/string_coercion.rb:25:incall'
/var/lib/gems/1.8/gems/rack-1.0.1/lib/rack/head.rb:9:in call' /var/lib/gems/1.8/gems/rack-1.0.1/lib/rack/methodoverride.rb:24:incall'
/home/guy/cv/releases/20100901195419/vendor/rails/actionpack/lib/action_controller/params_parser.rb:15:in call' /home/guy/cv/releases/20100901195419/vendor/rails/actionpack/lib/action_controller/session/abstract_store.rb:122:incall'
/home/guy/cv/releases/20100901195419/vendor/rails/activerecord/lib/active_record/query_cache.rb:29:in call' /home/guy/cv/releases/20100901195419/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:34:incache'
/home/guy/cv/releases/20100901195419/vendor/rails/activerecord/lib/active_record/query_cache.rb:9:in cache' /home/guy/cv/releases/20100901195419/vendor/rails/activerecord/lib/active_record/query_cache.rb:28:incall'
/home/guy/cv/releases/20100901195419/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb:361:in call' /home/guy/cv/releases/20100901195419/vendor/rails/actionpack/lib/action_controller/failsafe.rb:26:incall'
/var/lib/gems/1.8/gems/rack-1.0.1/lib/rack/lock.rb:11:in call' /var/lib/gems/1.8/gems/rack-1.0.1/lib/rack/lock.rb:11:insynchronize'
/var/lib/gems/1.8/gems/rack-1.0.1/lib/rack/lock.rb:11:in call' /home/guy/cv/releases/20100901195419/vendor/rails/actionpack/lib/action_controller/dispatcher.rb:106:incall'
/var/lib/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/rack/request_handler.rb:92:in process_request' /var/lib/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/abstract_request_handler.rb:207:inmain_loop'
/var/lib/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/railz/application_spawner.rb:441:in start_request_handler' /var/lib/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/railz/application_spawner.rb:381:inhandle_spawn_application'
/var/lib/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/utils.rb:252:in safe_fork' /var/lib/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/railz/application_spawner.rb:377:inhandle_spawn_application'
/var/lib/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/abstract_server.rb:352:in __send__' /var/lib/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/abstract_server.rb:352:inmain_loop'
/var/lib/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/abstract_server.rb:196:in start_synchronously' /var/lib/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/abstract_server.rb:163:instart'
/var/lib/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/railz/application_spawner.rb:222:in start' /var/lib/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/spawn_manager.rb:253:inspawn_rails_application'
/var/lib/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/abstract_server_collection.rb:126:in lookup_or_add' /var/lib/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/spawn_manager.rb:247:inspawn_rails_application'
/var/lib/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/abstract_server_collection.rb:80:in synchronize' /var/lib/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/abstract_server_collection.rb:79:insynchronize'
/var/lib/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/spawn_manager.rb:246:in spawn_rails_application' /var/lib/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/spawn_manager.rb:145:inspawn_application'
/var/lib/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/spawn_manager.rb:278:in handle_spawn_application' /var/lib/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/abstract_server.rb:352:insend'
/var/lib/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/abstract_server.rb:352:in main_loop' /var/lib/gems/1.8/gems/passenger-2.2.15/lib/phusion_passenger/abstract_server.rb:196:instart_synchronously'
/var/lib/gems/1.8/gems/passenger-2.2.15/bin/passenger-spawn-server:61

binaries should be statically compiled

When running the binary on x64 linux machines it breaks depending on other libs.

$ ./wkhtmltopdf-linux-i386-0-9-9
./wkhtmltopdf-linux-i386-0-9-9: error while loading shared libraries: libfontconfig.so.1: cannot open shared object file: No such file or directory

The binaries should be statically compiled, so they can be run.

PDF Kit produces error due to wrong source type recoginition

I reported this earlier, but cant find theissue anymore. In my production setup pdfkit doesn't recognize my pdf source type properly which leads to an error.

I generate the pdf like so in a view helper:

html = render(template, :layout => 'pdf.html.haml').gsub('/images/', RAILS_ROOT + '/public/images/')
kit = PDFKit.new( html, :margin_top => '0.24in',
:margin_right => '0.25in',
:margin_bottom => '0.3in',
:margin_left => '0.25in')
kit.stylesheets << RAILS_ROOT + '/public/stylesheets/site.css'
send_data(kit.to_pdf, :filename => filename.gsub(/(/||:)/, ''), :type => 'application/pdf')

Unfortunately pdf kit thinks that the source is a url or file instead of a pdf. But only in production.
I don't know why. When I make the function html? always return true the pdf generation works fine.

Best Regards,
Nico

ignoring configuration

I have been fooling around with this problem on and off for a couple of weeks now. On my dev system (OS X 10.6.4) PDFKit works w/o issue. When I run the same code on my server (CentOS release 5.4 (Final)) the generated pdf always comes out a page size of 33in x 44in. I get the same thing on ver. 0.4.1 and 0.4.6.

Any ideas as to what might be going on?

Manage margins, footer, header with middleware

I have installed, and is a great work, the reports looks awesome. But still can put a header, footer, manage the margins, and numbers on pages, in the perfect way "page # of #pages".
I not tested in production yet, but i will start using a lot this piece of work.
thanks.

Avoid page breaks in table cells

Not even sure this is an issue for PDFKit - but not sure where to ask.

I have this running under rails3 just fine. But - it will insist on pagebreaking halfway thru a table row with text appearing half on one page half on the next (and here I mean the same line of text - half the letters on one page - the bottom half on the next page).

I've tried setting page-break-inside: avoid; on tr, td and th to no help (print media stylesheet).

Any tips?

Middleware breaks with ruby 1.8.6

With the 0.4.0 version:

/!\ FAILSAFE /!\  Mon Jul 19 09:27:40 +0200 2010
  Status: 500 Internal Server Error
  undefined method `bytes' for #<String:0x105ac78c0>
    /Users/allop/.rvm/gems/ruby-1.8.6-p399/gems/pdfkit-0.4.0/lib/pdfkit/middleware.rb:30:in `call'
    /Users/allop/.rvm/gems/ruby-1.8.6-p399/gems/haml-3.0.10/lib/sass/plugin/rack.rb:41:in `call'

naming of gem / lib

plase rename the lib to pdfkit.rb so there is no extra gem 'pdfkit', :require=>'PDFKit' needed
(naming both pdf_kit would be the standard-conform/best solution imo)

Engine Yard Appcloud wiki entry???

Is it possible to show a code entry on how to include these non ruby libs in an app?

this is what it says, but doesn't show how to do it:

Use on Engine Yard AppCloud

Be sure to identify Unix packages x11-libs/libXext and x11-libs/libXrender as dependencies of your application that uses PDFKit.

PDFKit hangs rails server

Hi,

I use pdfkit 0.4.2 (also try on 0.4.0) with middleware configuration
and when I try generate view with jquery.datatable it hagns and don't respond on any action.
I try debug code and I figure out that problem is here:

[56, 65] in /usr/lib/ruby/gems/1.8/gems/pdfkit-0.4.2/lib/pdfkit/pdfkit.rb
56
57 def to_pdf
58 append_stylesheets
59
60 pdf = Kernel.open('|-', "w+")
61 exec(*command) if pdf.nil?
62 pdf.puts(@source.to_s) if @source.html?
63 pdf.close_write
=> 64 result = pdf.gets(nil)

65 pdf.close_read

it still wait for something (maybe some extra input)
Only pages with jqeury DataTable makes problem other pages are ok.

Problem is only when I try use pdfkit in middleware configuration in normal mode all views works.

Give me know if I can provide some extra information about this problem.

Thanks a lot of any suggestion

Send :format to page

I need to render a page a little bit diferent when it is html or pdf... So, there is a way to send a addicional parameter to the erb? like params[:format] == pdf ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.