如何打印 WebView 内容 C# UWP Win 10 [英] How do I print WebView content C# UWP Win 10

查看:20
本文介绍了如何打印 WebView 内容 C# UWP Win 10的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我搜索了如何将简单的 WebView 打印为:

 

我尝试了很多东西:

注意:我是 XAML 语言及其背后的逻辑的新手.

我想了解如何执行此操作以及是否可行?

这是我的 PageToPrint.xaml.cs 背后的代码:

使用系统;使用 System.Collections.Generic;使用 Windows.UI.Xaml;使用 Windows.UI.Xaml.Controls;使用 Windows.UI.Xaml.Media;使用 Windows.UI.Xaml.Navigation;命名空间 TestPrint{///<总结>///要发送到打印机的页面内容///</总结>公共密封部分类 PageToPrint : Page{公共 RichTextBlock TextContentBlock { 获取;放;}公共 PageToPrint(){this.InitializeComponent();文本内容块 = 文本内容;MyWebView.LoadCompleted += MyWebView_LoadCompletedAsync;}异步无效 MyWebView_LoadCompletedAsync(对象发送者,NavigationEventArgs e){MyWebViewRectangle.Fill = await GetWebViewBrushAsync(MyWebView);MyPrintPages.ItemsSource = await GetWebPagesAsync(MyWebView, new Windows.Foundation.Size(100d, 150d));MyWebView.Visibility = Windows.UI.Xaml.Visibility.Visible;}异步 System.Threading.Tasks.TaskGetWebViewBrushAsync(WebView webView){//根据内容调整宽度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;//根据内容调整高度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;//创建画笔var _OriginalVisibilty = webView.Visibility;webView.Visibility = Windows.UI.Xaml.Visibility.Visible;var _Brush = 新的 WebViewBrush{SourceName = webView.Name,拉伸 = 拉伸.均匀};_Brush.Redraw();//重置,返回webView.Width = _OriginalWidth;webView.Height = _OriginalHeight;webView.Visibility = _OriginalVisibilty;返回_Brush;}异步 System.Threading.Tasks.Task>GetWebPagesAsync(WebView webView, Windows.Foundation.Size page){//询问内容的宽度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;//询问内容的高度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;//会有多少页?var _Scale = page.Width/_ContentWidth;var _ScaledHeight = (_ContentHeight * _Scale);var _PageCount = (double)_ScaledHeight/page.Height;_PageCount = _PageCount + ((_PageCount > (int)_PageCount) ? 1 : 0);//创建页面var _Pages = new List();for (int i = 0; i < (int)_PageCount; i++){var _TranslateY = -page.Height * i;var _Page = 新的 Windows.UI.Xaml.Shapes.Rectangle{高度 = 页.高度,宽度 = 页.宽度,边距 = 新厚度(5),标签 = 新的 TranslateTransform { Y = _TranslateY },};_Page.Loaded += async (s, e) =>{var _Rectangle = s as Windows.UI.Xaml.Shapes.Rectangle;var _Brush = 等待 GetWebViewBrushAsync(webView);_Brush.Stretch = Stretch.UniformToFill;_Brush.AlignmentY = AlignmentY.Top;_Brush.Transform = _Rectangle.Tag as TranslateTransform;_Rectangle.Fill = _Brush;};_Pages.Add(_Page);}返回_Pages;}}}

解决方案

为了您的要求,我简化了

我已将代码示例上传到github,您可以参考.

I've searched how to print a simple WebView as :

 <WebView x:Name="MyWebView" Source="http://www.stackoverflow.com" />

I tried many things as :

How do I print WebView content in a Windows Store App?

This solution is sadly not updated for Windows 10 UWP apps, but, I converted it so the obsoletes functions would work that leads me to another problem.

To print, I used some classes from the sample (Windows-universal-samples/Samples/Printing/cs/) because I need the preview. I put the example given in the above mentioned question as :

<RichTextBlock
    x:Name="TextContent"
    Grid.Row="1"
    Grid.ColumnSpan="2"
    Width="595"
    HorizontalAlignment="Center"
    VerticalAlignment="Top"
    Foreground="Black"
    IsTextSelectionEnabled="True"
    OverflowContentTarget="{Binding ElementName=FirstLinkedContainer}">
        <Paragraph>
            <InlineUIContainer> [The question XAML]

The overflow is not managed, and so the WebView is seen like this : Note: I'm new to XAML language and the logic behind this.

I would like an update on how to do this and if this is possible ?

EDIT:

Here's the code behind of my PageToPrint.xaml.cs :

using System;
using System.Collections.Generic;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

namespace TestPrint
{
    /// <summary>
    /// Page content to send to the printer
    /// </summary>
    public sealed partial class PageToPrint : Page
    {
        public RichTextBlock TextContentBlock { get; set; }

        public PageToPrint()
        {
            this.InitializeComponent();
            TextContentBlock = TextContent;
            MyWebView.LoadCompleted += MyWebView_LoadCompletedAsync;
        }

        async void MyWebView_LoadCompletedAsync(object sender, NavigationEventArgs e)
        {
            MyWebViewRectangle.Fill = await GetWebViewBrushAsync(MyWebView);
            MyPrintPages.ItemsSource = await GetWebPagesAsync(MyWebView, new Windows.Foundation.Size(100d, 150d));
            MyWebView.Visibility = Windows.UI.Xaml.Visibility.Visible;
        }

        async System.Threading.Tasks.Task<WebViewBrush> GetWebViewBrushAsync(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 = Stretch.Uniform
            };
            _Brush.Redraw();

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

        async System.Threading.Tasks.Task<IEnumerable<FrameworkElement>> GetWebPagesAsync(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 Thickness(5),
                    Tag = new TranslateTransform { Y = _TranslateY },
                };
                _Page.Loaded += async (s, e) =>
                {
                    var _Rectangle = s as Windows.UI.Xaml.Shapes.Rectangle;
                    var _Brush = await GetWebViewBrushAsync(webView);
                    _Brush.Stretch = Stretch.UniformToFill;
                    _Brush.AlignmentY = AlignmentY.Top;
                    _Brush.Transform = _Rectangle.Tag as TranslateTransform;
                    _Rectangle.Fill = _Brush;
                };
                _Pages.Add(_Page);
            }
            return _Pages;
        }
    }
}

