You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS中如何去除WKWebView打印PDF时的默认边距并使用标准文档尺寸

iOS中如何去除WKWebView打印PDF时的默认边距并使用标准文档尺寸

我之前也碰到过和你完全一样的问题——想从WKWebView导出无默认边距的PDF,同时还要保留A4、Letter这类标准文档尺寸可选,试了outputType切换的方法确实不行,后来摸索出了一套靠谱的解决方案,分享给你:

核心思路是通过CSS直接控制页面边距和尺寸,同时配合正确的打印格式化器配置,替代WKWebView自带的viewPrintFormatter,这样既能去掉边距,又能保留标准文档尺寸选项。

具体步骤和代码修改:

  1. 从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)
    }
    
  2. 给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)
        }
    }
    
  3. 替换原有函数的逻辑
    把你原来的openPrintPanel函数里的逻辑改成先调用evaluateJavaScript获取HTML,再执行上面的打印方法就可以了。

为什么这个方法有效?

  • 用UIMarkupTextPrintFormatter替代viewPrintFormatter,我们能完全控制HTML的打印样式,不受WebView视图布局的限制;
  • CSS的@page规则直接告诉打印系统页面边距为0,同时size: auto会适配用户选择的任何标准文档尺寸(A4、Letter等);
  • printInfo.outputType = .general保证打印面板里只会显示标准文档尺寸选项,不会出现照片类的小尺寸。

额外注意点

  • 如果你的WebView里有固定宽度的元素,可能需要调整CSS让它自适应页面宽度,避免内容被裁切;
  • 测试时可以选择“保存到文件”来生成PDF,直接查看边距是否符合要求。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 12:24:32