问题
I have a Xamarin.Forms application supporting only UWP. I need to be able to load pdf files from the web and display the content in my application. I cannot find a solution that would work with UWP and handle pdf files that are not part of a project.
回答1:
For your requirement, you could refer this code sample that custom a WebView and load pdf file with pdf.js host web application.
[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))));
}
}
}
}
Update
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?
I recollect the case that I answered in the last few months. For displaying random files, you could convert pdf file into Base64String
then opening it by calling the openPdfAsBase64
JS function in the viewer.js. For detail please refer this case reply.
For better understand, I have create a code sample that you could refer. before using it you need place hello.pdf
file in the LocalState
folder. Because, the default file load path is LocalState
folder, but it is empty at fist start.
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); }
}
}
Usage
<Grid>
<local:PDFView FileName="hello.pdf"/>
</Grid>
Please note you need use this viewer.js that was added openPdfAsBase64
method.
来源:https://stackoverflow.com/questions/54240261/displaying-pdf-files-from-internet-in-xamarin-forms-uwp