dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
21.83k stars 1.67k forks source link

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

Open SunshineSpring666 opened 1 year ago

SunshineSpring666 commented 1 year ago

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.

ghost commented 1 year ago

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.

Sen-Gupta commented 1 year ago

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)

AmBplus commented 1 year ago

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

kyleweishaupt commented 1 year ago

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

mhrastegari commented 1 year ago

Maybe considering it on the Toolkit? 👀 @brminnick

MichaelHall001 commented 11 months ago

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

stipar commented 11 months ago

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.

lovinmaxwell commented 10 months ago

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

BartRennes commented 9 months ago

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

LOrellanaCarrion commented 9 months ago

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 ?

RNavaneethKumar commented 9 months ago

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

PrabhuRout007 commented 7 months ago
#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.

Luca-21 commented 5 months ago

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?

deeprobin commented 4 months ago

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

BartRennes commented 4 months ago

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 :(

wstaelens commented 1 month ago

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?

dbSoft-SoftwareSolutions commented 1 month ago

We also need this future for printing receipts and invoices

deeprobin commented 1 month ago

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.

wstaelens commented 1 month ago

@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.

deeprobin commented 1 month ago

@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.

wstaelens commented 1 month ago

@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...

dbSoft-SoftwareSolutions commented 1 month ago

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?

deeprobin commented 1 month ago

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

RyansBello commented 2 weeks ago

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

danieltharris commented 1 week ago

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.

negberts commented 1 week ago

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