Printing 在Xamarin UWP中打印具有多个页面的WebView

Printing 在Xamarin UWP中打印具有多个页面的WebView,printing,webview,xamarin.uwp,Printing,Webview,Xamarin.uwp,我正在尝试用xamarin表单打印网页。我正在使用DependencyService打印webview,我已经在android中成功实现了它 对于Windows UWP, 我提到了这个链接: 此过程中使用的方法是仅打印网页的第一页。 编辑: 我创建了一个接口IPrint,只为函数提供html源代码 public interface IPrint { void PrintAsync(string htmlSource); } 在PrintAsync函数中(在Windows UWP项目

我正在尝试用xamarin表单打印网页。我正在使用DependencyService打印webview,我已经在android中成功实现了它

对于Windows UWP, 我提到了这个链接:

此过程中使用的方法是仅打印网页的第一页。

编辑
我创建了一个接口
IPrint
,只为函数提供html源代码

public interface IPrint
{
    void PrintAsync(string htmlSource);
}
在PrintAsync函数中(在Windows UWP项目中)

当WebView完全加载时

    private async void ViewToPrint_LoadCompleteAsync(object sender, Windows.UI.Xaml.Navigation.NavigationEventArgs e)
    {

        if (PrintDoc != null)
        {
            printDoc.AddPages -= PrintDoc_AddPages;
            printDoc.GetPreviewPage -= PrintDoc_GetPreviewPage;
            printDoc.Paginate -= PrintDoc_Paginate;
        }
        this.printDoc = new PrintDocument();
        try
        {
            printDoc.AddPages += PrintDoc_AddPages;
            printDoc.GetPreviewPage += PrintDoc_GetPreviewPage;
            printDoc.Paginate += PrintDoc_Paginate;

            bool showprint = await PrintManager.ShowPrintUIAsync();

        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.ToString());
        }
        PrintDoc = null;
        GC.Collect();
    }
要在PrintDocument中添加页面

    private void PrintDoc_AddPages(object sender, AddPagesEventArgs e)
    {          
        printDoc.AddPage(ViewToPrint);
        printDoc.AddPagesComplete();
    }

要实现多页打印, 我提到这个链接:

我将AddPages函数更改为以下内容,但它似乎对我不起作用

    private void PrintDoc_AddPages(object sender, AddPagesEventArgs e)
    {     
        rectangleList = GetWebPages(ViewToPrint,  new Windows.Foundation.Size(100d, 150d));
        foreach (Windows.UI.Xaml.Shapes.Rectangle rectangle in rectangleList)
        {
            printDoc.AddPage(rectangle);
        }                                                                                     
        printDoc.AddPagesComplete();
    }
您可以在这里找到GetWebPages()函数

    List<Windows.UI.Xaml.Shapes.Rectangle> GetWebPages(Windows.UI.Xaml.Controls.WebView webView, Windows.Foundation.Size page)
    {
        // ask the content its width
        var _WidthString = webView.InvokeScriptAsync("eval",
            new[] { "document.body.scrollWidth.toString()" }).GetResults();
        int _ContentWidth;
        if (!int.TryParse(_WidthString, out _ContentWidth))
            throw new Exception(string.Format("failure/width:{0}", _WidthString));
        webView.Width = _ContentWidth;

        // ask the content its height
        var _HeightString = webView.InvokeScriptAsync("eval",
            new[] { "document.body.scrollHeight.toString()" }).GetResults();
        int _ContentHeight;
        if (!int.TryParse(_HeightString, out _ContentHeight))
            throw new Exception(string.Format("failure/height:{0}", _HeightString));
        webView.Height = _ContentHeight;

        // how many pages will there be?
        var _Scale = page.Width / _ContentWidth;
        var _ScaledHeight = (_ContentHeight * _Scale);
        var _PageCount = (double)_ScaledHeight / page.Height;
        _PageCount = _PageCount + ((_PageCount > (int)_PageCount) ? 1 : 0);

        // create the pages
        var _Pages = new List<Windows.UI.Xaml.Shapes.Rectangle>();
        for (int i = 0; i < (int)_PageCount; i++)
        {
            var _TranslateY = -page.Height * i;
            var _Page = new Windows.UI.Xaml.Shapes.Rectangle
            {
                Height = page.Height,
                Width = page.Width,
                Margin = new Windows.UI.Xaml.Thickness(5),
                Tag = new Windows.UI.Xaml.Media.TranslateTransform { Y = _TranslateY },
            };
            _Page.Loaded += (s, e) =>
            {
                var _Rectangle = s as Windows.UI.Xaml.Shapes.Rectangle;
                var _Brush = GetWebViewBrush(webView);
                _Brush.Stretch = Windows.UI.Xaml.Media.Stretch.UniformToFill;
                _Brush.AlignmentY = Windows.UI.Xaml.Media.AlignmentY.Top;
                _Brush.Transform = _Rectangle.Tag as Windows.UI.Xaml.Media.TranslateTransform;
                _Rectangle.Fill = _Brush;
            };
            _Pages.Add(_Page);
        }
        return _Pages;
    }

    WebViewBrush GetWebViewBrush(Windows.UI.Xaml.Controls.WebView webView)
    {
        // resize width to content
        var _OriginalWidth = webView.Width;
        var _WidthString = webView.InvokeScriptAsync("eval",
            new[] { "document.body.scrollWidth.toString()" }).GetResults();
        int _ContentWidth;
        if (!int.TryParse(_WidthString, out _ContentWidth))
            throw new Exception(string.Format("failure/width:{0}", _WidthString));
        webView.Width = _ContentWidth;

        // resize height to content
        var _OriginalHeight = webView.Height;
        var _HeightString = webView.InvokeScriptAsync("eval",
            new[] { "document.body.scrollHeight.toString()" }).GetResults();
        int _ContentHeight;
        if (!int.TryParse(_HeightString, out _ContentHeight))
            throw new Exception(string.Format("failure/height:{0}", _HeightString));
        webView.Height = _ContentHeight;

        // create brush
        var _OriginalVisibilty = webView.Visibility;
        webView.Visibility = Windows.UI.Xaml.Visibility.Visible;
        var _Brush = new WebViewBrush
        {
            SourceName = webView.Name,
            Stretch = Windows.UI.Xaml.Media.Stretch.Uniform
        };
        _Brush.Redraw();

        // reset, return
        webView.Width = _OriginalWidth;
        webView.Height = _OriginalHeight;
        webView.Visibility = _OriginalVisibilty;
        return _Brush;
    }
