Mihael Isaev

MIT License Swift 4.1 Swift.Stream


Swift 库,用于通过 wkhtmltopdf cli 从 Leaf 模板和/或网页构建 pdf 文件数据。专为 Vapor 3 构建,并使用 Vapor 本身(在底层使用 Swift-NIO)和 Leaf 作为模板。

安装 ⚙️

首先,安装 wkhtmltopdf 本身。

Ubuntu

可以自动安装它

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

macOS

brew cask install wkhtmltopdf

Heroku

从 Heroku 控制面板的“设置”选项卡或通过 Heroku CLI,将 WKHTMLTOPDF 构建包添加到您的 Heroku 应用程序。

初始化 WK 对象时,请务必将 "pathToBinary" 参数指定为 /app/bin/wkhtmltopdf

WK(pathToBinary: "/app/bin/wkhtmltopdf", .topMargin(20), ...)

Vapor Cloud

我不确定 Vapor Cloud 中是否提供了 wktmltopdf 二进制文件。如果您有任何相关信息,请随时发送 Pull Request,提供更新此自述文件的说明。

Swift Package Manager

编辑您的 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
    }
}

看起来不错,对吧? 😃

关于 UTF-8 编码的注意事项

请确保在您的文件中正确设置了 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)

欢迎贡献!