将Web视图内容另存为pdf文件

Gho*_*108 6 pdf macos cocoa webview swift

注意:我使用swift 4 for osx.我想从WebView生成一个pdf文件.

目前,我的WebView加载了一个html字符串并成功显示.如果按下按钮,打印面板将打开,并准备以正确的格式打印我的WebView内容.

这是我的打印代码:

var webView = WebView()
var htmlString = "MY HTML STRING"

override func viewDidLoad() {
    webView.mainFrame.loadHTMLString(htmlString, baseURL: nil)
}

func webView(_ sender: WebView!, didFinishLoadFor frame: WebFrame!) {

    let printInfo = NSPrintInfo.shared
    printInfo.paperSize = NSMakeSize(595.22, 841.85)
    printInfo.isHorizontallyCentered = true
    printInfo.isVerticallyCentered = true
    printInfo.orientation = .portrait
    printInfo.topMargin = 50
    printInfo.rightMargin = 0
    printInfo.bottomMargin = 50
    printInfo.leftMargin = 0
    printInfo.verticalPagination = .autoPagination
    printInfo.horizontalPagination = .fitPagination
    //webView.mainFrame.frameView.printOperation(with: printInfo).run()

    let printOp: NSPrintOperation = NSPrintOperation(view: webView.mainFrame.frameView.documentView, printInfo: printInfo)
    printOp.showsPrintPanel = true
    printOp.showsProgressPanel = false
    printOp.run() 
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

现在我想要另一个按钮,它将内容直接保存为pdf文件.

我试过这个:

let pdfData = webView.mainFrame.frameView.documentView.dataWithPDF(inside: webView.mainFrame.frameView.documentView.frame)
let document = PDFDocument(data: pdfData)
let fileURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).appendingPathComponent("myPDF.pdf")
document?.write(to: fileURL)
Run Code Online (Sandbox Code Playgroud)

但是我的pdf结果看起来很糟糕:

在此输入图像描述

有人有想法吗?

更新 这是我的网络视图结果的一部分:

在此输入图像描述

这是我的打印预览/ pdf文件的结果/缺少颜色,但现在无处不在."徽标"(图片)将显示颜色: 在此输入图像描述

Cha*_*tka 6

问题是dataWithPDF使用视图的当前帧来决定生成的PDF应该有多宽.由于你的WebView"在你的应用程序S架构可能比8.5/11"页面瘦,你得到一个PDF是充分宽,你可以调节WebView的帧到合适的大小,使PDF,然后对其进行调整回来了,或者你可以创建一个新的WebView,使其屏幕外,将其设置到合适的大小,并创建PDF文件.这是一个位在背面上的痛苦,但如果有一种方法,那岂不是巨大的编程执行打印对话框中的"PDF"按钮,因为打印系统会自动处理所有这些内容吗?

好吧,事实证明你可以!但你必须深入研究记录不佳的核心印刷世界.

func makePDF(at url: URL, for webView: WebView, printInfo: NSPrintInfo) throws {
    webView.preferences.shouldPrintBackgrounds = true

    guard let printOp = webView.mainFrame.frameView.printOperation(with: printInfo) else {
        throw MyPrintError.couldntGetPrintOperation // or something like this
    }

    let session = PMPrintSession(printOp.printInfo.pmPrintSession())
    let settings = PMPrintSettings(printOp.printInfo.pmPrintSettings())

    if PMSessionSetDestination(session,
                               settings,
                               PMDestinationType(kPMDestinationFile),
                               kPMDocumentFormatPDF as CFString,
                               url as CFURL) != noErr {
        throw MyPrintError.couldntSetDestination // or something like this
    }

    printOp.showsPrintPanel = false
    printOp.run()
}
Run Code Online (Sandbox Code Playgroud)

关键是PMSessionSetDestination调用,它允许我们将打印会话配置为打印到PDF而不是打印到实际的打印机.然后我们告诉NSPrintOperation不要显示打印面板,运行操作,然后!PDF打印.