Rendering a PDF document from a URL (WinRT)

Please note – This is the simplest code scenario that I have explained, further additions like zooming in/out can be added as well. This post outlines merely rendering the PDF, and is most suitable for sized PDFs (in terms of pages) as well as for those PDFs which have mostly Image content.

For some unusual reason, one can easily find samples for this problem in C++, but not C#. I faced this issue recently, as there was not much consolidated documentation on how the APIs have to be used, and the code samples I did find were fragmented. The simplest way to go forward with this issue is to use the native Windows.Data.Pdf namespace APIs to render the PDF document.

STEP 1 : Build the container that will render the pages of the PDF

I used a StackPanel within a ScrollViewer. Nothing complicated.

<ScrollViewer Background="#4CA6A6A6" Padding="10,5">
    <StackPanel x:Name="PagePanel" Margin="10"/>
</ScrollViewer>

 
STEP 2 : Attach a stream for reading to the URL of the PDF

Define these properties in the code behind of the rendering page, for the sake of simplicity.

public PdfDocument Document { get; set; }
public PdfPage CurrentPage { get; set; }

Create a streamed file, that can be stored as a temporary file for the lifetime of the page. Call this method from an event handler of your choice (I added it to the Page.Loaded event handler)

try
{                                                                           
    IRandomAccessStreamReference thumbnail = RandomAccessStreamReference.CreateFromUri(new Uri(webURL));
    StorageFile file1 = await StorageFile.CreateStreamedFileFromUriAsync("temp.pdf", new Uri(webURL), thumbnail);
    this.Document = await PdfDocument.LoadFromFileAsync(file1)
}
catch (Exception ex)
{
    MessageDialog dialog = new MessageDialog(ex.Message);
    dialog.ShowAsync();
    return;
}
for (int i = 0; i < Document.PageCount; i++)
{
    await this.RenderPage(i);
}

 
STEP 3 : Render the pages

Render the PDF pages into images and add them as items to the StackPanel.

private async Task RenderPage(int index)
{
    this.CurrentPage = this.Document.GetPage((uint)index);
    using (IRandomAccessStream stream = new MemoryStream().AsRandomAccessStream())
    {
        await this.CurrentPage.RenderToStreamAsync(stream);
        BitmapImage source = new BitmapImage();
        source.SetSource(stream);
        Image i = new Image();
        i.Source = source;
        i.Margin = new Thickness(0,5,0,0);
        PagePanel.Children.Add(i);
    }
}

That’s all folks!

Leave a comment