【问题标题】:Displaying pdf files from internet in Xamarin.Forms UWP在 Xamarin.Forms UWP 中显示来自 Internet 的 pdf 文件
【发布时间】:2019-06-11 21:48:59
【问题描述】:

我有一个仅支持 UWP 的 Xamarin.Forms 应用程序。我需要能够从网络加载 pdf 文件并在我的应用程序中显示内容。我找不到适用于 UWP 并处理不属于项目的 pdf 文件的解决方案。

【问题讨论】:

标签: xamarin.forms uwp xamarin.uwp


【解决方案1】:

根据您的要求,您可以参考此code sample 自定义 WebView 并使用 pdf.js 托管 Web 应用程序加载 pdf 文件。

[assembly: ExportRenderer(typeof(CustomWebView), typeof(CustomWebViewRenderer))]
namespace DisplayPDF.WinPhone81
{
    public class CustomWebViewRenderer : WebViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
        {
            base.OnElementChanged(e);

            if (e.NewElement != null)
            {
                var customWebView = Element as CustomWebView;
                Control.Source = new Uri(string.Format("ms-appx-web:///Assets/pdfjs/web/viewer.html?file={0}", string.Format ("ms-appx-web:///Assets/Content/{0}", WebUtility.UrlEncode(customWebView.Uri))));
            }
        }
    }
}

更新

这样就可以了。但是pdf应该是项目的一部分。这是否意味着无法显示随机文件,例如从网上下载的?

我记得我在过去几个月中回答的案例。为了显示随机文件,您可以将 pdf 文件转换为 Base64String 然后通过调用 viewer.js 中的 openPdfAsBase64 JS 函数打开它。详情请参考本案例reply

为了更好地理解,我创建了一个代码sample,您可以参考。在使用它之前,您需要hello.pdf 文件放在LocalState 文件夹中。因为,默认的文件加载路径是LocalState文件夹,但一开始是空的。

PDFViewRenderer.cs

public class PDFViewRenderer :WebViewRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
    {
        base.OnElementChanged(e);
        if (e.NewElement != null)
        {
            Control.Source = new Uri("ms-appx-web:///Assets/pdfjs/web/viewer.html");
            Control.LoadCompleted += Control_LoadCompleted;
        }
    }
    private async void Control_LoadCompleted(object sender, Windows.UI.Xaml.Navigation.NavigationEventArgs e)
    {
        PDFView pdfView = Element as PDFView;
        if (string.IsNullOrEmpty(pdfView?.FileName)) return;
        try
        {
            var Base64Data = await OpenAndConvert(pdfView?.FileName);
            var obj = await Control.InvokeScriptAsync("openPdfAsBase64", new[] { Base64Data });
        }
        catch (Exception ex)
        {
            throw ex;
        }

    }
    private async Task<string> OpenAndConvert(string FileName)
    {
        var folder = ApplicationData.Current.LocalFolder;
        var file = await folder.GetFileAsync(FileName);
        var filebuffer = await file.OpenAsync(FileAccessMode.Read);
        var reader = new DataReader(filebuffer.GetInputStreamAt(0));
        var bytes = new byte[filebuffer.Size];
        await reader.LoadAsync((uint)filebuffer.Size);
        reader.ReadBytes(bytes);
        return Convert.ToBase64String(bytes);
    }
}

PDFView.cs

public class PDFView : WebView
{
    public PDFView()
    {

    }
    public static readonly BindableProperty FileNameProperty = BindableProperty.Create(
    propertyName: "FileName",
    returnType: typeof(string),
    declaringType: typeof(PDFView),
    defaultValue: default(string));

    public string FileName
    {
        get { return (string)GetValue(FileNameProperty); }
        set { SetValue(FileNameProperty, value); }
    }
}

用法

<Grid>
    <local:PDFView FileName="hello.pdf"/>
</Grid>

请注意,您需要使用 viewer.js 添加的 openPdfAsBase64 方法。

【讨论】:

  • 我收到一个错误:消息:文件来源与查看者的不匹配。我尝试了另一个具有相同结果的文件。你能告诉我有什么问题吗?
  • 如果我在 2 个地方注释掉“origin !== viewerOrigin”条件,我会收到另一个错误:Unexpected server response (500) while retrieving PDF "ms-appx-web:///Assets/内容/myFile.pdf”。我让 isSameOrigin() 在两个地方返回 true,但没有帮助...
  • 请注意,您需要将myFile.pdf Build Action 设为Content
  • 我已经创建了一个代码示例,请查看上面的案例回复。
  • 对不起,我发现了,但这是 viewer.js 内部错误。我也不知道。
猜你喜欢
  • 1970-01-01
  • 2020-08-27
  • 2018-04-29
  • 2016-09-20
  • 2015-03-06
  • 1970-01-01
  • 2022-11-02
  • 2019-08-16
  • 1970-01-01
相关资源
最近更新 更多