Swift 库,用于通过 wkhtmltopdf cli 从 Leaf 模板和/或网页构建 pdf 文件数据。专为 Vapor 3 构建,并使用 Vapor 本身(在底层使用 Swift-NIO)和 Leaf 作为模板。
首先,安装 wkhtmltopdf
本身。
可以自动安装它
sudo apt-get update
sudo apt-get install wkhtmltopdf
或者手动安装,例如使用 从最新版本 下载的 deb
文件
wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.xenial_amd64.deb
sudo dpkg -i wkhtmltox_0.12.5-1.xenial_amd64.deb
sudo apt-get -f install
或者手动安装,例如使用 从最新版本 下载的 tar.xz
文件
wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.4/wkhtmltox-0.12.4_linux-generic-amd64.tar.xz
tar -xvf wkhtmltox-0.12.4_linux-generic-amd64.tar.xz
cd wkhtmltox/bin/
sudo mv wkhtmltopdf /usr/bin/wkhtmltopdf
sudo mv wkhtmltoimage /usr/bin/wkhtmltoimage
sudo chmod a+x /usr/bin/wkhtmltopdf
sudo chmod a+x /usr/bin/wkhtmltoimage
您可能还需要安装一些额外的软件包
sudo apt-get install xvfb libfontconfig libxrender1
brew cask install wkhtmltopdf
从 Heroku 控制面板的“设置”选项卡或通过 Heroku CLI,将 WKHTMLTOPDF 构建包添加到您的 Heroku 应用程序。
初始化 WK 对象时,请务必将 "pathToBinary" 参数指定为 /app/bin/wkhtmltopdf
WK(pathToBinary: "/app/bin/wkhtmltopdf", .topMargin(20), ...)
我不确定 Vapor Cloud 中是否提供了 wktmltopdf 二进制文件。如果您有任何相关信息,请随时发送 Pull Request,提供更新此自述文件的说明。
编辑您的 Package.swift 文件
//add this repo to dependencies
.package(url: "https://github.com/MihaelIsaev/wkhtmltopdf.git", from: "1.1.1")
//and don't forget about targets
//"WKHTMLTOPDF"
最常见的用法是在请求时动态生成一些报告,并在响应中返回 pdf 文件
import WKHTMLTOPDF
router.get("pdf") { req throws -> EventLoopFuture<Response> in
let wk = WK(.topMargin(20),
.leftMargin(20),
.rightMargin(20),
.bottomMargin(20),
.paperSize(.A4))
//Also you can provide path to your `wkhtmltopdf` binary
//while initialization because binary place may be different
//WK(pathToBinary: "/usr/bin/wkhtmltopdf", .topMargin(20), ...)
struct ReportIntro: Codable {
var reportName = "Monthly usage"
}
struct ReportData: Codable {
var records:[ReportRecord] = []
}
let page1 = Page(view: "report-intro", payload: ReportIntro(), params: PageParam.zoom(1.3))
let page2 = Page(view: "report-body", payload: ReportData(), params: PageParam.zoom(1.3))
let page3 = Page<Test>(url: "http://google.com", params: PageParam.zoom(1.3))
return try wk.generate(container: req, pages: page1, page2, page3).map { pdfData in //Data
let response = req.makeResponse(pdfData, as: .pdf)
response.http.headers.add(name: HTTPHeaderName.contentDisposition, value: "attachment; filename=\"report.pdf\"")
return response
}
}
看起来不错,对吧? 😃
请确保在您的文件中正确设置了 html 标头,并在您的操作系统中安装了所有必要的渲染包。
例如,正确的 html 标头可能如下所示
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>
<body>
</body>
</html>
它是 GeneralParam
枚举类型。
在 WK
对象初始化中使用。
WK(GeneralParam...)
GeneralParam | 描述 |
---|---|
.quiet | -q, --quiet 减少冗长,为了向后兼容而维护;与使用 --log-level none 相同 |
.paperSize(PaperSize) | -s, --page-size 设置纸张尺寸为:A4、Letter 等(默认为 A4) |
.grayscale | -g, --grayscale 将以灰度生成 PDF |
.lowQuality | -l, --lowquality 生成较低质量的 pdf/ps。有助于缩小结果文档的空间 |
.orientation(Orientation) | -O, --orientation 设置方向为 Landscape 或 Portrait(默认为 Portrait) |
.topMargin(Float) | -T, --margin-top 设置页面顶部边距 |
.rightMargin(Float) | -R, --margin-right 设置页面右侧边距(默认为 10mm) |
.bottomMargin(Float) | -B, --margin-bottom 设置页面底部边距 |
.leftMargin(Float) | -L, --margin-left 设置页面左侧边距(默认为 10mm) |
.pageHeight(Float) | --page-height 页面高度 |
.pageWidth(Float) | --page-width 页面宽度 |
.footerCenter(String) | --footer-center 居中的页脚文本 |
.footerFontName(String) | --footer-font-name 设置页脚字体名称(默认为 Arial) |
.footerFontSize(Int) | --footer-font-size 设置页脚字体大小(默认为 12) |
.footerHtml(url: String) | --footer-html 添加一个 html 页脚 |
.footerLeft(String) | --footer-left 左对齐的页脚文本 |
.footerLine | --footer-line 在页脚上方显示一条线 |
.noFooterLine | --no-footer-line 不要在页脚上方显示一条线(默认) |
.footerRight(String) | --footer-right 右对齐的页脚文本 |
.footerSpacing(Float) | --footer-spacing 页脚和内容之间的间距,以毫米为单位(默认为 0) |
.headerCenter(String) | --header-center 居中的页眉文本 |
.headerFontName(String) | --header-font-name 设置页眉字体名称(默认为 Arial) |
.headerFontSize(Int) | --header-font-size 设置页眉字体大小(默认为 12) |
.headerHtml(url: String) | --header-html 添加一个 html 页眉 |
.headerLeft(String) | --header-left 左对齐的页眉文本 |
.headerLine | --header-line 在页眉下方显示一条线 |
.noHeaderLine | --no-header-line 不要在页眉下方显示一条线(默认) |
.headerRight(String) | --header-right 右对齐的页眉文本 |
.headerSpacing(Float) | --header-spacing 页眉和内容之间的间距,以毫米为单位(默认为 0) |
.replace(name: String, value: String) | --replace 在页眉和页脚中将 [name] 替换为 value(可重复) |
.disableDottedLines | --disable-dotted-lines 不要在目录中使用点线 |
.tocHeaderText(String) | --toc-header-text 目录的标题文本(默认为 Table of Contents) |
.tocLevelIndentation(String) | --toc-level-indentation 对于目录中每个级别的标题,缩进此长度(默认为 1em) |
.disableTocLinks | --disable-toc-links 不要从目录链接到章节 |
.tocTextSizeShrink(Float) | --toc-text-size-shrink 对于目录中每个级别的标题,字体按此因子缩放(默认为 0.8) |
.xslStyleSheet(path: String) | --xsl-style-sheet 使用提供的 xsl 样式表来打印目录 |
它是 PageParam
枚举类型。
在 Page
对象初始化中使用。
Page(view: String, payload: Codable, PageParam...) //for generating Leaf page
//or
Page<Codable>(url: String, PageParam...) //for loading from URL
PageParam | 描述 |
---|---|
.allow(path: String) | --allow 允许加载指定文件夹中的文件(可重复) |
.background | --background 打印背景(默认) |
.noBackground | --no-background 不打印背景 |
.bypassProxyFor(String) | --bypass-proxy-for 绕过主机的代理(可重复) |
.cacheDir(path: String) | --cache-dir Web 缓存目录 |
.checkboxChecked(path: String) | --checkbox-checked-svg 渲染选中的复选框时使用此 SVG 文件 |
.checkboxUnchecked(path: String) | --checkbox-svg 渲染未选中的复选框时使用此 SVG 文件 |
.cookie(name: String, value: String) | --cookie 设置一个额外的 cookie(可重复),值应进行 URL 编码。 |
.customHeader(name: String, value: String) | --custom-header 设置一个额外的 HTTP 标头(可重复) |
.customHeaderPropagation | --custom-header-propagation 添加指定的 HTTP 标头 |
.noCustomHeaderPropagation | --no-custom-header-propagation 不要添加指定的 HTTP 标头 |
.defaultHeader | --default-header 添加一个默认标头,左侧为页面名称,右侧为页码 |
.encoding(String) | --encoding 设置输入的默认文本编码 |
.disableExternalLinks | --disable-external-links 不要创建指向远程网页的链接 |
.enableExternalLinks | --enable-external-links 创建指向远程网页的链接(默认) |
.enableForms | --enable-forms 将 HTML 表单字段转换为 pdf 表单字段 |
.disableForms | --disable-forms 不要将 HTML 表单字段转换为 pdf 表单字段(默认) |
.images | --images 加载或打印图像(默认) |
.noImages | --no-images 不要加载或打印图像 |
.disableInternalLinks | --disable-internal-links 不要创建本地链接 |
.enableInternalLinks | --enable-internal-links 创建本地链接(默认) |
.disableJavaScript | -n, --disable-javascript 不允许网页运行 JavaScript |
.enableJavaScript | --enable-javascript 允许网页运行 JavaScript(默认) |
.javascriptDelay(msec: Int) | --javascript-delay 等待 JavaScript 完成(默认 200 毫秒) |
.keepRelativeLinks | --keep-relative-links 将相对外部链接保留为相对外部链接 |
.loadErrorHandling(Handler) | --load-error-handling 指定如何处理加载失败的页面:abort、ignore 或 skip(默认为 abort) |
.loadMediaErrorHandling(Handler) | --load-media-error-handling 指定如何处理加载失败的媒体文件:abort、ignore 或 skip(默认为 ignore) |
.enableLocalFileAccess | --disable-local-file-access 不允许将本地文件转换为读取其他本地文件,除非使用 --allow 明确允许 |
.disableLocalFileAccess | --enable-local-file-access 允许将本地文件转换为读取其他本地文件。(默认) |
.minimumFontSize(Int) | --minimum-font-size 最小字体大小 |
.excludeFromOutline | --exclude-from-outline 不要将页面包含在目录和大纲中 |
.includeInOutline | --include-in-outline 将页面包含在目录和大纲中(默认) |
.pageOffset(Int) | --page-offset 设置起始页码(默认为 0) |
.password(String) | --password HTTP 身份验证密码 |
.disablePlugins | --disable-plugins 禁用已安装的插件(默认) |
.enablePlugins | --enable-plugins 启用已安装的插件(插件可能无法正常工作) |
.postField(name: String, value: String) | --post 添加一个额外的 post 字段(可重复) |
.postFile(name: String, path: String) | --post-file 发布一个额外的文件(可重复) |
.printMediaType | --print-media-type 使用 print media-type 代替 screen |
.noPrintMediaType | --no-print-media-type 不要使用 print media-type 代替 screen(默认) |
.proxy(String) | -p, --proxy 使用代理 |
.proxyHostnameLookup | --proxy-hostname-lookup 使用代理来解析主机名 |
.radioButtonChecked(path: String) | --radiobutton-checked-svg 渲染选中的单选按钮时使用此 SVG 文件 |
.radioButtonUnchecked(path: String) | --radiobutton-svg 渲染未选中的单选按钮时使用此 SVG 文件 |
.resolveRelativeLinks | --resolve-relative-links 将相对外部链接解析为绝对链接(默认) |
.runScript(js: String) | --run-script 在页面加载完成后运行此额外的 JavaScript(可重复) |
.disableSmartShrinking | --disable-smart-shrinking 禁用 WebKit 使用的智能收缩策略,该策略使像素/dpi 比率不恒定 |
.enableSmartShrinking | --enable-smart-shrinking 启用 WebKit 使用的智能收缩策略,该策略使像素/dpi 比率不恒定(默认) |
.sslCrtPath(path: String) | --ssl-crt-path ssl 客户端证书公钥的路径,采用 OpenSSL PEM 格式,可以选择后跟中间 ca 和受信任的证书 |
.sslKeyPassword(String) | --ssl-key-password ssl 客户端证书私钥的密码 |
.sslKeyPath(path: String) | --ssl-key-path ssl 客户端证书私钥的路径,采用 OpenSSL PEM 格式 |
.stopSlowScripts | --stop-slow-scripts 停止运行缓慢的 JavaScript(默认) |
.noStopSlowScripts | --no-stop-slow-scripts 不要停止运行缓慢的 JavaScript |
.disableTocBackLinks | --disable-toc-back-links 不要从章节标题链接到目录(默认) |
.enableTocBackLinks | --enable-toc-back-links 从章节标题链接到目录 |
.userStyleSheet(url: String) | --user-style-sheet 指定一个用户样式表,随每个页面加载 |
.username(String) | --username HTTP 身份验证用户名 |
.viewportSize(String) | --viewport-size <> 设置视口大小,如果您有自定义滚动条或 css 属性 overflow 来模拟窗口大小 |
.windowStatus(String) | --window-status 在渲染页面之前,等待 window.status 等于此字符串 |
.zoom(Float) | --zoom 使用此缩放因子(默认为 1) |
欢迎贡献!