Katelynn ruan
Katelynn ruan

Reputation: 332

Rails 4 pdfkit failed converting chartkick graph to pdf

I am using Rails 4

I followed instruction from https://github.com/pdfkit/pdfkit

In controller I have

respond_to do |format|
                    format.html {render layout:'application'}
                    format.csv {send_data @testdatares.to_csv}
                    format.pdf {
                            html = render_to_string(:layout => 'application' , :action => "testpage.html.erb");
                            kit = PDFKit.new(html);
                            kit.stylesheets << "#{Rails.root}/app/assets/stylesheets/application.css";
                            send_data(kit.to_pdf, :filename => "some_name.pdf", :type => 'application/pdf')
                    }
            end

In application.html.erb I have

<!DOCTYPE html>
<html>          
<head>                  
<title>STNEW</title>
<%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= javascript_include_tag "http://www.google.com/jsapi", "/usr/local/lib/ruby/gems/2.1.0/gems/chartkick-1.3.2/app/assets/javascripts/chartkick",media:'all' %>
<%= csrf_meta_tags %>
</head>       

Please note that I already used absolute path to chartkick.js

Now in html the chartkick contents were perfectly displayed.

But in the pdf file generated by pdfkit all chartkick contents were shown as "loading", while text was correctly shown

Googled around but found no answer

Upvotes: 1

Views: 1764

Answers (2)

dg6
dg6

Reputation: 480

While WickedPDF probably works just fine, there's a workaround to making PDFKit work as well. You just need to point wkhtmltopdf to the absolute path of the .js file, similar to the approach used for including the CSS files:

html = render_to_string(:layout => 'application' , :action => "testpage.html.erb")

html.gsub!("/assets", "#{Rails.root}/public/assets")

kit = PDFKit.new(html)
kit.stylesheets << "#{Rails.root}/app/assets/stylesheets/application.css"
send_data(kit.to_pdf, :filename => "some_name.pdf", :type => 'application/pdf')

The pre-compiled chartkick.js will be in the /public/assets folder and wkhtmltopdf is able to locate it there.

Upvotes: 0

Katelynn ruan
Katelynn ruan

Reputation: 332

Finally, after 3 days of search, trails and error, I found solution for this

first of all, I have to use wicked_pdf rather than pdfkit because the former provides two important helper functions

wicked_pdf_stylesheet_link_tag
wicked_pdf_javascript_include_tag

then I must use these two helper to include stylesheet and javascript, like this

<%= wicked_pdf_stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
<%= wicked_pdf_javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= javascript_include_tag "http://www.google.com/jsapi"%>
<%= wicked_pdf_javascript_include_tag 'chartkick'%>

The difference between javascript_include_tag and wicked_pdf_javascript_include_tag is that the latter will write all original java code into the html file. This is important because wkhtmltopdf, the core of wicked_pdf, does not know where to find the js and css assets. These assets are located at someplace like /usr/local/lib/ruby/gems/2.1.0/gems/ (yours might be different), but only your rails app know where it is

note that for

<%= javascript_include_tag "http://www.google.com/jsapi"%>

you can't and don't need wicked_pdf_javascript_include_tag.

Here the most most important thing come. wicked_pdf (and also pdfkit) will instruct you to install gem wkhtmltopdf-binary , which has the latest version 0.9.9 and then simply call something like this

format.pdf {render pdf :"test",layout:'application',template:'stinfos/testpage.html.erb'}         

to generate pdf. This ONLY works for html without chartkick or highchart component. In the PDF file generated, the chartkick or highchart figures will only show as "loading"

To solve this, you need to remove the wkhtmltopdf-binary gem by running

gem uninstall wkhtmltopdf-binary

in your rails app root

Then download the latest version of wkhtmltopdf from http://wkhtmltopdf.org/downloads.html

for me the precompiled version work http://downloads.sourceforge.net/project/wkhtmltopdf/0.12.1/wkhtmltox-0.12.1_linux-trusty-amd64.deb

and install

dpkg -i wkhtmltox-0.12.1_linux-trusty-amd64.deb

most likely it will be located here /usr/local/bin/wkhtmltopdf

if not, change the config/initializers/wicked_pdf.rb

:exe_path => '/yourpath/wkhtmltopdf'

Then add javascript_delay:2000 to the format.pdf

 format.pdf {render pdf:"test",javascript_delay:2000,
 layout:'application',template:'stinfos/testpage.html.erb'}

Then you should see the chartkick figures show up in the pdf generated. If not, use a larger delay time.

Note that javascript_delay option is not available for wkhtmlpdf below version 0.10

Upvotes: 7

Related Questions