Printing contents of WKWebView (OS X)

前端 未结 3 1454
后悔当初
后悔当初 2020-12-17 16:24

I am trying to print the contents of a WkWebView, but when the print panel appears the print preview is empty.

Here is the code:

- (voi         


        
相关标签:
3条回答
  • 2020-12-17 16:38

    The solution I use, is to instantiate a good old WebView object, and use the print method of that object. My example uses a html string as starting point, but it should be easily adaptable to an URL.

    Objective C

    @interface WebPrinter ()
    {
        WebView *printView;
        NSPrintInfo *printInfo;
    }
    
    @implementation WebPrinter
    
    - (void)printHtml:(NSString *)html {
    
        if (!printInfo) {
            printInfo = [NSPrintInfo sharedPrintInfo];
            printInfo.topMargin = 25;
            printInfo.bottomMargin = 10;
            printInfo.rightMargin = 10;
            printInfo.leftMargin = 10;
        }
    
        NSRect printViewFrame = NSMakeRect(0, 0, printInfo.paperSize.width, printInfo.paperSize.height);
        printView = [[WebView alloc] initWithFrame:printViewFrame frameName:@"printFrame" groupName:@"printGroup"];
        printView.shouldUpdateWhileOffscreen = true;
        printView.frameLoadDelegate = self;
        [printView.mainFrame loadHTMLString:html baseURL:NSBundle.mainBundle.resourceURL];
    }
    
    - (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame {
    
        if (frame != sender.mainFrame) {
            return;
        }
    
        if (sender.isLoading) {
            return;
        }
    
        if ([[sender stringByEvaluatingJavaScriptFromString:@"document.readyState"] isEqualToString:@"complete"]) {
    
            sender.frameLoadDelegate = nil;
    
            NSWindow *window = NSApp.mainWindow;
            if (!window) {
                window = NSApp.windows.firstObject;
            }
    
            NSPrintOperation *printOperation = [NSPrintOperation printOperationWithView: frame.frameView.documentView printInfo:printInfo];
            [printOperation runOperationModalForWindow:window delegate:window didRunSelector:nil contextInfo:nil];
        }
    }
    
    @end
    

    Swift

    class WebPrinter: NSObject, WebFrameLoadDelegate {
    
        let window: NSWindow
        var printView: WebView?
        let printInfo = NSPrintInfo.shared
    
        init(window: NSWindow) {
            self.window = window
            printInfo.topMargin = 30
            printInfo.bottomMargin = 15
            printInfo.rightMargin = 0
            printInfo.leftMargin = 0
        }
    
        func printHtml(_ html: String) {
            let printViewFrame = NSMakeRect(0, 0, printInfo.paperSize.width, printInfo.paperSize.height)
            if let printView = WebView(frame: printViewFrame, frameName: "printFrame", groupName: "printGroup") {
                printView.shouldUpdateWhileOffscreen = true
                printView.frameLoadDelegate = self
                printView.mainFrame.loadHTMLString(html, baseURL: Bundle.main.resourceURL)
            }
        }
    
        func webView(_ sender: WebView!, didFinishLoadFor frame: WebFrame!) {
            if frame != sender.mainFrame {
                return
            }
    
            if sender.isLoading {
                return
            }
    
            if sender.stringByEvaluatingJavaScript(from: "document.readyState") == "complete" {
                sender.frameLoadDelegate = nil
                let printOperation = NSPrintOperation(view: frame.frameView.documentView, printInfo: printInfo)
                printOperation.runModal(for: window, delegate: window, didRun: nil, contextInfo: nil)
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-17 16:56

    You can print the contents of WKWebView with viewPrintFormatter. Here is the sample code:

    if ([UIPrintInteractionController isPrintingAvailable])
    {
        UIPrintInfo *pi = [UIPrintInfo printInfo];
        pi.outputType = UIPrintInfoOutputGeneral;
        pi.jobName = @"Print";
        pi.orientation = UIPrintInfoOrientationPortrait;
        pi.duplex = UIPrintInfoDuplexLongEdge;
    
        UIPrintInteractionController *pic = [UIPrintInteractionController sharedPrintController];
        pic.printInfo = pi;
        pic.showsPageRange = YES;
        pic.printFormatter = self.webView.viewPrintFormatter;
        [pic presentFromBarButtonItem:barButton animated:YES completionHandler:^(UIPrintInteractionController *printInteractionController, BOOL completed, NSError *error) {
            if(error)
                NSLog(@"handle error here");
            else
                NSLog(@"success");
        }];
    }
    
    0 讨论(0)
  • 2020-12-17 16:58

    If your app can require macOS 10.13 or later, there is a new method on WKWebView: takeSnapshot(with:completionHandler:), which generates an NSImage representation of your web view.

    As far as I know this is the best option for rendering a WKWebView to image.

    0 讨论(0)
提交回复
热议问题