https://github.com/vapor-community/wkhtmltopdf
Generate and return PDFs from Vapor views
https://github.com/vapor-community/wkhtmltopdf
pdf vapor vapor-provider wkhtmltopdf
Last synced: 6 months ago
JSON representation
Generate and return PDFs from Vapor views
- Host: GitHub
- URL: https://github.com/vapor-community/wkhtmltopdf
- Owner: vapor-community
- Created: 2017-02-17T05:57:03.000Z (over 8 years ago)
- Default Branch: main
- Last Pushed: 2025-03-28T15:44:05.000Z (7 months ago)
- Last Synced: 2025-03-28T16:28:46.341Z (7 months ago)
- Topics: pdf, vapor, vapor-provider, wkhtmltopdf
- Language: Swift
- Homepage:
- Size: 46.9 KB
- Stars: 61
- Watchers: 6
- Forks: 11
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# wkhtmltopdf


Vapor 4 library for converting HTML (Leaf or otherwise) into PDF files using
[wkhtmltopdf](http://wkhtmltopdf.org/).## Getting Started
Add the following in your `Package.swift` file
```Swift
.package(url: "https://github.com/vapor-community/wkhtmltopdf.git", from: "4.0.0"),
```## 📘 Overview
First, install [wkhtmltopdf](http://wkhtmltopdf.org/downloads.html). This
library is tested on version 0.12.5. 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 `Page`s,
and then call `generatePDF(on: threadPool, eventLoop: eventLoop)`. Here is a full example using Vapor:```Swift
import wkhtmltopdffunc pdf(_ req: Request) -> EventLoopFuture {
// 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("Page from direct HTML
")// Create a page from a Leaf template.
let page2 = req.view.render("page_from_leaf_template")// Create a page from a Leaf template with Context variables.
let context = ["firstName": "Peter", "lastName": "Pan"]
let page3 = req.view.render("page_from_leaf_template", context)let pages = [ page2, page3]
.flatten(on: req.eventLoop)
.map { views in
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 = document.generatePDF(on: req.application.threadPool, eventLoop: req.eventLoop)
// Now you can return the PDF as a response, if you want
return pdf.map { data in
return Response(
status: .ok,
headers: HTTPHeaders([("Content-Type", "application/pdf")]),
body: .init(data: data)
)
}
}
}
```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
`` tag to tell `wkhtmltopdf` to look in the Public directory by default.```HTML
![]()
Welcome #(firstName) #(lastName)!
```
### 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.