Swiftpack.co - Package - vapor-community/wkhtmltopdf


Swift Vapor Travis

Vapor 3 library for converting HTML (Leaf or otherwise) into PDF files using wkhtmltopdf.

Getting Started

Add the following in your Package.swift file

.package(url: "https://github.com/vapor-community/wkhtmltopdf.git", from: "2.0.0"),

📘 Overview

First, install wkhtmltopdf. This library is tested on version 0.12.4. Specify the location of wkhtmltopdf in the Document initialiser. The default is /usr/local/bin/wkhtmltopdf. Run it to ensure it and any dependencies are installed correctly.

To create a PDF, create and configure a Document, add one or more Pages, and then call generatePDF(on: Request). Here is a full example:

import wkhtmltopdf

func pdf(_ req: Request) -> Future<Response> {
     // Create document. Margins in mm, can be set individually or all at once.
    // If no margins are set, the default is 20mm.
    let document = Document(margins: 15)
    // Create a page from an HTML string.
    let page1 = Page("<p>Page from direct HTML</p>")

    // Create a page from a Leaf template.
    let page2 = try req.view().render("page_from_leaf_template")

    // Create a page from a Leaf template with Context variables.
    let page3 = try req.view().render("page_from_leaf_template", [ "firstName": "Peter",
                                                               "lastName": "Pan"])
    let pages = [ page2, page3].flatten(on: req)
        .map { views in
            return views.map { Page($0.data) }

    return pages.flatMap { pages in
        // Add the pages to the document
        document.pages = [page1] + pages
        // Render to a PDF
        let pdf = try document.generatePDF(on: req)
        // Now you can return the PDF as a response, if you want
        return pdf.map { data -> Response in
            let http = HTTPResponse(status: .ok,
                                    headers: HTTPHeaders([("Content-Type", "application/pdf")]),
                                    body: data)
            return Response(http: http,
                            using: req)

In your Leaf file, you may want to load resources such as images, CSS stylesheets and web fonts. Store these in your Public directory, and you can direct wkhtmltopdf to this directory using the #(publicDir) tag.

If you'd like to use a non-public directory, you can use the #(workDir) tag to render the Droplet's working directory. Of course, you can always hard-code an absolute path instead.

Here is a worked example Leaf file which loads CSS and images. It uses the <base> tag to tell wkhtmltopdf to look in the Public directory by default.

<!DOCTYPE html>
    <base href='#(publicDir)'>
    <link href='css/pdf.css' rel='stylesheet'>
    <img src='img/welcome.jpg'>
    <p>Welcome #(firstName) #(lastName)!</p>

Zoom calibration

Across different platforms, wkhtmltopdf can require different zoom levels to ensure that 1 mm in HTML equals 1 mm in PDF. The default zoom level is 1.3, which has been found to work well on Linux, but if you need a different zoom level set the static property Document.zoom before doing any rendering.

Why Pages?

WebKit is not very good at rendering page breaks. If it works with your design, a good alternative is to split the PDF document into separate HTML files. wkhtmltopdf will combine them all and return a single PDF document.


Stars: 26
Help us keep the lights on


Used By

Total: 0


2.0.1 - Aug 19, 2019

Supports setting the location of the wkhtmltopdf binary, for platforms such as Heroku. Many thanks to @maciejtrybilo for making this change.

2.0.0 - May 13, 2019

Update to Vapor 3. Many thanks to @kimdv for making this change.

1.1.0 - May 18, 2017

Update to Vapor 2.

Minor API changes. We now use Vapor's Bytes instead of Foundation's Data to make interoperating with Vapor easier, e.g. when returning responses. See the README for new usage.

It is also possible to set the default zoom level for the wkhtmltopdf binary.

If you need to use Vapor 1, stay with version 1.0.0 of this package.

1.0.0 - Apr 7, 2017

Swift 3.1, Vapor 1.5

0.1.0 - Feb 17, 2017

First release. Functional and used in production.

Swift 3.0, Vapor 1.5