简体   繁体   中英

cefsharp winform silent print to pdf if js callback window.print()

I've a problem with a popup and print it to pdf silently. When I push print button (on the site), it's open a popup, generate a barcode and then popup prints. The popup contain two js functions window.print() and then window.close() . I need to print this popup silently to pdf, but I don't found nothing about this method. Currently I intercept through ILifeSpanHandler, but targetUrl contain a static link and not contain barcode generated. I think the popup must be print as is bypassing window.print() and block print dialog. Can someone help me? Thank you so much.

EDITED

This is the js popup that I need to print silently to pdf. It is parent popup:

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title></title>
<script src="xxxx"></script>
<script src="xxxx/js/jquery-1.11.1.min.js" type="text/javascript"></script>
<script src="xxxx/js/lib/barcode/JsBarcode.all.min.js?v=20200729001"></script>
<script src="xxxx/js/lib/qrcode/qrcode.min.js?v=20200729001"></script>
<style>
#logo, #barcodes, #qrcode{
    text-align:center;
}
img{
    display:initial!important;
}
</style>
</head>
<script type="text/javascript">
    $(document).ready(function() {

        var qrcode = window.qrcode;
        var parentData = window.data;
        
        console.log(parentData);
        console.log("Start");

        
            var c = parentData;
            var id = 'id-'+c;
            if(qrcode){
                $("#barcodes").append("<div id='"+id+"' style=\"text-align:center;\"/><br/>");
            
                new QRCode(document.getElementById(id), {
                    text: c,
                    width: 128,
                    height: 128,
                    colorDark : "#000000",
                    colorLight : "#ffffff",
                    correctLevel : QRCode.CorrectLevel.H
                });
                $('#'+id).append('<br/> <br/> <div id="qrcode" style="font-weight:bold;">' + c + '</div>');
                
                
            }else{
                $("#barcodes").append("<img id='"+id+"' /><br/>");          
                JsBarcode("#" + id, c, {format: "CODE128", height:60});                 
            }
            console.log(parentData);
        

        console.log("End");
        console.log(parentData);
});
                    
</script>
<body>
<div id="logo">

<img style="   height: auto; width: auto; max-width: 300px; max-height: 300px;" src="xxxx">
<br>
<img style="height: auto; width: auto; max-width: 253px; max-height: 253px;" src="xxxx">
</div>
<br />
<div id="barcodes"></div>
</body>
</html>

window.data (coupon) is passed through key cookie value. I think that ILifeSpanHandler must intecpet and print to pdf file and close it self.

EDITED

I've tried:

using System;
using System.IO;
using CefSharp;

namespace CefSharp
{
    public class EnablePrint : ILifeSpanHandler
    {
        bool ILifeSpanHandler.DoClose(IWebBrowser chromiumWebBrowser, IBrowser browser)
        {
            var coupon = browser.PrintToPdfAsync("c://coupon//text.pdf", new PdfPrintSettings
            {
                MarginType = CefPdfPrintMarginType.Custom,
                MarginBottom = 0,
                MarginTop = 0,
                MarginLeft = 0,
                MarginRight = 0,
                ScaleFactor = 95
            });


            coupon.ContinueWith(exit =>
            browser.GetHost().CloseBrowser(true));


            return true;
        }

        void ILifeSpanHandler.OnAfterCreated(IWebBrowser chromiumWebBrowser, IBrowser browser)
        {
        }

        void ILifeSpanHandler.OnBeforeClose(IWebBrowser chromiumWebBrowser, IBrowser browser)
        {
        }

        bool ILifeSpanHandler.OnBeforePopup(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, string targetUrl, string targetFrameName, WindowOpenDisposition targetDisposition, bool userGesture, IPopupFeatures popupFeatures, IWindowInfo windowInfo, IBrowserSettings browserSettings, ref bool noJavascriptAccess, out IWebBrowser newBrowser)
        {                           
            newBrowser = null;
            return false;
        }
    }
}

