DEV Community

Cover image for Images not showing up using PDFKit and WkHTMLtoPDF
chowderhead
chowderhead

Posted on • Edited on

Images not showing up using PDFKit and WkHTMLtoPDF

Photo cred: Brigitta Schneiter

Assumptions:

  • you use WkHTMLtoPDF on your app to generate PDF documents
  • you are piping in images (via URL) to a pregenerated HTML template

The Problem:

  • The way that WkhtmltoPFf Opens assets on a generated PDF document is for the most part under the hood. a black box so to say.
  • This can cause issues of Images not appearing in your generated PDF documents if they are not stored locally on the server.

The Solution:

  1. Download image manually
  2. Convert image to base64 string
  3. Manually insert into HTML template.

Our setup:

  • we are using a ruby on rails backend , loading the PDF Kit gem
  • Our front end is uploading images and sending them to our RAILS API to generate the HTML document
  • Our controllers use the uploaded images to generate the HTML document that gets fed into PDF Kit

Helper in controller:
doc_helper.rb

def generate_html_template(image_url)

    "<!DOCTYPE html>
    <html>
        <head>
        </head>
        <body>
        ... some html template
        <img src='#{image_url}'/>
        </body>
    </html>
    "
end
Enter fullscreen mode Exit fullscreen mode

This helper creates a temporary HTML document, and I can feed this into PDF KIT

There are ton of different ways to do this, but to illustrate a point ill do it this way.

Our issue was that the the image url that we were sending into this was coming from a protected AWS s3 bucket, on top of that it had a cloud front signature that was causing all sorts of problems for us. WkHTMLtoPDF was not able to render the image when it was parsing the html

How we solved it:

application.rb

require 'rails/all'
require 'base64'
Enter fullscreen mode Exit fullscreen mode

doc_helper.rb

def download_image(url)
    return 'data:image/png;base64,' + Base64.encode64(open(url) { |io| io.read })
end

def generate_html_template(image_url)

    "<!DOCTYPE html>
    <html>
        <head>
        </head>
        <body>
        ... some html template
        <img src='#{download_image(image_url)}'/>
        </body>
    </html>
    "
end

# credit: https://stackoverflow.com/questions/1547008/how-to-encode-media-in-base64-given-url-in-ruby
Enter fullscreen mode Exit fullscreen mode

In the same line we use open() to read the file on our rails file, and then we convert is using the Base64 module.

After this we just inject it back into the template, this way WKHTMLtoPDF doesnt have to open the file from a source, it just reads it as a Base64 string!

Let me know if you have any issues implementing this fix!

Top comments (5)

Collapse
 
marcusatlocalhost profile image
Marcus

I came to the same conclusion when I tried to load images with weird url encoding or query strings (google filestorage) or images that needed to be accessed with auth headers.
Downloading the file to the server and base64 encode it was the way to go.

Has anybody successfully used the --image-quality switch in wkhtmltopdf?

Collapse
 
marcusatlocalhost profile image
Marcus

I finally found out, that in my specific case, images were missing dpi information and wkhtmltopdf seems to just skipped those and didn't optimize them: github.com/wkhtmltopdf/wkhtmltopdf...

Collapse
 
kiransiluveru profile image
kirankumar

do we have any wkhtmltopdf like plugin for client-side

Collapse
 
adampal profile image
adampal

Thanks for the great solution! Worked perfectly for me and saved me hours of trying to figure out why my images weren't showing in PDFs :)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.