Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to load PDF in Xamarin Forms

I have a Xamarin Forms app where I want to open a locally stored PDF. I don't need to load them within the app, I'm fine with shelling out to the device's default document viewer for PDFs. How can I do this?

I tried sending a WebView to the PDF, but that didn't work, I just got a blank page.

like image 934
Eric Avatar asked Aug 15 '14 14:08

Eric


People also ask

What is WebView in xamarin forms?

The WebView displays the HTML content inside your app and shows how much content is loading in your HTML and web content of your app. This function is available in Xamarin. Forms.

What is xamarin essentials?

Xamarin. Essentials provides a single cross-platform API that works with any iOS, Android, or UWP application that can be accessed from shared code no matter how the user interface is created. See the platform & feature support guide for more information on supported operating systems.


2 Answers

I've recently done this in my own project using a custom renderer. First implement an empty Xamarin forms view such as (I've included a bindable FilePath attribute):

    public class PdfViewer : View
{
    public static readonly BindableProperty FilePathProperty =
        BindableProperty.Create<DocumentViewer, string>(p => p.FilePath, null);

    public string FilePath
    {
        get
        {
            return (string)this.GetValue(FilePathProperty);
        }

        set
        {
            this.SetValue(FilePathProperty, value);
        }
    }
}

Then create an iOS Renderer that will be registered for this control. This renderer can, as it is within an iOS project, use the Quick Look Preview Controller to delegate to the built in iOS pdf viewer:

[assembly: ExportRenderer(typeof(PdfViewer), typeof(DocumentViewRenderer))]

public class DocumentViewRenderer 
        : ViewRenderer<PdfViewer, UIView>
{
    private QLPreviewController controller;

    protected override void OnElementChanged(ElementChangedEventArgs<DocumentViewer> e)
    {
        base.OnElementChanged(e);

        this.controller = new QLPreviewController();
        this.controller.DataSource = new DocumentQLPreviewControllerDataSource(e.NewElement.FilePath);

        SetNativeControl(this.controller.View);
    }

    private class DocumentQLPreviewControllerDataSource : QLPreviewControllerDataSource 
    {
        private string fileName;
        public DocumentQLPreviewControllerDataSource(string fileName)
        {
            this.fileName = fileName;
        }

        public override int PreviewItemCount(QLPreviewController controller) 
        {
            return 1;
        }

        public override QLPreviewItem GetPreviewItem(QLPreviewController controller, int index)
        {
            var documents = NSBundle.MainBundle.BundlePath;
            var library = Path.Combine(documents, this.fileName);
            NSUrl url = NSUrl.FromFilename(library);

            return new QlItem(string.Empty, url);
        }

        private class QlItem : QLPreviewItem 
        { 
            public QlItem(string title, NSUrl uri) 
            { 
                this.ItemTitle = title; 
                this.ItemUrl = uri; 
            } 

            public override string ItemTitle { get; private set; }

            public override NSUrl ItemUrl { get; private set; }
        }
    }
}

I haven't compiled and run this as I've extracted it from my larger project but in general this should work.

like image 131
Cargowire Avatar answered Oct 05 '22 19:10

Cargowire


I had to do something and solve it using a DependencyService . You can use it to open the pdf depending on each platform

I show you an example of how to solve it on Android :

IPdfCreator.cs:

public interface IPdfCreator
    {
        void ShowPdfFile();
    }

MainPage.cs:

private void Button_OnClicked(object sender, EventArgs e)
{
    DependencyService.Get<IPdfCreator>().ShowPdfFile();
}

PdfCreatorAndroid.cs

[assembly: Dependency(typeof(PdfCreatorAndroid))]
namespace Example.Droid.DependecyServices
{
    public class PdfCreatorAndroid : IPdfCreator
    {

        public void ShowPdfFile()
        {
            var fileLocation = "/sdcard/Template.pdf";
            var file = new File(fileLocation);

            if (!file.Exists())
                return;

            var intent = DisplayPdf(file);
            Forms.Context.StartActivity(intent);
        }

        public Intent DisplayPdf(File file)
        {
            var intent = new Intent(Intent.ActionView);
            var filepath = Uri.FromFile(file);
            intent.SetDataAndType(filepath, "application/pdf");
            intent.SetFlags(ActivityFlags.ClearTop);
            return intent;
        }
    }
}

Result: http://i.stack.imgur.com/vrwzt.png

like image 44
Victor Madurga Avatar answered Oct 05 '22 21:10

Victor Madurga