在 Xamarin.Forms UWP 中显示来自互联网的 pdf 文件
Displaying pdf files from internet in Xamarin.Forms UWP
我有一个 Xamarin.Forms 应用程序只支持 UWP。我需要能够从网络加载 pdf 文件并在我的应用程序中显示内容。我找不到适用于 UWP 并处理不属于项目一部分的 pdf 文件的解决方案。
根据您的要求,您可以参考此 code sample that custom a WebView and load pdf file with pdf.js 主机 Web 应用程序。
[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))));
}
}
}
}
更新
This way it works. But the pdf should be a part of the project. Does it mean that there is no way to display random files, e.g. downloaded from the web?
回想一下最近几个月我回答的案例。为了显示随机文件,您可以将pdf文件转换为Base64String
,然后通过调用viewer.js中的openPdfAsBase64
JS函数打开它。详情请参考这个案例.
为了更好地理解,我创建了一个代码 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
方法。
我有一个 Xamarin.Forms 应用程序只支持 UWP。我需要能够从网络加载 pdf 文件并在我的应用程序中显示内容。我找不到适用于 UWP 并处理不属于项目一部分的 pdf 文件的解决方案。
根据您的要求,您可以参考此 code sample that custom a WebView and load pdf file with pdf.js 主机 Web 应用程序。
[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))));
}
}
}
}
更新
This way it works. But the pdf should be a part of the project. Does it mean that there is no way to display random files, e.g. downloaded from the web?
回想一下最近几个月我回答的案例。为了显示随机文件,您可以将pdf文件转换为Base64String
,然后通过调用viewer.js中的openPdfAsBase64
JS函数打开它。详情请参考这个案例
为了更好地理解,我创建了一个代码 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
方法。