Displaying PDF files in a UWP app
This article is more than two years old. Some details may have changed, so check the current documentation before applying them.
In this short blogpost I want to show you how I’ve used the Windows.Data.Pdf.PdfDocument class in order to render a PDF file inside my UWP app.
In order to open a PDF from a UWP app, you can ofcourse, always use Windows.System.Launcher.LaunchUriAsync like this:
using LauncherOptions
Windows.System.LauncherOptions options = new Windows.System.LauncherOptions();
options.ContentType = "application/pdf";
Windows.System.Launcher.LaunchUriAsync(new Uri(fileUrl), options);
This works great, but your file is being opened in an other app. And this might not be what you want. We just want the content of the PDF file being rendered inside our UWP app itself.
PDF content in UWP
And that’s very simple to do!
First we need to load a PDF document in a Windows.Data.Pdf.PdfDocument object. There are two way to do this: From a StorageFile or from a Stream.
LoadFromFileAsync
public async void OpenLocal()
{
StorageFile f = await
StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/pdffile.pdf"));
PdfDocument doc = await PdfDocument.LoadFromFileAsync(f);
Load(doc);
}
LoadFromStreamAsync
public async void OpenRemote()
{
HttpClient client = new HttpClient();
var stream = await client.GetStreamAsync(url);
var memStream = new MemoryStream();
await stream.CopyToAsync(memStream);
memStream.Position = 0;
PdfDocument doc = await PdfDocument.LoadFromStreamAsync(memStream.AsRandomAccessStream());
Load(doc);
}
This PdfDocument object has a method GetPage(int pageIndex) which returns a PdfPage object. This object represents a single page of our PdfDocument and has this interesting method: RenderToStreamAsync. This method accepts a IRandomAccessStream and optionally PdfPageRenderOptions. Once the page is rendered to the Stream, we can set it to a BitmapImage by using the BitmapImage’s SetSource(Asyc) method.
var page = pdfDoc.GetPage(0);
using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
{
await page.RenderToStreamAsync(stream);
await bitmapImage.SetSourceAsync(stream);
}
This BitmapImage can now be easily bound to the Source property of an Image in XAML. Or, in this case, we can bind our collection of PdfPages to an ItemsControl and display an Image for each item.
Binding
<ScrollViewer ZoomMode="Enabled" Background="DarkGray" Grid.Column="1">
<ItemsControl ItemsSource="{Binding PdfPages, ElementName=root}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" Margin="0 2" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
Complete code-behind:
Code-behind
public MainPage()
{
this.InitializeComponent();
}
public async void OpenLocal()
{
StorageFile f = await
StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/pdffile.pdf"));
PdfDocument doc = await PdfDocument.LoadFromFileAsync(f);
Load(doc);
}
public async void OpenRemote()
{
HttpClient client = new HttpClient();
var stream = await
client.GetStreamAsync("http://www.adobe.com/content/dam/Adobe/en/accessibility/products/acrobat/pdfs/acrobat-x-accessible-pdf-from-word.pdf");
var memStream = new MemoryStream();
await stream.CopyToAsync(memStream);
memStream.Position = 0;
PdfDocument doc = await PdfDocument.LoadFromStreamAsync(memStream.AsRandomAccessStream());
Load(doc);
}
async void Load(PdfDocument pdfDoc)
{
PdfPages.Clear();
for (uint i = 0; i < pdfDoc.PageCount; i++)
{
BitmapImage image = new BitmapImage();
var page = pdfDoc.GetPage(i);
using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
{
await page.RenderToStreamAsync(stream);
await image.SetSourceAsync(stream);
}
PdfPages.Add(image);
}
}
public ObservableCollection<BitmapImage> PdfPages
{
get;
set;
} = new ObservableCollection<BitmapImage>();
And that’s all there is to it!
Sources: https://1drv.ms/u/s!AtU3InGVXXeFi44ogMTAbHvtAXyDYw
UPDATE
I made a PdfViewerControl you can use in order to easily display PDF files in your UWP apps. It’s available, together with the source code in GitHub.
See this blogpost: UWP Simple PDF viewer
Join the discussion