iOS中如何去除WKWebView打印PDF时的默认边距并使用标准文档尺寸
iOS中如何去除WKWebView打印PDF时的默认边距并使用标准文档尺寸
我之前也碰到过和你完全一样的问题——想从WKWebView导出无默认边距的PDF,同时还要保留A4、Letter这类标准文档尺寸可选,试了outputType切换的方法确实不行,后来摸索出了一套靠谱的解决方案,分享给你:
核心思路是通过CSS直接控制页面边距和尺寸,同时配合正确的打印格式化器配置,替代WKWebView自带的viewPrintFormatter,这样既能去掉边距,又能保留标准文档尺寸选项。
具体步骤和代码修改:
从WKWebView获取完整的HTML内容
我们需要拿到WebView加载的完整HTML,最好用JavaScript去获取,这样能保证拿到渲染后的完整DOM:wKWebView.evaluateJavaScript("document.documentElement.outerHTML") { [weak self] html, error in guard let self = self, let htmlString = html as? String, error == nil else { print("获取HTML失败: \(error?.localizedDescription ?? "未知错误")") return } // 后续的打印逻辑放在这里 self.printWithCustomHTML(htmlString: htmlString, fileName: fileName) }给HTML添加控制打印样式的CSS
我们要在HTML头部插入自定义的CSS,强制设置页面边距为0,同时指定页面尺寸(也可以设为auto让系统适配可选的标准尺寸):private func printWithCustomHTML(htmlString: String, fileName: String) { // 包裹带有打印样式的HTML let styledHTML = """ <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <style> /* 重置body边距 */ body { margin: 0 !important; padding: 0 !important; } /* 控制打印页面的边距和尺寸 */ @page { margin: 0; size: auto; /* 自动适配选择的标准尺寸(A4/Letter等) */ /* 如果想固定尺寸,可以换成 size: A4; 或者 size: Letter; */ } /* 确保所有元素不会超出页面范围 */ * { box-sizing: border-box; } </style> </head> <body> \(htmlString) </body> </html> """ // 配置打印信息 let printInfo = UIPrintInfo.printInfo() printInfo.outputType = .general // 用general保证标准文档尺寸可选 printInfo.jobName = fileName // 创建自定义的打印格式化器 let printFormatter = UIMarkupTextPrintFormatter(markupText: styledHTML) printFormatter.contentInsets = UIEdgeInsetsZero // 去掉格式化器自带的边距 // 配置打印控制器 let printController = UIPrintInteractionController.shared printController.printInfo = printInfo printController.printFormatter = printFormatter // 完成回调 let completionHandler: UIPrintInteractionController.CompletionHandler = { (controller, completed, error) in if let error = error, !completed { print("打印失败: \(error.localizedDescription)") } else if completed { print("打印/导出PDF成功") } } // 弹出打印面板 if let rootVC = UIApplication.shared.windows.first?.rootViewController { printController.present(animated: true, completionHandler: completionHandler) } else { printController.present(animated: true, completionHandler: completionHandler) } }替换原有函数的逻辑
把你原来的openPrintPanel函数里的逻辑改成先调用evaluateJavaScript获取HTML,再执行上面的打印方法就可以了。
为什么这个方法有效?
- 用
UIMarkupTextPrintFormatter替代viewPrintFormatter,我们能完全控制HTML的打印样式,不受WebView视图布局的限制; - CSS的
@page规则直接告诉打印系统页面边距为0,同时size: auto会适配用户选择的任何标准文档尺寸(A4、Letter等); printInfo.outputType = .general保证打印面板里只会显示标准文档尺寸选项,不会出现照片类的小尺寸。
额外注意点
- 如果你的WebView里有固定宽度的元素,可能需要调整CSS让它自适应页面宽度,避免内容被裁切;
- 测试时可以选择“保存到文件”来生成PDF,直接查看边距是否符合要求。
内容来源于stack exchange
相关产品推荐
相关产品推荐