<代码>列表GETWebPage(Windows .U.XAML.Nealth.WebVIEW WebVIEW,Windows .Fask.Stage页面) { //询问内容的宽度 var\u WidthString=webView.InvokeScriptAsync(“eval”, 新建[]{“document.body.scrollWidth.toString()”}).GetResults(); int_ContentWidth; if(!int.TryParse(_WidthString,out_ContentWidth)) 抛出新异常(string.Format(“failure/width:{0}”,_WidthString)); webView.Width=\u ContentWidth; //询问内容的高度 var\u HeightString=webView.InvokeScriptAsync(“eval”, 新建[]{“document.body.scrollHeight.toString()”}).GetResults(); 内部内容高度; 如果(!int.TryParse(_HeightString,out_ContentHeight)) 抛出新异常(string.Format(“failure/height:{0}”,_HeightString)); webView.Height=\u ContentHeight; //有多少页? var _Scale=页面宽度/_内容宽度; var _ScaledHeight=(_ContentHeight*_Scale); var _PageCount=(双精度)_ScaledHeight/page.Height; _PageCount=PageCount+(PageCount>(int)PageCount)?1:0; //创建页面 var_Pages=新列表(); 对于(int i=0;i<(int)\u PageCount;i++) { var_TranslateY=-page.Height*i; var_Page=new Windows.UI.Xaml.Shapes.Rectangle { 高度=页面高度, 宽度=页宽, 边距=新的Windows.UI.Xaml.Thickness(5), Tag=new Windows.UI.Xaml.Media.TranslateTransform{Y=\u TranslateY}, }; _页面加载+=(s,e)=> { var_Rectangle=s作为Windows.UI.Xaml.Shapes.Rectangle; var_Brush=GetWebViewBrush(webView); _Brush.Stretch=Windows.UI.Xaml.Media.Stretch.UniformToFill; _Brush.AlignmentY=Windows.UI.Xaml.Media.AlignmentY.Top; _Brush.Transform=_Rectangle.Tag为Windows.UI.Xaml.Media.TranslateTransform; _矩形填充=_画笔; }; _页面。添加(_页面); } 返回页面; } WebViewBrush GetWebViewBrush(Windows.UI.Xaml.Controls.WebView WebView) { //根据内容调整宽度 var _OriginalWidth=webView.Width; var\u WidthString=webView.InvokeScriptAsync(“eval”, 新建[]{“document.body.scrollWidth.toString()”}).GetResults(); int_ContentWidth; if(!int.TryParse(_WidthString,out_ContentWidth)) 抛出新异常(string.Format(“failure/width:{0}”,_WidthString)); webView.Width=\u ContentWidth; //根据内容调整高度 var _OriginalHeight=webView.Height; var\u HeightString=webView.InvokeScriptAsync(“eval”, 新建[]{“document.body.scrollHeight.toString()”}).GetResults(); 内部内容高度; 如果(!int.TryParse(_HeightString,out_ContentHeight)) 抛出新异常(string.Format(“failure/height:{0}”,_HeightString)); webView.Height=\u ContentHeight; //创建笔刷 var _originalvisibility=webView.Visibility; webView.Visibility=Windows.UI.Xaml.Visibility.Visible; var\u Brush=新的WebViewBrush { SourceName=webView.Name, 拉伸=Windows.UI.Xaml.Media.Stretch.Uniform }; _画笔。重画(); //复位,返回 宽度=_原始宽度; webView.Height=_原始高度; webView.Visibility=_originalVisibility; 回刷; }
@Jerry Nixon的方法对我来说很有效。因为他的代码示例大约在五年前发布在该线程上。对于当前的UWP API,我只做了一些更改(例如,
webView.InvokeScriptAsync
)。我还看到您在代码中调用了
webView.InvokeScriptAsync
方法。那很好。但是你调用
GetResults()
方法,我不建议你调用
GetResults()
方法。因为调用javascript代码有时会花费很多时间。您可能会得到异常
一个方法在意外时间被调用

然后,我也注意到你的打印流程有点混乱。请阅读以了解标准化印刷工艺

您可以查看官方代码示例以了解详细信息

以下是您的代码段的更新代码:

async Task<List<Windows.UI.Xaml.Shapes.Rectangle>> GetWebPages(Windows.UI.Xaml.Controls.WebView webView, Windows.Foundation.Size page)
{
        // ask the content its width
        var _WidthString = await webView.InvokeScriptAsync("eval",
            new[] { "document.body.scrollWidth.toString()" });
        int _ContentWidth;
        if (!int.TryParse(_WidthString, out _ContentWidth))
            throw new Exception(string.Format("failure/width:{0}", _WidthString));
        webView.Width = _ContentWidth;

        // ask the content its height
        var _HeightString = await webView.InvokeScriptAsync("eval",
            new[] { "document.body.scrollHeight.toString()" });
        int _ContentHeight;
        if (!int.TryParse(_HeightString, out _ContentHeight))
            throw new Exception(string.Format("failure/height:{0}", _HeightString));
        webView.Height = _ContentHeight;

        // how many pages will there be?
        var _Scale = page.Width / _ContentWidth;
        var _ScaledHeight = (_ContentHeight * _Scale);
        var _PageCount = (double)_ScaledHeight / page.Height;
        _PageCount = _PageCount + ((_PageCount > (int)_PageCount) ? 1 : 0);

        // create the pages
        var _Pages = new List<Windows.UI.Xaml.Shapes.Rectangle>();
        for (int i = 0; i < (int)_PageCount; i++)
        {
            var _TranslateY = -page.Height * i;
            var _Page = new Windows.UI.Xaml.Shapes.Rectangle
            {
                Height = page.Height,
                Width = page.Width,
                Margin = new Windows.UI.Xaml.Thickness(5),
                Tag = new Windows.UI.Xaml.Media.TranslateTransform { Y = _TranslateY },
            };
            _Page.Loaded +=async (s, e) =>
            {
                var _Rectangle = s as Windows.UI.Xaml.Shapes.Rectangle;
                var _Brush = await GetWebViewBrush(webView);
                _Brush.Stretch = Windows.UI.Xaml.Media.Stretch.UniformToFill;
                _Brush.AlignmentY = Windows.UI.Xaml.Media.AlignmentY.Top;
                _Brush.Transform = _Rectangle.Tag as Windows.UI.Xaml.Media.TranslateTransform;
                _Rectangle.Fill = _Brush;
            };
            _Pages.Add(_Page);
        }
        return _Pages;
}

    async Task<WebViewBrush> GetWebViewBrush(Windows.UI.Xaml.Controls.WebView webView)
    {
        // resize width to content
        var _OriginalWidth = webView.Width;
        var _WidthString = await webView.InvokeScriptAsync("eval",
            new[] { "document.body.scrollWidth.toString()" });
        int _ContentWidth;
        if (!int.TryParse(_WidthString, out _ContentWidth))
            throw new Exception(string.Format("failure/width:{0}", _WidthString));
        webView.Width = _ContentWidth;

        // resize height to content
        var _OriginalHeight = webView.Height;
        var _HeightString = await webView.InvokeScriptAsync("eval",
            new[] { "document.body.scrollHeight.toString()" });
        int _ContentHeight;
        if (!int.TryParse(_HeightString, out _ContentHeight))
            throw new Exception(string.Format("failure/height:{0}", _HeightString));
        webView.Height = _ContentHeight;

        // create brush
        var _OriginalVisibilty = webView.Visibility;
        webView.Visibility = Windows.UI.Xaml.Visibility.Visible;
        var _Brush = new WebViewBrush
        {
            SourceName = webView.Name,
            Stretch = Windows.UI.Xaml.Media.Stretch.Uniform
        };
        _Brush.Redraw();

        // reset, return
        webView.Width = _OriginalWidth;
        webView.Height = _OriginalHeight;
        webView.Visibility = _OriginalVisibilty;
        return _Brush;
    }
<代码>异步任务GETWebPage(Windows .U.XAML.Nealth.WebVIEW WebVIEW,WiDOW.Studio.Stage页面) { //询问内容的宽度 var\u WidthString=wait webView.InvokeScriptAsync(“eval”, 新[]{“document.body.scrollWidth.toString()”}); int_ContentWidth; if(!int.TryParse(_WidthString,out_ContentWidth)) 抛出新异常(string.Format(“failure/width:{0}”,_WidthString)); webView.Width=\u ContentWidth; //询问内容的高度 var\u HeightString=wait webView.InvokeScriptAsync(“eval”, 新[]{“document.body.scrollHeight.toString()”}); int
async Task<List<Windows.UI.Xaml.Shapes.Rectangle>> GetWebPages(Windows.UI.Xaml.Controls.WebView webView, Windows.Foundation.Size page)
{
        // ask the content its width
        var _WidthString = await webView.InvokeScriptAsync("eval",
            new[] { "document.body.scrollWidth.toString()" });
        int _ContentWidth;
        if (!int.TryParse(_WidthString, out _ContentWidth))
            throw new Exception(string.Format("failure/width:{0}", _WidthString));
        webView.Width = _ContentWidth;

        // ask the content its height
        var _HeightString = await webView.InvokeScriptAsync("eval",
            new[] { "document.body.scrollHeight.toString()" });
        int _ContentHeight;
        if (!int.TryParse(_HeightString, out _ContentHeight))
            throw new Exception(string.Format("failure/height:{0}", _HeightString));
        webView.Height = _ContentHeight;

        // how many pages will there be?
        var _Scale = page.Width / _ContentWidth;
        var _ScaledHeight = (_ContentHeight * _Scale);
        var _PageCount = (double)_ScaledHeight / page.Height;
        _PageCount = _PageCount + ((_PageCount > (int)_PageCount) ? 1 : 0);

        // create the pages
        var _Pages = new List<Windows.UI.Xaml.Shapes.Rectangle>();
        for (int i = 0; i < (int)_PageCount; i++)
        {
            var _TranslateY = -page.Height * i;
            var _Page = new Windows.UI.Xaml.Shapes.Rectangle
            {
                Height = page.Height,
                Width = page.Width,
                Margin = new Windows.UI.Xaml.Thickness(5),
                Tag = new Windows.UI.Xaml.Media.TranslateTransform { Y = _TranslateY },
            };
            _Page.Loaded +=async (s, e) =>
            {
                var _Rectangle = s as Windows.UI.Xaml.Shapes.Rectangle;
                var _Brush = await GetWebViewBrush(webView);
                _Brush.Stretch = Windows.UI.Xaml.Media.Stretch.UniformToFill;
                _Brush.AlignmentY = Windows.UI.Xaml.Media.AlignmentY.Top;
                _Brush.Transform = _Rectangle.Tag as Windows.UI.Xaml.Media.TranslateTransform;
                _Rectangle.Fill = _Brush;
            };
            _Pages.Add(_Page);
        }
        return _Pages;
}

    async Task<WebViewBrush> GetWebViewBrush(Windows.UI.Xaml.Controls.WebView webView)
    {
        // resize width to content
        var _OriginalWidth = webView.Width;
        var _WidthString = await webView.InvokeScriptAsync("eval",
            new[] { "document.body.scrollWidth.toString()" });
        int _ContentWidth;
        if (!int.TryParse(_WidthString, out _ContentWidth))
            throw new Exception(string.Format("failure/width:{0}", _WidthString));
        webView.Width = _ContentWidth;

        // resize height to content
        var _OriginalHeight = webView.Height;
        var _HeightString = await webView.InvokeScriptAsync("eval",
            new[] { "document.body.scrollHeight.toString()" });
        int _ContentHeight;
        if (!int.TryParse(_HeightString, out _ContentHeight))
            throw new Exception(string.Format("failure/height:{0}", _HeightString));
        webView.Height = _ContentHeight;

        // create brush
        var _OriginalVisibilty = webView.Visibility;
        webView.Visibility = Windows.UI.Xaml.Visibility.Visible;
        var _Brush = new WebViewBrush
        {
            SourceName = webView.Name,
            Stretch = Windows.UI.Xaml.Media.Stretch.Uniform
        };
        _Brush.Redraw();

        // reset, return
        webView.Width = _OriginalWidth;
        webView.Height = _OriginalHeight;
        webView.Visibility = _OriginalVisibilty;
        return _Brush;
    }