解决方案

For your requment, I simplified the PrintHelper of official sample and created a simple sample to print WebView via use WebViewBrush.

<Page.BottomAppBar>
    <CommandBar>
        <AppBarButton
            x:Name="appbar_Printer"
            Click="appbar_Printer_Click"
            Label="printer" />
    </CommandBar>
</Page.BottomAppBar>

<Grid x:Name="PrintArea" Background="White">

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="995" />
        <ColumnDefinition Width="300" />
        <ColumnDefinition  Width="50"/>

    </Grid.ColumnDefinitions>

    <WebView Grid.Column="0" x:Name="MyWebView" Source="http://www.stackoverflow.com" HorizontalAlignment="Right" />
    <Rectangle Grid.Column="1" x:Name="MyWebViewRectangle" Fill="Red" />
    <Button Grid.Column="2" Content="Print"  HorizontalAlignment="Center"/>

</Grid>

When the WebView load completed, you could add the MyWebViewRectangle that fill with WebViewBrush to printDoc.

private async void appbar_Printer_Click(object sender, RoutedEventArgs e)
{
    if (printDoc != null)
    {
        printDoc.GetPreviewPage -= OnGetPreviewPage;
        printDoc.Paginate -= PrintDic_Paginate;
        printDoc.AddPages -= PrintDic_AddPages;
    }
    this.printDoc = new PrintDocument();
    printDoc.GetPreviewPage += OnGetPreviewPage;
    printDoc.Paginate += PrintDic_Paginate;
    printDoc.AddPages += PrintDic_AddPages;
    bool showPrint = await PrintManager.ShowPrintUIAsync();
}
private void PrintDic_AddPages(object sender, AddPagesEventArgs e)
{
    Rectangle page = (Rectangle)this.FindName("MyWebViewRectangle");
    printDoc.AddPage(page);
    printDoc.AddPagesComplete();
}
private void PrintDic_Paginate(object sender, PaginateEventArgs e)
{
    PrintTaskOptions opt = task.Options;
    PrintTaskOptionDetails printDetailedOptions = PrintTaskOptionDetails.GetFromPrintTaskOptions(e.PrintTaskOptions);

    printDoc.SetPreviewPageCount(1, PreviewPageCountType.Final);
}

I have uploaded the code sample to github that you could refer to.

这篇关于如何打印 WebView 内容 C# UWP Win 10的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