Save a web page as PDF

Using some code from @ShaneStanley, I’m able to save a web page as PDF.
The following code gets the page’s source and saves it in 2 formats:

  • one in html that renders perfectly with QuickLook
  • another in PDF that is totally messed up.

Can we do anything to make this PDF look better?

Here is the script:

use framework "Foundation"
use framework "AppKit"
use scripting additions

set thePage to current application's NSURL's URLWithString:"https://www.eurofins-biomnis.com/services/referentiel-des-examens/page/125D/?r=1#"
set pdfFile to current application's NSURL's fileURLWithPath:(POSIX path of ("" & (path to desktop) & "PDF from Web Page.pdf"))
set htmlFile to current application's NSURL's fileURLWithPath:(POSIX path of ("" & (path to desktop) & "PDF from Web Page.html"))

set printInfo to current application's NSPrintInfo's alloc()'s initWithDictionary:(current application's NSDictionary's dictionaryWithObject:pdfFile forKey:(current application's NSPrintJobSavingURL))
printInfo's setJobDisposition:(current application's NSPrintSaveJob)
printInfo's setHorizontalPagination:(current application's NSClipPagination)
printInfo's setVerticalPagination:(current application's NSAutoPagination)
printInfo's setPaperSize:{900, 1600}
printInfo's setLeftMargin:0
printInfo's setRightMargin:0
printInfo's setTopMargin:0
printInfo's setBottomMargin:0

set theView to current application's NSTextView's alloc()'s initWithFrame:{{0, 0}, {1200, 3.0E+38}}
theView's setHorizontallyResizable:false

set {theHtml, theError} to current application's NSData's dataWithContentsOfURL:thePage options:0 |error|:(reference)
if theHtml = missing value then error (theError's localizedDescription() as text)
theHtml's writeToURL:htmlFile atomically:true -- only for comparison
set theData to current application's NSData's dataWithContentsOfFile:htmlFile
set attStr to current application's NSAttributedString's alloc()'s initWithHTML:theHtml documentAttributes:(missing value)
theView's textStorage()'s setAttributedString:attStr

if current application's NSThread's isMainThread() then
	theView's sizeToFit()
else
	theView's performSelectorOnMainThread:"sizeToFit" withObject:(missing value) waitUntilDone:true
end if

set printOp to current application's NSPrintOperation's printOperationWithView:theView printInfo:printInfo
printOp's setShowsPrintPanel:false
printOp's setShowsProgressPanel:false
if current application's NSThread's isMainThread() then
	set my theResult to printOp's runOperation()
else
	my performSelectorOnMainThread:"runPrintOperation:" withObject:printOp waitUntilDone:true
end if

on runPrintOperation:printOp -- on main thread
	set my theResult to printOp's runOperation()
end runPrintOperation:

After some tests, I’m pretty sure it’s the conversion from html data to attributed string that causes the problem.
Is there any way to avoid this?

Another approach could be to use a webView instead of a textView. But all I get is an empty pdf file…

use framework "Foundation"
use framework "WebKit"
use scripting additions

property theResult : missing value

my performSelectorOnMainThread:"webpageTOpdf" withObject:(missing value) waitUntilDone:true
return theResult

on webpageTOpdf()
	set thePage to current application's NSURL's URLWithString:"https://www.eurofins-biomnis.com/services/referentiel-des-examens/page/125D/?r=1#"
	set pdfFile to current application's NSURL's fileURLWithPath:(POSIX path of ("" & (path to desktop) & "PDF from Web Page.pdf"))
	set htmlFile to current application's NSURL's fileURLWithPath:(POSIX path of ("" & (path to desktop) & "PDF from Web Page.html"))
	
	set printInfo to current application's NSPrintInfo's alloc()'s initWithDictionary:(current application's NSDictionary's dictionaryWithObject:pdfFile forKey:(current application's NSPrintJobSavingURL)) -- sets destination
	printInfo's setJobDisposition:(current application's NSPrintSaveJob) -- save to file job
	printInfo's setHorizontalPagination:(current application's NSClipPagination)
	printInfo's setVerticalPagination:(current application's NSAutoPagination)
	printInfo's setPaperSize:{900, 1600}
	printInfo's setLeftMargin:0
	printInfo's setRightMargin:0
	printInfo's setTopMargin:0
	printInfo's setBottomMargin:0
	log 1
	
	set theConf to current application's WKWebViewConfiguration's new()
	set theSource to current application's NSString's stringWithContentsOfURL:thePage encoding:(current application's NSUTF8StringEncoding) |error|:(missing value)
	set userScript to current application's WKUserScript's alloc()'s initWithSource:theSource injectionTime:(current application's WKUserScriptInjectionTimeAtDocumentEnd) forMainFrameOnly:true
	set userContentController to current application's WKUserContentController's alloc()'s init()
	userContentController's addUserScript:userScript
	theConf's setUserContentController:userContentController
	log 2
	
	set webView to current application's WKWebView's alloc()'s initWithFrame:{{0, 0}, {900, 3.0E+38}} configuration:theConf
	webView's setNavigationDelegate:me
	webView's setUIDelegate:me
	webView's setTranslatesAutoresizingMaskIntoConstraints:true
	log 3
	
	set printOp to current application's NSPrintOperation's printOperationWithView:webView printInfo:printInfo
	printOp's setShowsPrintPanel:false
	printOp's setShowsProgressPanel:false
	printOp's view()'s setFrame:{{0, 0}, {900, 1600}}
	log 6
	
	set my theResult to printOp's runOperation()
	log my theResult
	
end webpageTOpdf