Конвертируйте содержимое WKWebView в PDF в macOS - PullRequest
1 голос
/ 19 марта 2019

Я пытаюсь преобразовать содержимое 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 свойства ...

1 Ответ

0 голосов
/ 21 марта 2019

Обновление .Приведенное ниже решение прекрасно работает на iOS , но я только что заметил сейчас , что вы ищете решение macOS вместо этого.Пожалуйста, дайте мне знать, если это решение вообще может помочь ... извините за путаницу;)


Теперь вы можете использовать метод UIView.viewPrintFormatter() (из класса UIView) дляthat:

Возвращает средство форматирования печати для получающего представления.

При запуске задания печати вы можете вызвать этот метод, чтобы получить соответствующий объект средства форматирования печати представления для вашего представления.Вы можете использовать объект форматирования для настройки параметров макета страницы для вашего вида во время печати.

Например:

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
    }
}

Наконец, теперь вы можете сохранитьPDF с использованием exportAsPDF() API, определенного выше:

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)

...