如何在Xamarin表单中加载PDF

如何在Xamarin表单中加载PDF,xamarin,xamarin.forms,Xamarin,Xamarin.forms,我有一个Xamarin表单应用程序,我想在其中打开本地存储的PDF。我不需要在应用程序中加载它们,我可以使用设备的默认PDF文档查看器。我该怎么做 我尝试将WebView发送到PDF,但没有成功,我只得到了一个空白页面。我最近在自己的项目中使用自定义渲染器完成了这项工作。首先实现一个空的Xamarin表单视图,例如(我已经包括了一个可绑定的FilePath属性): 公共类PdfViewer:视图 { 公共静态只读BindableProperty FilePathProperty= Create(

我有一个Xamarin表单应用程序,我想在其中打开本地存储的PDF。我不需要在应用程序中加载它们,我可以使用设备的默认PDF文档查看器。我该怎么做


我尝试将WebView发送到PDF,但没有成功,我只得到了一个空白页面。

我最近在自己的项目中使用自定义渲染器完成了这项工作。首先实现一个空的Xamarin表单视图,例如(我已经包括了一个可绑定的FilePath属性):

公共类PdfViewer:视图
{
公共静态只读BindableProperty FilePathProperty=
Create(p=>p.FilePath,null);
公共字符串文件路径
{
得到
{
返回(字符串)this.GetValue(FilePathProperty);
}
设置
{
this.SetValue(FilePathProperty,value);
}
}
}
然后创建将为此控件注册的iOS呈现程序。此渲染器可以在iOS项目中使用来委托给内置的iOS pdf查看器:

[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; }
        }
    }
}
[程序集:ExportRenderer(typeof(PdfViewer)、typeof(DocumentViewRenderer))]
公共类DocumentViewRenderer
:视图渲染器
{
专用控制器;
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
基础。一个要素发生变化(e);
this.controller=new QLPreviewController();
this.controller.DataSource=新文档qlpreviewcontrollerdatasource(e.NewElement.FilePath);
SetNativeControl(this.controller.View);
}
私有类文档QLPreviewController数据源:QLPreviewController数据源
{
私有字符串文件名;
公共文档QLPreviewController数据源(字符串文件名)
{
this.fileName=文件名;
}
公共覆盖int PreviewItemCount(QLViewController控制器)
{
返回1;
}
公共覆盖QLViewWitem GetPreviewWitem(QLViewController控制器,int索引)
{
var documents=NSBundle.MainBundle.BundlePath;
var library=Path.Combine(文档,this.fileName);
NSUrl url=NSUrl.FromFilename(库);
返回新的QlItem(string.Empty,url);
}
私有类QlItem:QlPreviewWitem
{ 
公共QlItem(字符串标题,NSUrl uri)
{ 
this.ItemTitle=标题;
this.ItemUrl=uri;
} 
公共重写字符串ItemTitle{get;private set;}
公共覆盖NSUrl ItemUrl{get;private set;}
}
}
}

我还没有编译和运行它,因为我是从我更大的项目中提取出来的,但总的来说,这应该是可行的。

我必须做一些事情,并使用DependencyService解决它。您可以使用它打开pdf,具体取决于每个平台

我向您展示了如何在Android上解决此问题的示例:

IPdfCreator.cs

public interface IPdfCreator
    {
        void ShowPdfFile();
    }
MainPage.cs:

private void Button_OnClicked(object sender, EventArgs e)
{
    DependencyService.Get<IPdfCreator>().ShowPdfFile();
}
结果: 在xamarin中有一个很好的项目使用了MuPDF库。我已经测试过了,它工作正常

使用MuPDF可以缩小、放大,甚至在PDF上写一些注释

private void Button_OnClicked(object sender, EventArgs e)
{
    DependencyService.Get<IPdfCreator>().ShowPdfFile();
}
[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;
        }
    }
}