ChartKick charts do not show when rendering to PDF

2019-02-24 21:23发布

问题:

I am using Rails 4, Wicked_PDF and Chartkick Gem's
For Google Charts I use:

<%= javascript_include_tag "//www.google.com/jsapi", "chartkik" %>

The html view comes up with charts and everything as expected. When I append .pdf to the url the pdf document shows in the browser but the ChartKick charts do not show.
The following error appears where the chart should be:

Error Loading Chart: No adapter found

I have found the following online in the PDFKit documentation.

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.

I am assuming that wkhtmltopdf is not finding the link to the charts, but I am not sure how to fix this.
Does anyone have a suggestion?

I found this link:
Render jQuery in wicked_pdf

Where Unixmonkey helps FattRyan to solve this for Highcharts.

Can anyone help how to set this wicked_pdf_javascript_include_tag so that Wicket_PDF will accept charts from Chartkick using Google charts?

回答1:

You have to specify a protocol http or https when referencing to a CDN inside the pdf layout.

Also chartkick is served via the assets pipeline, so use wicked_pdf_javascript_include_tag instead.

Replace this line:

<%= javascript_include_tag "//www.google.com/jsapi", "chartkik" %>

With this:

<%= javascript_include_tag "https://www.google.com/jsapi" %>
<%= wicked_pdf_javascript_include_tag "chartkick" %>

That's how I do it in a project of mine.

Cheers.



回答2:

I struggled with this for a bit and the other answers were only partially useful for me. I wanted to provide more detail for anyone in the future:

The 4 major things I did to fix this for us were:

(1) Not using the middleware approach and instead using one off ruby embedded pdfs based off of a PDF layout you create

   #Example layout file
   #app/views/layout/pdf.pdf.rb

   <!DOCTYPE html>
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <%= wicked_pdf_stylesheet_link_tag "print" %> #print specific stylesheet
        <%= yield :head %>
      </head>
      <body>
        <h1>PDF Report</h1>
        <%= yield %>
      </body>
    </html>

(2) using wicked_pdf's asset helpers to load ONLY the javascript we needed on those pages for assets we store in the app (all CDN based assets can be loaded with a normal javascript_include_tag)

#Example page template for a PDF you're downloading
#app/views/users/profile.pdf.erb

<% content_for :head do %>
  <%= javascript_include_tag "some_cdn.com" %>
  <%= wicked_pdf_javascript_include_tag "chartkick" %>
<% end %>

<p>All your pages content</p>

(3) using the javascript_delay option

#Use it universally from the initializer or on the specific PDF rendering in the controller
#config/initializers/wicked_pdf.rb
WickedPdf.config = {
  javascript_delay: 3000,
  other_options...
}

(4) pass the "discrete" axis option otherwise we only saw the axis and no data for time based charts (line/area/etc.)

#In the above template, wherever you render your chart
#app/views/users/profile.pdf.erb

<% content_for :head do %>
  <%= javascript_include_tag "some_cdn.com" %>
  <%= wicked_pdf_javascript_include_tag "chartkick" %>
<% end %>

<%= area_chart @data_retriever.time_based_data, discrete: true %>
<%= pie_chart @data_retriever.other_data %> # the default is discrete: false so no need for another option


回答3:

Add the following to the top of the view your trying to convert to a pdf:

  <%= wicked_pdf_javascript_include_tag "application", "chartkick" %>


回答4:

I got it to work with Alex Villa's answer and from the answer to a similar question by installing the latest wkhtmltopdf version then specifying the javascript_delay option in the controller in step (3):

respond_to do |format|
  format.html
  format.pdf do
    render pdf: "filename",
    javascript_delay: 3000,
    template: 'template_path.pdf.erb',
    layout: 'pdf.html'
  end
end