Печать WebView с несколькими страницами в Xamarin UWP - PullRequest
0 голосов
/ 22 мая 2018

Я пытаюсь распечатать веб-страницу в формах xamarin.Я использую DependencyService для печати веб-просмотра, который я успешно реализовал в Android.

Для Windows UWP, я ссылался на эту ссылку:
https://forums.xamarin.com/discussion/91163/problem-with-printing-webview-in-uwp-phone
Подход, используемый в этомпечать только первой страницы веб-страницы.

Редактировать :
Я создал интерфейс IPrint, предоставляющий функции только источник html.

public interface IPrint
{
    void PrintAsync(string htmlSource);
}

В PrintAsyncфункция (в проекте Windows UWP),

    async void IPrint.PrintAsync(string htmlSource)
    {
        ViewToPrint.NavigateToString(htmlSource);
        ViewToPrint.LoadCompleted += ViewToPrint_LoadCompleteAsync;
    }

Когда 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();
    }


Чтобы реализовать печать нескольких страниц, Я ссылался на эту ссылку: https://stackoverflow.com/a/17222629/6366591

Я изменил функцию 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;
    }

1 Ответ

0 голосов
/ 24 мая 2018

@ Метод Джерри Никсона хорошо сработал на моей стороне.Так как его пример кода был размещен в этой теме около пяти лет назад.Для текущих API UWP я только что сделал небольшие изменения (например, webView.InvokeScriptAsync).Я также видел, что вы вызываете метод webView.InvokeScriptAsync в своем коде.Это хорошо.Но вы вызываете метод GetResults(), я не предлагал вам вызывать метод GetResults().Потому что вызов кода JavaScript иногда отнимает у вас много времени.Вы можете получить исключение A method was called at an unexpected time.

Затем я также заметил, что ваш процесс печати немного беспорядок.Пожалуйста, прочитайте Печать из вашего приложения , чтобы узнать стандартизированный процесс печати. ​​

Вы можете проверить официальный образец кода Образец печати для получения подробной информации.

Ниже был обновленный код вашего фрагмента кода:

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;
    }

Я использовал Образец печати и вставил в него мой обновленный код, приведенный выше, и сделал некоторые соответствующие изменения, после чего я мог бы распечатать всю сеть.страницы успешно.

...