如何从Xamarin.Forms UWP打印pdf文档?

时间:2019-03-26 12:00:47

标签: c# xamarin.forms printing uwp

我有一个Xamarin.Forms应用程序,仅支持UWP。我找不到打印pdf文档的方法。无论我在网上看到什么,由于某种原因对我都不起作用。例如。我尝试过

https://www.syncfusion.com/kb/8767/how-to-print-pdf-documents-in-xamarin-forms-platform

它可以打印,但是打印对话框中的预览永远不会显示,并且进度指示器永远保持旋转状态。

我也尝试过http://zawayasoft.com/2018/03/13/uwp-print-pdf-files-silently-without-print-dialog/ 这给了我无法修复的错误。

因此,我想知道是否有人可以提出其他可行的建议。也许比我尝试过的要新(我使用VS 2017)。没有打印对话框的打印将是更可取的。

谢谢。

1 个答案:

答案 0 :(得分:1)

我用一个很脏的黑客来做到这一点!

我要做的是尝试打印pdf的图像版本(我在后端进行了转换),然后使用了以下DependencyInjection:

在UWP项目的Print类中:

class Print : IPrint
    {
        void IPrint.Print(byte[] content)
        {
            Print_UWP printing = new Print_UWP();
            printing.PrintUWpAsync(content);
        }
    }

和负责在uwp中打印的类:

 public class Print_UWP
    {
        PrintManager printmgr = PrintManager.GetForCurrentView();
        PrintDocument PrintDoc = null;
        PrintDocument printDoc;
        PrintTask Task = null;
        Windows.UI.Xaml.Controls.Image ViewToPrint = new Windows.UI.Xaml.Controls.Image();

        public Print_UWP()
        {

            printmgr.PrintTaskRequested += Printmgr_PrintTaskRequested;
        }

        public async void PrintUWpAsync(byte[] imageData)
        {
            int i = 0;

            while (i < 5)
            {
                try
                {
                    BitmapImage biSource = new BitmapImage();
                    using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
                    {
                        await stream.WriteAsync(imageData.AsBuffer());
                        stream.Seek(0);
                        await biSource.SetSourceAsync(stream);
                    }

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

                    this.printDoc = new PrintDocument();
                    try
                    {
                        printDoc.GetPreviewPage += PrintDoc_GetPreviewPage;
                        printDoc.Paginate += PrintDoc_Paginate;
                        printDoc.AddPages += PrintDoc_AddPages;

                        bool showprint = await PrintManager.ShowPrintUIAsync();

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

                    //  printmgr = null;
                    // printDoc = null;
                    // Task = null;
                    PrintDoc = null;
                    GC.Collect();
                    printmgr.PrintTaskRequested -= Printmgr_PrintTaskRequested;
                    break;
                }
                catch (Exception e)
                {
                    i++;
                }

            }
        }

        private void Printmgr_PrintTaskRequested(PrintManager sender, PrintTaskRequestedEventArgs args)
        {
            var deff = args.Request.GetDeferral();
            Task = args.Request.CreatePrintTask("Invoice", 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(ViewToPrint);
            printDoc.AddPagesComplete();
        }

        private void PrintDoc_Paginate(object sender, PaginateEventArgs e)
        {
            PrintTaskOptions opt = Task.Options;
            printDoc.SetPreviewPageCount(1, PreviewPageCountType.Final);
        }

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

    }

请注意,这不是一个完美的解决方案,有时会崩溃,而实际上却无法跟踪异常(这确实很奇怪),因此,我敢肯定,即使这样做确实可以解决问题。