This code generate an exception:

System.ObjectDisposedException
  HResult=0x80131622
  Messaggio=Impossibile accedere a un oggetto eliminato.
Nome oggetto: 'This instance of CefSharp.IBrowser been disposed!'.
  Origine=CefSharp.Core
  Analisi dello stack:
   in CefSharp.Internals.CefWrapper.ThrowIfDisposed()
   in CefSharp.Internals.CefSharpBrowserWrapper.GetHost()
   in PremierClient_x86.EnablePrint.<>c__DisplayClass0_0.<CefSharp.ILifeSpanHandler.DoClose>b__0(Task`1 exit) in C:\Users\XXXXXXX\EnablePrint.cs: riga 23
   in System.Threading.Tasks.ContinuationTaskFromResultTask`1.InnerInvoke()
   in System.Threading.Tasks.Task.Execute()

The popup ramian on front and I cannot manually close.

Based on the example give above you'll have to close the popup window manually, which is easy enough. The code will look something like below (it compiles though I haven't tested as I don't have a working example to go from).

using System;
using System.Runtime.InteropServices;
using CefSharp;

namespace CefSharp.MinimalExample.WinForms
{
    public class LifeSpanHandler : ILifeSpanHandler
    {
        [DllImport("user32.dll")]
        private static extern bool DestroyWindow(IntPtr hWnd);
        [DllImport("user32.dll")]
        private static extern IntPtr GetTopWindow(IntPtr hWnd);
        
        bool ILifeSpanHandler.DoClose(IWebBrowser chromiumWebBrowser, IBrowser browser)
        {
            //Only do this for popups
            if(!browser.IsPopup)
            {
                return false;
            }
            
            var hwnd = browser.GetHost().GetWindowHandle();
            
            browser.PrintToPdfAsync("c://coupon//text.pdf", new PdfPrintSettings()).ContinueWith(exit =>
            {
                //You may need to get the top level window and close that instead
                //var parentHwnd = GetTopWindow(hwnd);
                //DestroyWindow(parentHwnd);
                
                //Close the browser, if the popup window doesn't close then
                //get the top level window and close that instead (code commented out above)
                DestroyWindow(hwnd);
            });

            //Cancel close, destroy window manually after pdf generated
            return true;
        }

        void ILifeSpanHandler.OnAfterCreated(IWebBrowser chromiumWebBrowser, IBrowser browser)
        {
        }

        void ILifeSpanHandler.OnBeforeClose(IWebBrowser chromiumWebBrowser, IBrowser browser)
        {
        }

        bool ILifeSpanHandler.OnBeforePopup(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, string targetUrl, string targetFrameName, WindowOpenDisposition targetDisposition, bool userGesture, IPopupFeatures popupFeatures, IWindowInfo windowInfo, IBrowserSettings browserSettings, ref bool noJavascriptAccess, out IWebBrowser newBrowser)
        {                           
            newBrowser = null;
            return false;
        }
    }
}

Additionally to avoid showing the print dialog you can inject some javascript to override window.print and make it a noop

namespace CefSharp.MinimalExample.WinForms
{
    internal class LoadHandler : ILoadHandler
    {
        void ILoadHandler.OnFrameLoadEnd(IWebBrowser chromiumWebBrowser, FrameLoadEndEventArgs args)
        {
            
        }

        void ILoadHandler.OnFrameLoadStart(IWebBrowser chromiumWebBrowser, FrameLoadStartEventArgs args)
        {
            if (args.Browser.IsPopup)
            {
                //Override window.print so it does nothing
                args.Browser.MainFrame.ExecuteJavaScriptAsync("window.print = function () { };");
            }
        }

        void ILoadHandler.OnLoadError(IWebBrowser chromiumWebBrowser, LoadErrorEventArgs args)
        {
            
        }

        void ILoadHandler.OnLoadingStateChange(IWebBrowser chromiumWebBrowser, LoadingStateChangedEventArgs args)
        {
            
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM