打印以编程方式创建的矩形

问题描述

我想将 WebView 设置为 WebViewBrush添加内部矩形和打印矩形。我想在后端做所有事情,我不想使用 XAML 代码

我这样做是因为当我获得打印预览时会看到模糊/模糊的文本。所以人们说解决这个问题的方法是创建WebViewBrush,然后创建一个矩形来打印

首先我创建画布和画笔:

  private Windows.UI.Xaml.Controls.WebView ViewToPrint = new Windows.UI.Xaml.Controls.WebView();
  private Windows.UI.Xaml.Controls.WebViewBrush wvBrush = new Windows.UI.Xaml.Controls.WebViewBrush();
  private Windows.UI.Xaml.Shapes.Rectangle rectangle = new Windows.UI.Xaml.Shapes.Rectangle();

然后在方法中我将 WebView 分配给 WebViewBrush 并将其添加到矩形中,

public async void Print(Xamarin.Forms.WebView viewToPrint,string html)
        {
        ViewToPrint.NavigatetoString(html);
        wvBrush.SetSource(ViewToPrint);
        wvBrush.Redraw();
        rectangle.Fill = wvBrush;
        rectangle.Width = 200;
        rectangle.Height = 200;

        }

然后在打印预览方法中,我想将矩形预览视为:

 private void PrintDoc_GetPreviewPage(object sender,GetPreviewPageEventArgs e)
        {
           
            printDoc.SetPreviewPage(e.PageNumber,rectangle);
        }

但是我的矩形是空白的,我看不到里面的任何东西。我做错了什么

重现问题:

Xamarin 共享项目类:

   private readonly IPrintUWPService _printUWPService = DependencyService.Get<IPrintUWPService>();

   public void Printhtml()
        {
        
   var Meta = "<Meta name='viewport' content='width=device-width,initial-scale=5.0,maximum-scale=5.0,minimum-scale=1.0'>";
            var style = "<style>svg{height:140px; width:140px;} p{font-size:20px;} </style>";

         var  _htmlSource = @$"
                    <!DOCTYPE html>
                    <html>
                    <head>
                      {Meta}
                       {style}
                    </head>
                    <body>
                   <table border = '1px solid'; style='border-collapse:collapse;'>
                    <tbody>
                    <tr>
                    <td>qr</td>
                    <td>
                    <p><b>Heat Number:number</b></p>
                    <p><b> Cylinder Type Name: cylindername</b></p>
                   <p><b> Color: colorname</b></p>
                    </td>
                    </tr>
                    </tbody>
                    </table>
                    </body>
                    </html>
                    ";
          Print(_htmlSource);

        }
     

  public void Print(string _htmlSource)
        {
            _printUWPService.Print( _htmlSource);
        }

共享项目中的接口:

public interface IPrintUWPService
    {
        void Print(string html);
    }

UWP 项目服务:

 public class PrintUWPService : IPrintUWPService
    {
        PrintManager printmgr = PrintManager.GetForCurrentView();
        PrintDocument PrintDoc;
        PrintDocument printDoc;
        PrintTask Task;
        private Windows.UI.Xaml.Controls.WebView ViewToPrint = new Windows.UI.Xaml.Controls.WebView();
        private DeviceinformationCollection deviceCollection;
        private Windows.UI.Xaml.Shapes.Rectangle rectangle = new Windows.UI.Xaml.Shapes.Rectangle();


        public PrintUWPService()
        {
            printmgr.PrintTaskRequested += Printmgr_PrintTaskRequested;
        }

        public async void Print(Xamarin.Forms.WebView viewToPrint,string html)
        {


            ViewToPrint.NavigatetoString(html);
            //MakePage();


            if (PrintDoc != null)
            {
                printDoc.GetPreviewPage -= PrintDoc_GetPreviewPage;
                printDoc.Paginate -= PrintDoc_Paginate;
                printDoc.AddPages -= PrintDoc_AddPages;
            }

            printDoc = new PrintDocument();

            try
            {
                printDoc.GetPreviewPage += PrintDoc_GetPreviewPage;
                printDoc.Paginate += PrintDoc_Paginate;
                printDoc.AddPages += PrintDoc_AddPages;

                var showprint = PrintManager.ShowPrintUIAsync();

            }
            catch (Exception e)
            {
                Debug.WriteLine(e.ToString());
            }

            PrintDoc = null;
            GC.Collect();
        }

        private void MakePage()
        {
            var brush = new WebViewBrush
            {
                Stretch = (Windows.UI.Xaml.Media.Stretch)Windows.UI.Xaml.Media.Stretch.Uniform
            };
            
            brush.SetSource(ViewToPrint);
            brush.Redraw();

            using (var waitHandle = new System.Threading.ManualResetEventSlim(initialState: false))
                waitHandle.Wait(TimeSpan.FromMilliseconds(5000));

            rectangle.Width = 200;
            rectangle.Height = 200;
            rectangle.Fill = brush;
            brush.Stretch = (Windows.UI.Xaml.Media.Stretch)Windows.UI.Xaml.Media.Stretch.UniformToFill;
            brush.AlignmentY = AlignmentY.Top;
            rectangle.Name = "MyWebViewRectangle";

            rectangle.Visibility = Windows.UI.Xaml.Visibility.Visible;
        }

        private void Printmgr_PrintTaskRequested(PrintManager sender,PrintTaskRequestedEventArgs args)
        {
            var deff = args.Request.GetDeferral();
            Task = args.Request.CreatePrintTask($"Card Stock { DateTime.Now}",OnPrintTaskSourceRequested);

            deff.Complete();

        }
        async void OnPrintTaskSourceRequested(PrintTaskSourceRequestedArgs args)
        {

            var def = args.GetDeferral();
            await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.dispatcher.RunAsync(Windows.UI.Core.CoredispatcherPriority.normal,() =>
            {
                args.SetSource(printDoc.DocumentSource);
            });
            def.Complete();
        }

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

        private async void PrintDoc_Paginate(object sender,PaginateEventArgs e)
        {
            PrintTaskOptions printingOptions = ((PrintTaskOptions)e.PrintTaskOptions);
            deviceCollection =  await Deviceinformation.FindAllAsync("System.Devices.InterfaceClassGuid:=\"{0ecef634-6ef0-472a-8085-5ad023ecbccd}\"");
           var rolloPrinter = deviceCollection.Where(x => x.Name.Contains("Rollo")).SingleOrDefault();

            // Get the page description to deterimine how big the page is
            PrintPageDescription pageDescription = printingOptions.GetPageDescription(0);

            PrintTaskOptions opt = Task.Options;

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

        private  void PrintDoc_GetPreviewPage(object sender,GetPreviewPageEventArgs e)
        {
            printDoc.SetPreviewPage(e.PageNumber,rectangle);
        }

      
    }

解决方法

用 WebView 数据填充矩形

根据您的描述,在调用 print api 之前,您似乎没有在 xaml 中呈现矩形。并将其插入到 Route::get('search',[HomeController::class,'search'])->name('search'); 页面中。请参考此案例 reply 并首先渲染矩形。

printDoc

更新

在检查你的代码时,我找到了原因,问题是你没有在可视化树中呈现你的 WebView,使 Rectangle page = (Rectangle)this.FindName("MyWebViewRectangle"); printDoc.AddPage(page); printDoc.AddPagesComplete(); 不起作用。 通常需要在与 WebView 源代码相同的 UI 中为在 XAML 中声明的 WebViewBrush 调用 Redraw。有关更多信息,请参阅 this

您可以使用以下行来验证这一点。

WebViewBrush