Unlock the Power of Direct PDF Editing with WebViewer 10.7

How to Build a PDF Viewer with AngularJS and PDF.js

By Apryse | 2018 Nov 23

Sanity Image
Read time

5 min

This post will show you how to add a simple PDF viewer to your AngularJS app with PDF.js and the angularjs-pdf directive. You can use Angular to display a PDF from an API and match your app's look and feel by wrapping it in a custom UI like this:

Custom UI of angular and pdf.js viewer

This viewer is ideal for basic viewing use cases, and includes a few basic widgets:

  • Opening a local file
  • Rotating left
  • Zooming in/out
  • Previous/next page navigation

The source code for this project is available in our Git repo. We're using PDF.js version 1.6.414.

Let’s create an Angular JS PDF viewer example!

Step 1 - Clone the Repo

Copied to clipboard

To build your own Angular JS PDF viewer, first create the directory where you want this app to live, then clone the repo from the command line:

# command line
git clone https://github.com/PDFTron/angular-pdf-ui.git
cd angular-pdf-ui

To change the PDF that's loaded by default, replace PDFTron SDK and pdftron-sdk.pdf in docCtrl.js:

// file: angular-pdf-ui/src/js/controllers
  $scope.pdfName = 'PDFTron SDK';
  $scope.pdfUrl = 'pdf/pdftron-sdk.pdf';

You can now run this basic viewer in your app.

Next, we'll customize the UI.

Step 2 - Configuration

Copied to clipboard

The viewer has limited options that can be configured in index.html:

<! -- file: angular-pdf-ui/src/index.html -- >
<ng-pdf
  template-url="partials/viewer.html"
  scale="page-fit"
  page="1"
  usecredentials="false"
  debug="false"
></ng-pdf>

The scale value can be page-fit or a number, the page value indicates the first page displayed in the viewer, while a usecredentials value of true would require a password to open the file (but it does not encrypt the file). See the official README.

The $scope.onProgress and $scope.onLoad functions can be used to show an animation while the file is loaded, and then do something when it's finished.

Step 3 - Removing Widgets From the UI

Copied to clipboard

The code for displaying widgets is located in viewer.html, with widgets wrapped in <span> tags. To remove (or re-order) the widgets, find the tag and adjust as needed.

<! -- file: angular-pdf-ui/src/partials/viewer.html -- >
<input
  onchange="angular.element(this).scope().onFileSelected(this)"
  type="file"
  id="file"
  class="d-none"
  accept=".pdf"
/>
<div class="toolbar d-flex">
  <span
    class="my-icon"
    ng-include="'icon/baseline-open_in_browser-24px.svg'"
    ng-click="openLocalFile()"
    title="Open File"
  ></span>
  <span
    class="my-icon"
    ng-include="'icon/baseline-rotate_right-24px.svg'"
    ng-click="rotate()"
    title="Rotate Right"
  ></span>
  <span
    class="my-icon"
    ng-include="'icon/baseline-zoom_in-24px.svg'"
    ng-click="zoomIn()"
    title="Zoom In"
  ></span>
  <span
    class="my-icon"
    ng-include="'icon/baseline-zoom_out-24px.svg'"
    ng-click="zoomOut()"
    title="Zoom Out"
  ></span>

  <span
    class="my-icon ml-auto"
    ng-include="'icon/baseline-navigate_before-24px.svg'"
    ng-click="goPrevious()"
    title="Previous Page"
  ></span>
  <div>
    <input type="number" class="page-num" min="1" ng-model="pageNum" />
    <span>/ {{ pageCount }}</span>
  </div>
  <span
    class="my-icon"
    ng-include="'icon/baseline-navigate_next-24px.svg'"
    ng-click="goNext()"
    title="Next Page"
  ></span>
</div>

For example, delete this code to remove the rotation toggle:

<! -- file: angular-pdf-ui/src/partials/viewer.html -- >
  <span
    class="my-icon"
    ng-include="'icon/baseline-rotate_right-24px.svg'"
    ng-click="rotate()"
    title="Rotate Right"
  ></span>

Step 4 - Replacing Widget Icons in Your Angular JS PDF Viewer

Copied to clipboard

Widget icons are referenced individually from viewer.html, so it's easy to swap them out with whatever image you'd like to use:

<! -- file: angular-pdf-ui/src/partials/viewer.html -- >
  <span
    class="my-icon"
    ng-include="'icon/baseline-open_in_browser-24px.svg'"
    ng-click="openLocalFile()"
    title="Open File"
  ></span>

