pdf links

PDF Rendering
Convert PDF to Image (.NET)
Convert PDF to image on Android (Xamarin)
Convert PDF to image on iOS (Xamarin)
Convert PDF to image in Windows Store apps (.NET)
Convert PDF to image in Windows Phone apps (.NET)
PDF to image in Universal Windows Store apps (.NET)
Free PDF Viewer control for Windows Forms (.NET)
How to integrate PDF Viewer control in WPF app (.NET)
Creating WPF PDF Viewer supporting bookmarks (.NET)
Cross-platform PDF Viewer using GTK# (MONO)
Silverlight PDF viewer control (Silverlight 5)
Multithreaded PDF rendering (.NET)
Convert pdf to image in Silverlight app (C# sample)
How to set fallback fonts for PDF rendering (C#)
Avoiding the out-of-memory exception on rendering (C#)
PDF viewer single page application (WebAPI, AngularJS)
PDF viewer control for Windows 10 universal applications
Use custom ICC profile for CMYK to RGB conversion
PDF layers - separate images, text, annotations, graphics

PDF Forms Creation PDF Security
Conversion to PDF/A
Other topics
PDF Document Manipulation
PDF Content Generation
Fixed and Flow layout document API (.NET)
Creation of grids and tables in PDF (C# sample)
How to create interactive documents using Actions (C# sample)
Text flow effects in PDF (C# sample)
How to generate ordered and bulleted lists in PDF (C# sample)
Convert HTML to PDF using flow layout API (C# sample)
How to use custom fonts for PDF generation (.NET)
Create document with differently sized pages (C#)
Create PDF documents using MONO (C#/MONO/Windows/OSX)
How to use background images for content elements (C#/PDF Kit/FlowLayout)
Add transparent images to PDF document (C#)
Draw round rect borders in PDF documents(C#)
ICC color profiles and and ICC based colors in PDF (C#)
How to use bidirectional and right to left text in PDF (C#)
Create PDF documents from XML templates (C# sample)
How to resize PDF pages and use custom stamps (C#)
Add header and footer to PDF page (.NET sample)
How to use clipping mask for drawing on PDF page
Fill graphics path with gradient brushes in PDF (Shadings)
Apitron PDF Kit and Rasterizer engine settings
Add layers to PDF page (optional content, C# sample)
How to create free text annotation with custom appearance

PDF Content Extraction
PDF Navigation

PDF to TIFF conversion
Contact us if you have a PDF related question and we'll cover it in our blog.

2015-11-30

Web PDF viewer implemented as single page web application using AngularJS and Web API

Introduction


There’s a trend to implement web applications as so-called Single Page Applications or SPA for short. These are apps that do most of their job in asynchronous and user-responsive way providing an experience similar to desktop apps, avoiding the need for page reloading.

In this article, we’ll show how to create a simple PDF viewer implemented as single page app using ASP.NET Web API for the server side and AngularJS for the client side. We’ve also used a bit of CSS to make it more interesting.


Creating the project


Open Visual Studio and select File -> New -> Project… -> Web -> ASP .NET Web Application as shown on the illustration below:

Pic. 1 Creating new project

Pic. 1 Creating new project


Click OK when you’re ready, and you’ll be redirected to template selection wizard.


Template selection


We’ll use the Web API template as we are going to create a very simple UI based exclusively on HTML / CSS and AngularJS. In this example we didn’t use any authentication, so turned it off by selecting the No Authentication option


Pic. 2 Finalizing project creation

Pic. 2 Finalizing project creation

Click OK when you’re ready to finish the project creation.


Adding packages


Install AngularJS core and Apitron PDF Rasterizer for .NET packages via NuGet package manager. 


Server side code


The RenderingController shown below, returns document info and renders pages by request.

public class RenderingController : ApiController
{
    private static readonly string filePath;
    static RenderingController()
    {
        filePath = HttpContext.Current.Server.MapPath(
            "~/App_Data/Apitron_Pdf_Kit_in_Action.pdf");
    }

    /// <summary>
    /// Gets the rendered page as encoded image.
    /// </summary>
    /// <param name="id">Page index, zero-based.</param>
    /// <returns>String containing encoded image, or null if the call fails.</returns>
    public string GetRenderedPage(int id)
    {
        using (Document doc = new Document(File.OpenRead(filePath)))
        {
            if (id >= 0 && doc.Pages.Count > id)
            {
                Bitmap bm = doc.Pages[id].Render(new Resolution(72, 72), 
                    new RenderingSettings());

                if (bm != null)
                {
                    using (MemoryStream ms = new MemoryStream())
                    {
                        bm.Save(ms, ImageFormat.Png);
                        return string.Format("data:image/png;base64,{0}",
Convert.ToBase64String(ms.ToArray()));
                    }
                }
            }
        }
        return null;
    }

    /// <summary> Returns document info. </summary>
    /// <returns>Valid document info object, or null if the call fails.</returns>
    public DocumentInfo GetFileInfo()
    {
        try
        {
            using (Document doc = new Document(File.OpenRead(filePath)))
            {
                return new DocumentInfo() {PageCount = doc.Pages.Count};
            }
        }
        catch (Exception e)
        {
            Debug.WriteLine(e.Message);
            return null;
        }
    }
}


In order to properly map requests to our controller, change the default route registered in WebApiConfig class as folllows:

  
public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );          
    }
}                 


UI template



The html provided below is located in the root of the project and set as startup page for it (see index.html). It references the CSS stylesheet and scripts needed to run the AngularJS app.

<!DOCTYPE html>
<html ng-app="mainApp" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script src="/Scripts/angular.min.js"></script>
    <script src="/Scripts/app/app.js"></script>
    <script src="/Scripts/app/renderingController.js"></script>   
    <link rel="stylesheet" type="text/css" href="Content/styles.css">
</head>
    <body ng-controller="pageByPageRenderingController" ng-init="setup()">       
          <div class="navbarContainer">
              <ul>
                  <li ng-click="loadFile()">Load file</li>
                  <li ng-click="renderPrev()">Prev</li>
                  <li ng-click="renderNext()">Next</li>
                  <li onclick="alert('Apitron PDF Rasterizer usage sample,
                     implemented using WebAPI and AngularJS.')">About</li>
              </ul>
          </div>
          <div class="viewArea">
            <span id="aligner">{{errorText}}</span>
            <img ng-src="/images/loading.gif" class="{{progressBarClass}}"/>               
            <img ng-src="{{imageSource}}" class="{{pageViewClass}} shadow"/>              
          </div>       
    </body>
</html>


AngularJS part


This part consists of app.js and renderingController.js files located in “/Scripts/app” project folder.
app.js - contains the code needed to configure our app’s module that depends on renderingController module that performs the actual interaction with our Web API methods.

var mainApp = angular.module('mainApp', ['renderingController']);
                 
renderingController.js  - contains the code for pageByPageRenderingController object which implements the methods referenced in UI template, e.g. setup(), loadFile() etc. The complete code for this controller can be found in corresponding sample project and downloaded from our GitHub repo.  

   

Results


We kept the app simple, and as it can be seen from the RenderingController’s code, we didn’t use any caching and implemented page rendering using the simplest way: open the file and render the requested page for every request.

The image shown below demonstrates the resulting PDF viewer single page application:

Pic. 3 PDF Viewer single page app

Pic. 3 PDF Viewer single page app

Conclusion


If you plan to implement your web app as a single page app and need to integrate PDF preview or PDF processing capabilities, then Apitron’s .NET PDF components such as Apitron PDF Rasterizer or Apitron PDF Kit can be easily employed to achieve the best results.

In this article we have shown how to implement basic pdf preview, but it’s also possible to implement full featured pdf viewer with loading of the document bookmarks, support for internal navigation, and so on. You can also read and create document fields, create PDF forms, extract text, sign documents and do whatever you want with them using our PDF components.

If you have any questions regarding our products, just let us know and we’ll be happy to answer them.

Downloadable version of this article can be found by the following link [PDF].