maui icon indicating copy to clipboard operation
maui copied to clipboard

[Feature Request] Printing UI for MAUI Windows/Android/iOS

Open SunshineSpring666 opened this issue 3 years ago • 26 comments

Description

MAUI is awesome. Some OA and LOB apps need basic functionalities like printing files (documents, images, receipts, etc.). Existing code which works for Xamarin raises puzzling exceptions when migrated to MAUI projects. To my knowledge, there are no such libs for MAUI now. Any clues on how to get "printing by printer" functionality in MAUI (on Windows/Android/iOS)?

Thanks to the great Syncfusion team, a Xamarin Printing demo with sample project could be found, it works basically ok in Xamarin, but when migrated to MAUI, the Windows code raises exceptions like "Interface not registered", "Class not registered", etc. Some issues are solved by replacing UI Dispatcher with Dispatcher Queue, and using PrintManagerInterop; while still no clues on these "xxx not registered" issues. These issues seems to be raised due to switching to WindowsAppSDK WinUI3 in MAUI?

Note that the Android implementation above crashes with exception on MAUI, too.

Public API Changes

Developer pass a file stream / path to the API, it popup a UI showing Printing preview/configurations.

Intended Use-Case

Many to-B and to-C apps (including warehouse management, line-of-business, office automation, retail apps) need the functionality of printing documents/receipts/invoices by passing a file to the printer.

SunshineSpring666 avatar Sep 06 '22 04:09 SunshineSpring666

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

ghost avatar Sep 06 '22 18:09 ghost

This is just plain non-sense to have a product released in market without basic printing capability available? Microsoft Printers are not obsolete, they are still being used in each POS application. MAUI can't be used for even a simple POS system?

(Been on Microsoft Tech Stack for entire career)

Sen-Gupta avatar Apr 12 '23 15:04 Sen-Gupta

this is one of strangest things , the printing is a very basic fuctionality but in maui android we can't do that , i developed an app for customer and i never think such simple thing not implmented yet ,for now it's seem maui app for android is very bad choice for enterprize application , please soon implmented it

AmBplus avatar Apr 14 '23 09:04 AmBplus

Hope this can be addressed soon. I too am working on a MAUI app that could use a native print preview dialog.

kyleweishaupt avatar May 31 '23 20:05 kyleweishaupt

Maybe considering it on the Toolkit? 👀 @brminnick

mhrastegari avatar Jun 22 '23 21:06 mhrastegari

That is insane you put .net MAUI out there without printer support.

MichaelHall001 avatar Aug 04 '23 17:08 MichaelHall001

Es hilo se generó casi 1 año atras, es increible que despues de tanto tiempo todavía no haya solución, para imprimir, en windows encontre un solucion y funciona bien, pero para iOS y Android todavía nada, la verdad una verguenza.

stipar avatar Aug 04 '23 19:08 stipar

Its been one year now, still issues is not closed yet

lovinmaxwell avatar Sep 04 '23 07:09 lovinmaxwell

Do we have to wait for the MAUI successor to get printing capabilities?

BartRennes avatar Sep 27 '23 12:09 BartRennes

Es hilo se generó casi 1 año después, es increíble que después de tanto tiempo todavía no haya solución, para imprimir, en windows encontré una solución y funciona bien, pero para iOS y Android todavía nada, la verdad una verguenza.

Cual es la solucion que haz encontrado, la puedes compartir ?

LOrellanaCarrion avatar Sep 27 '23 23:09 LOrellanaCarrion

Has anyone managed to find a workaround to print from MAUI application?

RNavaneethKumar avatar Sep 29 '23 06:09 RNavaneethKumar

#if MACCATALYST
using CoreGraphics;
using Foundation;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UIKit;
{
    public class PrintonMac

    {
        public async void PrintImage(Stream img)
        {
            try 
            {
                var data = NSData.FromStream(img);
                var uiimage = UIImage.LoadFromData(data);

                var printer = UIPrintInteractionController.SharedPrintController;

                if (printer == null)
                {
                    Debug.WriteLine("Printer is not connected");
                }
                else
                {

                    var printInfo = UIPrintInfo.PrintInfo;
                    printInfo.OutputType = UIPrintInfoOutputType.General;
                    printer.PrintInfo = printInfo;
                    printer.PrintingItem = uiimage;

                    var handler = new UIPrintInteractionCompletionHandler((printInteractionController, completed, error) =>
                    {
                        if (completed)
                        {
                            Debug.WriteLine("Printer Success");
                        }
                        else if (!completed && error != null)
                        {
                            Debug.WriteLine("Print Failed");
                        }

                    });

                    CGRect frame = new CGRect();
                    frame.Size = uiimage.Size;
                    printer.Present(true, handler);
                }
            }
            catch (Exception ex) 
            {
                LogHandler.LogError(ex);
            }
        }
    }
}
#endif

in .cs on button event add

#if MACCATALYST
            var filepath = selectedImages.FirstOrDefault();
            var openFile = System.IO.File.OpenRead(filepath);
            _printServicesMac = new PrintServicesMac();
            _printServicesMac.PrintImage(openFile);

This will work for mac and IOS.

PrabhuRout007 avatar Nov 27 '23 07:11 PrabhuRout007

I use this PrintDocumentAdapter but it works only with bitmap. I can print only image and pdf and it doesn't work perfectly. Has anyone found any other solution?

Luca-21 avatar Jan 30 '24 09:01 Luca-21

I am in favour of creating a general cross-platform API for printing, which could serve as the basis for the MAUI implementation.

Maybe you would like to share your thoughts under the following issue: https://github.com/dotnet/runtime/issues/75628

deeprobin avatar Feb 26 '24 17:02 deeprobin