The above code is for the File Open widget. To use a different image, replace icon/baseline-open_in_browser-24px.svg with the one you'd like to use.

Step 5 - Changing Widget or Toolbar Styling

Copied to clipboard

Widgets and the toolbar can be styled in style.css. Here we can adjust the background of the toolbar, widget sizing or padding, and more.

/* file: angular-pdf-ui/src/style.css  */
*{box-sizing: border-box;}
.wrapper {margin: 0 auto; width: 960px; }
.pdf-controls { width: 100%; display: block; background: #eee; padding: 1em;}
.rotate0 {-webkit-transform: rotate(0deg); transform: rotate(0deg); }
.rotate90 {-webkit-transform: rotate(90deg); transform: rotate(90deg); }
.rotate180 {-webkit-transform: rotate(180deg); transform: rotate(180deg); }
.rotate270 {-webkit-transform: rotate(270deg); transform: rotate(270deg); }
.fixed { position: fixed; top: 0; left: calc(50% - 480px); z-index: 100; width: 100%; padding: 1em; background: rgba(238, 238, 238,.9); width: 960px; }

.toolbar {
	background: #303030;
	padding: 10px;
	position: fixed;
	left: 0;
	right: 0;
	top: 0;
	z-index: 9999;
}

.toolbar span {
	color: white;
}

.my-icon {
	margin: 0 7px;
	cursor: pointer;
}

.my-icon:hover {
	opacity: 0.5;
}

.my-icon.active {
	opacity: 0.5;
}

.my-icon.active:hover {
	opacity: 1;
}

.page-num {
	width: 50px;
	border: 0;
	margin-right: 2px;
	text-align: center;
}

.searchbox {
	width: 0;
	opacity: 0;
	transition: all 0.3s ease-out;
	border: 0px;
	padding: 0 3px;
}

.searchbox:focus, .searchbox:active {
	outline: 0;
	box-shadow: none;
}

.searchbox:focus {
	opacity: 1;
	width: 200px;
}

.pdf-body {
	margin-top: 46px;
}

input:focus, input:active {
	outline: 0;
	box-shadow: none;
}

And that's it! You now have a simple AngularJS documentation PDF viewer that matches your app's look and feel.

This is a great solution if you just need basic viewing capabilities, and you're not too concerned with PDF.js rendering inconsistencies or failures that can occur (especially the older versions). If you are in the process of evaluating PDF.js, be sure to see our guide to evaluating PDF.js.

If you need to add more robust functionality, like annotation, form filling, 100% rendering reliability, and more to your viewer, we offer a JavaScript-based PDF viewer:

To see it in action, check out our WebViewer demo or visit our comprehensive WebViewer Buyers Guide.

Also, it's easy to integrate into your AngularJS project.

Integrating Apryse WebViewer into AngularJS Projects

Copied to clipboard

Make sure you have Node.js installed to run the sample.

Note: Node.js is not required for WebViewer. WebViewer does not require Node, npm, or node_modules. It is only recommended to run the samples.

Start by cloning and installing our WebViewer AngularJS sample project:

git clone https://github.com/PDFTron/webviewer-angularjs-sample.git
cd webviewer-angularjs-sample
npm install
npm start

And that's it! You've now got a robust and reliable PDF viewer that's easy to customize.

To integrate this into your own app, use the directive provided in the sample.

angular.module('components', [])

  .directive('webviewer', function() {
    return {
      restrict: 'E',
      scope: {},
      controller: function($scope, $element) {
        WebViewer({
          path: 'lib', // path to the PDFTron 'lib' folder on your server
          initialDoc: 'https://pdftron.s3.amazonaws.com/downloads/pl/webviewer-demo.pdf'
        }, document.getElementById('viewer'))
        .then(function(instance) {
          var docViewer = instance.docViewer;
          docViewer.on('documentLoaded', function() {
            // call methods relating to document processing
          });
        });
      },
      template: "<div id='viewer' style='width: 1024px; height: 600px; margin: 0 auto;'></div>",
      replace: true
    };
  })

Conclusion

Copied to clipboard

Building a PDF viewer with AngularJS and PDF.js can be straightforward, but once you need more advanced features, 100% reliability, or high-fidelity rendering, open source may not be the best approach.

Apryse WebViewer has hundreds of features, support for 30+ file formats, a proven rendering engine built right in, and it's simple to integrate with Angular projects.

Check out documentation for our JavaScript PDF library, and get started with your free trial.

If you have any questions about Apryse's PDF SDK, please feel free to get in touch!

You can find the source code for this blog post at Github.

Sanity Image

Apryse

Share this post

email
linkedIn
twitter