用于使用 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 文档。