在开放 Web 上,window.print() 会唤起浏览器打印面板,用户可保存为 PDF 或发送到打印机。在 WebView 里,这个调用静默无作为。Android 只通过宿主侧 API 暴露打印,iOS WKWebView 则完全忽略该调用。宿主自有 runtime 桥接打印与 PDF 导出——同一个 API,在每种引擎上都能产出真实文档。

Android:打印是宿主专属 API

Android 官方文档写得很清楚:要在 WebView 里打印,必须调用 webView.createPrintDocumentAdapter(jobName) 并交给系统 PrintManager,页面自身无法触发 window.print()。文档还列了硬性限制:不能用 JavaScript 触发打印、同一 WebView 实例一次只能跑一个打印任务、带横屏等 CSS 打印属性的 HTML 不被支持。于是,在 Chrome 里能打印票据的结算页,在 App 的 WebView 里按钮毫无反应。开发者必须持有 WebView 实例、构造适配器、弹出系统打印面板——PDF 导出走的也是同一条路,页面无法自行发起。

iOS:window.print() 被静默忽略

在 WKWebView 里,window.print() 不会弹出打印面板。社区通行的做法是注入一段脚本,把 window.print 覆写为向 WKScriptMessageHandler 发消息,再由原生侧驱动 UIPrintInteractionController。即便如此,iOS 也没有桌面等价的「纯 Web 静默打印」:打印控制器必须呈现一个用户可见的打印界面供确认,网页无法触达无头打印管线。PDF 导出同理——桥必须活在 App 里。

打印失效时,什么会崩

  • 票据与行程单出不来。 在 Safari 能用的「打印 / 存 PDF」按钮,在 WebView 里毫无反应。
  • 发票与报表无法导出。 依赖浏览器打印转 PDF 的财务与 SaaS 流程丢失了出口。
  • 物流与零售小票打印失败。 拣货单、面单、POS 小票都无法在 App 内生成。
  • 内置浏览器更糟。 微信、抖音等内置 WebView 几乎不暴露任何打印面,桌面 QA 时问题被掩盖。

runtime 解法

宿主自有 runtime 桥接打印与导出层。页面调用统一 API——runtime.print() 或 runtime.exportPdf()——宿主通过 Android 原生 PrintManager 与 iOS 原生 UIPrintInteractionController 渲染。页眉、页脚、页码、横竖屏由原生统一处理。一次集成,每种引擎,同一文档格式。

维度WebView宿主自有 runtime
触发window.print() 无作为统一 runtime.print()
Android 路径宿主须接适配器 + PrintManager原生 PrintManager
iOS 路径window.print() 被忽略原生 UIPrintInteractionController
JS 触发打印平台拦截原生桥
PDF 导出页面无法发起单一 API
一致性因引擎而异统一

原生 App 能在每台设备上打印小票,裸 WebView 几乎一台都打不了。runtime 给页面一个打印面——最终产出真实的 PDF。

参考来源