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