wkhtmltopdf

Swift Vapor Travis

用于使用 wkhtmltopdf 将 HTML(Leaf 或其他)转换为 PDF 文件的 Vapor 4 库。

入门指南

在您的 Package.swift 文件中添加以下内容

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

📘 概述

首先,安装 wkhtmltopdf。 此库已在 0.12.5 版本上进行测试。 在 Document 初始化程序中指定 wkhtmltopdf 的位置。 默认位置是 /usr/local/bin/wkhtmltopdf。 运行它以确保它及其所有依赖项都已正确安装。

要创建 PDF,请创建并配置 Document,添加一个或多个 Page,然后调用 generatePDF(on: threadPool, eventLoop: eventLoop)。 这是一个使用 Vapor 的完整示例

import wkhtmltopdf

func pdf(_ req: Request) -> EventLoopFuture<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 = 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)
            )
        }
    }
}

在您的 Leaf 文件中,您可能需要加载资源,例如图像、CSS 样式表和 Web 字体。 将这些资源存储在您的 Public 目录中,您可以使用 #(publicDir) 标签将 wkhtmltopdf 指向此目录。

如果您想使用非公共目录,可以使用 #(workDir) 标签来渲染 Droplet 的工作目录。 当然,您始终可以硬编码绝对路径来代替。

这是一个工作示例 Leaf 文件,它加载 CSS 和图像。 它使用 <base> 标签来告知 wkhtmltopdf 默认在 Public 目录中查找。

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

缩放校准

在不同的平台上,wkhtmltopdf 可能需要不同的缩放级别,以确保 HTML 中的 1 毫米等于 PDF 中的 1 毫米。 默认缩放级别为 1.3,这已被发现在 Linux 上运行良好,但如果您需要不同的缩放级别,请在进行任何渲染之前设置静态属性 Document.zoom

为什么使用页面?

WebKit 在渲染分页符方面不是很出色。 如果它适用于您的设计,一个好的替代方案是将 PDF 文档拆分为单独的 HTML 文件。 wkhtmltopdf 将会把它们全部合并并返回一个单独的 PDF 文档。