Save web view content as pdf

Note: I am working with swift 4 for osx. I would like to create a PDF file from WebView.

At the moment, my WebView is loading an html string and showing it successfully. If I press the button, the print panel opens and is ready to print the contents of the WebView in the correct format.

This is my print code:

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

enter image description here

Now I would like to have another button that saves the content directly as a pdf file.

I tried this:

 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) 

But the result of my pdf looks awful:

enter image description here

Does anyone have an idea?

UPDATE This is part of the result of my web view:

enter image description here

and this is the result of my preview / pdf / color file is missing, but now everywhere. "logo" (image) will be displayed with color: enter image description here

+5
source share
1 answer

The problem is that dataWithPDF uses the current view frame to determine how wide the generated PDF file should be. Since your WebView frame in your application is probably thicker than the 8.5 / 11 "page, you get a not widespread PDF file. You can adjust the frame of the WebView to the desired size, make a PDF file, and then edit it, or you you can create a new WebView , make it off-screen, set it to the appropriate size and create a PDF. However, this is a bit of a pain in the back. It would be great if there were a way to programmatically do what the "PDF" button in the dialog Print window, because the print system is processing it all automatically for you?

Well, it turns out you can! But you have to plunge into the poorly documented world of Core Printing.

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

The key is calling PMSessionSetDestination , which allows us to set up a print session for printing in PDF instead of the actual printer. Then we just tell NSPrintOperation not to show the print panel, start the operation and presto! PDF printed.

+5
source

Source: https://habr.com/ru/post/1271992/


All Articles