swift - 在 macOS 中将 WKWebView 内容转换为 PDF
问题描述
我正在尝试将 a 的内容转换为WKWebView
PDF 文件。
在UIWebView
被弃用之前,它是这样完成的:
webView.loadHTMLString("<h1>HELLO!</h1>", baseURL: nil)
let pdfData = webView.mainFrame.frameView.documentView.dataWithPDF(inside: webView.mainFrame.frameView.documentView.frame)
let document = PDFDocument(data: pdfData)
我现在尝试的:
webView.loadHTMLString("<h1>HELLO!</h1>", baseURL: nil)
let pdfData = self.webViewPDF.webFrame.frameView.documentView.dataWithPDF(inside: self.webViewPDF.webFrame.frameView.documentView.frame)
let document = PDFDocument(data: pdfData)
但得到了以下错误:
[WKWebView webFrame]:发送到实例的无法识别的选择器。
[General] 引发了未捕获的异常
问题是WKWebView
没有mainFrame
财产...
解决方案
更新。下面的解决方案在iOS上运行良好,但我现在才注意到您正在寻找macOS解决方案。请让我知道这个解决方案是否有任何帮助......抱歉造成混淆;)
您现在可以使用该UIView.viewPrintFormatter()
方法(来自UIView
类):
返回接收视图的打印格式化程序。
启动打印作业时,您可以调用此方法为您的视图获取适当的视图打印格式化程序对象。您可以使用格式化程序对象在打印期间为您的视图配置页面布局选项。
例如:
import UIKit
import WebKit
import PDFKit
extension WKWebView {
/// Exports a PDF document with this web view current contents.
/// Only call this function when the web view has **finished** loading.
func exportAsPDF() -> PDFDocument? {
guard self.isLoading == false else {
print("WKWebView still loading!")
return nil
}
let pdfData = createPDFData()
return PDFDocument(data: pdfData)
}
private func createPDFData() -> Data {
let oldBounds = self.bounds
var printBounds = self.bounds
printBounds.size.height = scrollView.contentSize.height
self.bounds = printBounds
var printableRect = printBounds
printableRect.origin = .zero
let printRenderer = UIPrintPageRenderer()
printRenderer.addPrintFormatter(self.viewPrintFormatter(), startingAtPageAt: 0)
printRenderer.setValue(NSValue(cgRect: UIScreen.main.bounds), forKey: "paperRect")
printRenderer.setValue(NSValue(cgRect: printableRect), forKey: "printableRect")
self.bounds = oldBounds
return printRenderer.generatePDFData()
}
}
并添加以下辅助方法UIPrintPageRenderer
:
extension UIPrintPageRenderer {
func generatePDFData() -> Data {
let pdfData = NSMutableData()
UIGraphicsBeginPDFContextToData(pdfData, self.paperRect, nil)
self.prepare(forDrawingPages: NSMakeRange(0, self.numberOfPages))
let printRect = UIGraphicsGetPDFContextBounds()
for pdfPage in 0..<self.numberOfPages {
UIGraphicsBeginPDFPage()
self.drawPage(at: pdfPage, in: printRect)
}
UIGraphicsEndPDFContext()
return pdfData as Data
}
}
最后,您现在可以使用exportAsPDF()
上面定义的 API 保存 PDF:
let webView: WKWebView = ...
let pdfDocument = webView.exportAsPDF()!
let docsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let pdfFile = docsDir.appendingPathComponent("WebViewPDF.pdf")
try! pdfDocument.write(to: pdfFile)
推荐阅读
- java - 如何在通过 SQL 加载器将数据加载到数据库时从日文字符中修剪空格?
- r - 在 R 中堆叠 .rds 文件
- python - 在 Flask 中推送应用程序上下文
- haskell - 为什么这个功能没有触底
- odata - 使用 Automapper 的 OData 元数据
- pytorch - 如何在 BCELoss Pytorch 上检查准确性?
- avisynth - 在avisynth中使用ddcomb插件
- c++ - g++ -I 包含所有带有头文件的子目录
- javascript - 如何在提交反应之前检查多个文本框验证
- nuget - NuGet 版本范围 - 始终获取具有最高修订号的包