No basic printing, that's the reason i'm moving to Flutter. It is great to speak about a cross-platform API for printing but after some years still nothing :(

BartRennes avatar Feb 27 '24 08:02 BartRennes

No basic printing, that's the reason i'm moving to Flutter. It is great to speak about a cross-platform API for printing but after some years still nothing :(

Any updates from the MAUI team?

wstaelens avatar May 15 '24 09:05 wstaelens

We also need this future for printing receipts and invoices

There is already a great deal of interest in printing. I hope that the maintainers will realize this at some point so that we can shed light on the topic in .NET 9 or 10 at the latest.

Perhaps we should push this issue forward, which could serve as the base abstraction and implementation for MAUI.

deeprobin avatar May 22 '24 07:05 deeprobin

@deeprobin there are fixes on the way for XPS after ±10 years, planned to be included in .net 9 but the team doesn't review or make any progress anymore it seems... See: https://github.com/dotnet/runtime/pull/97898

I wish you good luck with pushing issues forward, like I did in the last years... Guess printing and xps isn't as sexy as the projects that @davidfowl is working on and this is why they keep everything printing in some dark cave in Redmond. XPS is a far more beautiful format compared to the mess and horrors i've seen in PDF files, but in general everything print related seems to be a forbitten territory nowadays.

Really don't understand what is going on there at Microsoft. I hope @ericstj of @jeffhandley will follow up.

wstaelens avatar May 22 '24 07:05 wstaelens

@wstaelens I could imagine that Printing is also a place in the Windows Kernel that (understandably) nobody wants to deal with ...

Does NT actually have a product owner / area owner for printing? Maybe we should talk to him about plans for the future etc.

deeprobin avatar May 22 '24 07:05 deeprobin

@deeprobin I guess there is no more such a team like in the days with Feng Yuan, Bobby Mattappally, Ashwin, Alan Morris, Ron Martinsen etc...

wstaelens avatar May 22 '24 08:05 wstaelens

Does anyone found any 3d party plugin for this? At least for andoid? I found Plugin.BLE but it doesn't seems to work. Does anyone found something similar?

Does anyone found any 3d party plugin for this? At least for andoid? I found Plugin.BLE but it doesn't seems to work. Does anyone found something similar?

I am not familiar with MAUI in depth. However, the Android API itself offers printing functionality (package android.print).

If the effort is not too great, you might implement e.g. some wrapper around this: https://developer.android.com/reference/android/print/package-summary

deeprobin avatar May 22 '24 10:05 deeprobin

It's been two years now, and no comment from MAUI. It seems funny to build on top of Windows and not support the print function on its main OS. The term Multi-platform App UI doesn't seem so right at this point

RyansBello avatar Jun 18 '24 14:06 RyansBello

Has anyone managed to find a workaround to print from MAUI application?

Which platform do you need to print on?

I don't have a workaround yet (only just looking to do this today), but something I'm going to try (and have had success with in a different context) is standing up a service on a Windows machine connected to the printer in question and submitting the request that way.

It won't work for everybody in all situations but my use case is a LOB app so the users won't be moving around and printing from all different places, so I don't even need it to be done from the device directly.

If I go down this route and it works I'll upload it in case it's useful to anybody else.

danieltharris avatar Jun 28 '24 15:06 danieltharris

On Android this works for us:

public Task PrintAsync(string html, string jobName)
{
    TaskCompletionSource<bool> taskCompletionSource = new TaskCompletionSource<bool>();
    try
    {
        string htmlToPrint = $"<!DOCTYPE html><html><head><link href=\"https://fonts.googleapis.com/css2?family=Libre+Barcode+39+Extended+Text&display=swap\" rel=\"stylesheet\"></head><body>{html}</body></html>";

        using var webView = new global::Android.Webkit.WebView(global::Android.App.Application.Context);

        var activity = Microsoft.Maui.ApplicationModel.Platform.CurrentActivity;
        using PrintManager printManager = (PrintManager)activity.GetSystemService(Context.PrintService);

        webView.LoadData(htmlToPrint, null, null);

        using PrintAttributes printAttribute = new PrintAttributes.Builder()
                                            .SetMediaSize(PrintAttributes.MediaSize.NaLetter)
                                            .Build();

        using var adapter = webView.CreatePrintDocumentAdapter(jobName);
        using var printJob = printManager.Print(jobName, adapter, printAttribute);

        taskCompletionSource.SetResult(true);
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "Something went wrong printing.");
        taskCompletionSource.SetResult(false);
    }

    return taskCompletionSource.Task;
}

We use it to print barcodes from the app.

Getting the html with javascript:

<script> function getBarcodesHtml() { // Get element with the specified ID name var div = document.getElementById("printBlock"); return div.innerHTML; } </script>

And calling the print function like this:

private async void Print()
{
    string html = await JsRuntime.InvokeAsync<string>("getBarcodesHtml");

    await PrintService.PrintAsync(html, "PrintBarcodes");
}

negberts avatar Jun 29 '24 06:06 negberts

PrintManager manager = PrintManager.GetForCurrentView();
await PrintManager.ShowPrintUIAsync();

The above worked on Xamarin(UWP), but an exception was thrown on MAUI(WinUI3). but I specify the window handle and declare runFullTrust in Package.appxmanifest, the following worked on MAUI(WinUI3).

IntPtr hwnd = ((MauiWinUIWindow)App.Current.Windows[0].Handler.PlatformView).WindowHandle;
PrintManager manager = PrintManagerInterop.GetForWindow(hwnd);
IntPtr hwnd = ((MauiWinUIWindow)App.Current.Windows[0].Handler.PlatformView).WindowHandle;
await PrintManagerInterop.ShowPrintUIForWindowAsync(hwnd);

ratocinoue avatar Mar 06 '25 03:03 ratocinoue