@miljann995/ngx-extended-pdf-viewer

Embedding PDF files in your Angular application. Highly configurable viewer including the toolbar, sidebar, and all the features you're used to.

Usage no npm install needed!

<script type="module">
  import miljann995NgxExtendedPdfViewer from 'https://cdn.skypack.dev/@miljann995/ngx-extended-pdf-viewer';
</script>

README

ngx-extended-pdf-viewer

downloads npm version

CDN: unpkg.com

What's new in version 6.0 and 7.0?

Limited Internet Explorer 11 support. More to the point, IE 11 support is now a community effort. Starting with version 7.0, I'll reduce my efforts to support IE11. It's extremly difficult to hunt down bugs in IE11. In my installation of IE11, the debugger crashes all the time. But I'll happily accept pull requests for IE11. I can also fix bugs when you tell me which line is buggy. IE has a tendency to omit this info from the error messages, so I appreciate your help!

The JavaScript files have been renamed. Now the file names contain the version number. This should avoid caching problems after updating ngx-extended-pdf-viewer.

[(zoom)] has been overhauled. Now opening a new PDF file doesn't reset the zoom value.

[src] closes the current PDF file if you set [src]="undefined".

NgxExtendedPdfViewerService now allows you to getCurrentDocumentAsBlob() and to access the low-level form data using getFormData().

Version 6.0 adds a warning if you're displaying a signature (because the PDF viewer can't verify it) and it drops the custom zoom dropdown menu.

Potentially breaking changes

Version 7.0 fixes several bugs concerning [(zoom)]. Now (zoom) also emits the text values ("page-fit", "auto", "page-width", "page-actual"). When you open a new PDF document, the old value of [zoom] is used for the new document. This was always the intended behavior, but it's possible it breaks applications relying on the bugs.

The JavaScript files have been renamed. Now the version number is part of the file name.

Version 7.0 also removes several attributes and methods that have been deprecated a long time ago.

Several additions of version 6.0 may be consider breaking changes:

  • There's a warning if you're displaying a signature (because the PDF viewer can't verify it).
  • The custom zoom dropdown menu is replaced by the standard dropdown element of the browser because of cross-browser incompatibilities.
  • The algorithm hiding the toolbar has been fixed. If no button is shown, it's hidden, and the PDF file uses the free screen estate. Previously, this algorithm wasn't 100% failsafe.
  • The locale files are now expected to be in the assets folder defined by pdfDefaultOptions.assetsFolder. If you're configured a user-defined assets folder, this may be a breaking change because previous versions ignored this setting. You can override the default using the new attribute localeFolderPath.

Showcase and manual

There's a showcase at https://pdfviewer.net. Check this page for live demos, source code examples, and a handbook.

Bringing PDF to the Angular world

This library provides an embeddable PDF viewer component. It's different from other approaches like ng2-pdf-viewer in that it shows the full suite of UI widgets. In other words, it strongly resembles the PDF viewer of your browser:

Features

  • Limited support for Internet Explorer 11 (I'll accept pull requests fixing bugs, but I'll work on IE11 bugs with low priority myself)
  • Searching (including a programmatic API)
  • Printing
  • Support for forms
  • (Limited) support for signatures (lacking verification of the signature, so use on your own risk!)
  • Sidebar with thumbnails, outlines, and attachments (and each of them both optional and customizable)
  • Rotating
  • Download (including form data) and upload
  • Zoom (with optional two-way binding to an attribute)
  • Full-screen mode
  • Various selection tools
  • Standard display or even / odd spreads (like a book)
  • Multiple event listeners
  • Several approaches to scrolling (vertical, horizontal, "wrapped" scrolling)
  • Internationalization (providing translations to several dozen languages)
  • Direct access to the core API of pdf.js (including TypeScript definition files)
  • The ability to deactivate (i.e. hide) every button, menu item, and the context menu
  • Color theming
  • And to customize the toolbars and menus according to your needs.

Not to mention the ability to display PDF files, running on Mozilla's pdf.js 2.6.347, released in March 2020. If you're the daring one, you can also use the developer version 2.7. It's bleeding edge, so use it at own risk. Basically, this preview is there to make the update easier when a Mozilla publishes a new version of their pdf.js library.

Alternatives

Expand to learn more about the other options to display PDF files in Angular If you only need the base functionality, I'll happily pass you to the project of Vadym Yatsyuk. Vadym does a great job delivering a no-nonsense PDF viewer. However, if you need something that can easily pass as the native viewer on a gloomy day, ngx-extended-pdf-viewer is your friend.

There's also a direct counterpart to my library: ng2-pdfjs-viewer. As far as I can see, it's also a good library. Recently (May 24, 2019), it has been updated to PDF.js 2.2.171. It wraps the PDF viewer in an iFrame. That's a more reliable approach, but it also offers fewer options. The list of attributes is shorter, and the PDF viewer can't emit events to your application. If you're not happy with my library, check out ng2-pdfjs-viewer. It's a good library, too. Its unique selling point is displaying multiple PDF files simultaneously on the same page.

You might also try to use the native PDF viewer of your browser. That's a valid approach. It's even the preferred approach. However, ngx-extended-pdf-viewer gives you a wide range of options that aren't available using the native API.

How to use the library

As a rule of thumb, I recommend cloning the showcase project from GitHub before doing anything else. It's a standard Angular CLI application, so you'll get it up and running in less than ten minutes. It's a good starting point to do your own experiments. Maybe even more important: you'll learn if the library works on your machine. (Of course, it does, but it's always good to double-check!)

The detailed instructions for JHipster and Angular 2, 4, and 5 are available on the showcase.

  1. Install the library with npm i ngx-extended-pdf-viewer --save

  2. Open the file angular.json (or .angular-cli.json if you're using an older version of Angular) and configure Angular to copy the assets folder of the library into the assets folder of your application:

  "assets": [
    "src/favicon.ico",
    "src/assets",
    {
      "glob": "**/*",
      "input": "node_modules/ngx-extended-pdf-viewer/assets/",
      "output": "/assets/"
    }
  ],
  "scripts": []

This simply copies the entire assets folder. If you're concerned about disk memory, you can omit the subfolders inline-locale-files and additional-locale. If you need only one language, you can reduce the list to locale.properties and your language folder.

If you want to use the developer preview of pdf.js 2.7, import the "bleeding edge" files instead:

"assets": [
  "src/favicon.ico",
  "src/assets",
  {
    "glob": "**/*",
    "input": "node_modules/ngx-extended-pdf-viewer/bleeding-edge/",
    "output": "/assets/"
  }
],
"scripts": []

Hint: There are two ways to define the language files needed for the labels of the buttons and screen elements. The second method is described below in the "internationalization" section.

  1. Now you can display the PDF file like so:
<ngx-extended-pdf-viewer [src]="'assets/example.pdf'" useBrowserLocale="true" height="80vh"></ngx-extended-pdf-viewer>
  1. If you want to display a PDF file you have downloaded from a server, you probably have a Blob or a Base64 encoded string. Blobs can be passed directly to the attribute [src]. Base64 string must be passed to the attribute [base64Src] instead.

Configuration

Do you miss a configuration option? File an issue on the project bug tracker. If the base library pdf.js supports the requested option, I'll probably add it. BTW, you can speed up the process by providing a code snippet telling me how to implement the feature or by submitting a pull request.

Legend:

  • [(attribute)] describes an attribute with two-way-binding
  • [attribute] means that PDF-viewer reacts when the attribute changes
  • (attribute) means an event is raised when the user changes a setting
  • attribute (without special characters) means the attribute is used at load time only. Subsequent changes are ignored.

Also see the attribute list on the showcase. It's the same list, just a little more useful because the showcase doesn't truncate the table on the right-hand side.

Attribute default value description
[(src)] If [src] is a string: defines the URL of the PDF file to display. src may also be a Blob, a Uint8Array or an ArrayBuffer. To a limited extend, [(src)] is also a two-way binding attribute. If the user opens another PDF file, the event (srcChange) is fire. There's a catch: for security reasons, most browsers don't display the correct filename. Most often than not, the path is C:\fakepath\. The (srcChange) event removes the fakepath bit of the path. The $event attribute is simply the filename. But don't rely on it: it's up to the browser to implement that feature, and if you add the page to the "trusted pages" list in the Internet Explorer, the fully qualified file name is provided.
[base64Src] accepts a PDF file as base64 encoded string
(afterPrint) This event is fired after the print jov has either been sent to the printer, or after the user has cancelled the print job. Note there's no way to tell printing from aborting the print.
[authorization] undefined This attribute is designed to activate server-side authorization. If this attribute has a value, the attribute withCredentials is set to true. If you're using Keycloak, you can pass the bearer token with this attribute. Note that you have to add the prefix "Bearer: " (with a capital B and a trailing space). To support other authorization servers, you can also set additional headers using the attribute [httpHeaders].
(beforePrint) This event is fired when the print is initiated. Note that this simply means the print preview window is opened. There's no way to predict if the user is actually going to print.
[backgroundColor] ? background color
[contextMenuAllowed] true should the context menu show when the right-hand side button is clicked?
(currentZoomFactor) n/a fires each time the viewer changes the zoom level. The parameter is the numeric scale factor. Note that it's not a percentage; instead, [zoom]="'100%'" results in (currentZoomFactor) sending a value of 1.0. This event seems to fire often enough to make it reliable for detecting the current zoom factor all the time.
[customFindbarInputArea] (none) Allows you to customize the pop-up dialog that opens when you click the "find" button. See https://pdfviewer.net/custom-toolbar.
[customFindbarButtons] (none) Allows you to customize the pop-up dialog that opens when you click the "find" button. See https://pdfviewer.net/custom-toolbar.
[customSecondaryToolbar] (none) Allows you to replace the kebab menu on the right-hand side with your custom menu.
[customSidebar] (none) Allows you to replace the entire toolbar with your own custom toolbar. See https://pdfviewer.net/custom-sidebar.
[customThumbnail] (none) Allows you to implement custom thumbnails in the sidebar. See https://pdfviewer.net/custom-thumbnails.
[customToolbar] (none) Allows you to replace the entire toolbar with your own custom toolbar. See https://pdfviewer.net/custom-toolbar.
[customFreeFloatingBar] (none) Allows you to add a toolbar you can place anywhere on the PDF viewer. The original use case was to let the zoom controls hover as a separate window at the bottom of the PDF file. See https://pdfviewer.net/custom-toolbar.
delayFirstView 0 Number of milliseconds to wait between initializing the PDF viewer and loading the PDF file. Most users can let this parameter safely at it's default value of zero. Set this to 1000 or higher if you run into timing problems (typically caused by loading the locale files after the PDF files, so they are not available when the PDF viewer is initialized).
[enablePinchOnMobile] false By default, the pinch gesture zooms the entire window on mobile devices. If you prefer to zoom the PDF viewer only, you can activate enablePinchOnMobile="true".
[enablePrint] true Setting this flag to false disables printing the PDF file.
[filenameForDownload] document.pdf Allows the user to define the name of the file after clicking "download"
[(handTool)] true setting this flag to true, activates the "hand tool" to scroll the PDF file by dragging. Setting this to false activates the "text selection" tool. You can also use this flag as a two-way binding attribute. If you're only interested in the event, the event name is (handToolChange). Deactivating this flag also activates the "text layer". This, in turn, enables marking text and highlighting search result.
[height] (see text) define the height of the PDF window. By default, it's 100%. On most web pages, this results in a height of 0 pixels. In this case, the height is set to fill all the available space. More precisely, the all the space to the bottom of the window. If that's less then 100 pixel, the height is set to 100 pixel. Note that this is just an initial setting. It doesn't change when the window is resized.
[httpHeaders] (none) If you pass a JSON object to httpHeaders, the content of the JSON object is sent to the server as an array of additional httpHeaders.
[ignoreKeyboard] false if this flag is set to true, the PDF viewer ignores every keyboard event.
[ignoreKeys] (none) Accepts a comma-separated list of keys. For example, a legal value is "['P', 'N']". Every key in the list is ignored. In the example, the key "k" navigates to the next page but "n" does not.
[acceptKeys] (none) Accepts a comma-separated list of keys. For example, a legal value is "['P', 'N']". Every key in the list is accepted, and every other key is ignored. In the example, the key "n" navigates to the next page but "k" does not.
[ignoreResponsiveCSS] n/a This property has been removed in version 3.0.0-beta.6.
imageResourcesPath ./assets/images allows you to put the viewer's SVG files into an arbitrary folder.
localeFolderPath ./assets/locale allows you to put the locale folder into an arbitrary folder.
language undefined Language of the UI. Must the the complete locale name, such as "es-ES" or "es-AR". It may be all lowercase.
listenToURL false deactivates the URL listener of the PDF viewer. You can set it to "true" to allow for anchor tags like "#page=23" or "#nameddest=chapter_3". Only activate this flag if you don't use the anchor to encode the URLs for the router.
[logLevel] 1 Log level. Legal values: VerbosityLevel.ERRORS (=0),VerbosityLevel.WARNINGS (=1), and VerbosityLevel.INFOS (=5). The higher the log level, the more is logged. Please note that the log level is only updated when a new PDF document is loaded programmatically (i.e. when [src]changes).
[nameddest] undefined allows you to jump to a "named destination" inside the document. Typical examples of names destinations are "chapter_7" oder "image_3". The named destination are defined within the PDF document; you can only jump to destinations defined by the author of the PDF file.
[showSidebarButton] true Show or hide the button to toggle the sidebar
minifiedJSLibraries true Since version 4.0.0, ngx-extended-pdf-viewer loads the minified pdf.js libraries by default. You can set this flag to load the human-readable files. However, in most cases this shouldn't be necessary due to the source map files. Using the human-readable files give you a performance penalty.
minZoom 0.1 Minimum zoom factor you can achieve by pinching or by hitting the "-" button or the "+" key.
maxZoom 10 Maximum zoom factor you can achieve by pinching or by hitting the "+" button or the "+" key.
[mobileFriendlyZoom] 100% Increases the size of the UI elements so you can use them on small mobile devices. Must be a percentage ('150%') or a floating-point number ('1.5'). Alternatively you can set this attribute to 'true' (= '150%') or 'false' (= '100%').
[password] undefined Allows you to pass a password programatically. If you pass the wrong password, a red error message claiming "corrupt pdf file" is show in below the toolbar. Caveat: the password must be a string. During my test I accidentially used a numerical value. This fails even if the password consists only of digits. Please note that the password is stored in the main memory without encryption. If you're really serious about protecting your user's data from hackers, this might be a security issue. Please note that the log level is only updated when a new PDF document is loaded programmatically (i.e. when [src]changes).
[(page)] undefined two-way binding attribute to determine the page to display; more precisely: [page]="25" makes the PDF viewer show page 25 (at any time - even after load time); [(page)]="attribute" updates the attribute each time the user scrolls to another page. If you're only interested in the event, that's (pageChange).
[(pageLabel)] undefined two-way binding attribute to determine the page to display; more precisely: [pageLabel]="25" makes the PDF viewer show the page the author called page "25". This may or may not be a numeric value. For instance, many books use roman numbers for the preface and arab numbers for the rest of the document. In this case, [pageLabe]="iv" usually refers to the same page as [page]="4". [(pageLabel)]="attribute" updates the attribute each time the user scrolls to another page. If you're only interested in the event, that's (pageLabelChange).
(pagesLoaded) undefined emits the number of pages when a document is loaded; more precisely: emits an instance of PagesLoadedEvent. The attribute pagesCount tells how many pages the document has. The source attribute contains a reference to the PDF viewer. You can also use this event to detect when a document has been loaded.
(pageRendered) undefined fires each time a page is rendered. Emits an instance of PageRenderedEvent. The pageNumber attribute tells you which page has been rendered.
pageViewMode multiple pageViewMode="multiple" is the default PDF viewer. It shows the entire PDF files as a long roll of pages, just as Acrobat reader does. pageViewMode="single" only displays one page at a time. You can't scroll to the next page. The only way to navigate to another page is to click on the "next page/previous page" button, enter a page number, jump to the next result of a search, and to click on an entry of the table of contents.
(pdfDownloaded) undefined fires when a user downloads a document. Strictly speaking, it fires when they click the "download" button. Caveat: Even if the user cancels the download, the event is fired.
(pdfLoaded) undefined emits when the PDF file has been load successfully. The paramter $event is an PdfLoadedEvent, containing the number of pages of the PDF file.
(pdfLoadingFailed) undefined emits when trying to load and open a PDF file has failed. The parameter $event is an Error, which may or may not contain the stacktrace and additional info about the root cause of the error.
[printResolution] 150 set the print resolution in DPI. Sensible values are 300, 600, and maybe even 900. Note that higher values result in more memory consumption, more CPU uses, and may even cause browser crashes. During my tests setting the resolution to 1100 dpi worked, but 1150 failed. In my case, the browser seemed to ignore the print request without displaying any error message.
[showBorders] true By default, the PDF file is displayed with page borders. You hide them by setting [showBorders]="false". Note that the page borders can be switched off and on even after the PDF file is diplayed, but if you're using one of the zoom presets (auto, page-width etc.), the page isn't resized correctly.
[(rotation)] 0 [rotation] allows you to rotate every page. Note that this attribute is not responsible to rotate individual pages - it always rotates the entire document. (rotationChange) notifies you when the user rotates the document. This attribute can be used as a two-way binding attribute, i.e. [(rotation)]="angle". Legal values are 0, 90, 180, and 270. Every other value is ignored.
[showBookmarkButton] true Show or hide the "bookmark" button
[showDownloadButton] true Show or hide the "download" button (aka "save" button)
[showFindButton] true Show or hide the "find" button
[showHandToolButton] false Show or hide the "hand tool" menu item in the secondary toolbar. (The hand tool allows you to move the page by clicking and dragging). This activates also the opposite menu item: "text selection tool". As a side effect, the hand tool also activates the "text layer". This, in turn, enables marking text and highlighting search result.
[showOpenFileButton] true Show or hide the "open file" button
[showPagingButtons] true Show or hide the buttons to navigate between pages and the input field to navigate to a particular input field
[showPresentationModeButton] true Show or hide the "full screen" button
[showPrintButton] true Show or hide the "print" button
[showPropertiesButton] true Show or hide the "show document properties" menu item in the secondary toolbar
[showRotateButton] true Show or hide the "rotate" menu items in the secondary toolbar
[showScrollingButton] true show or hide the button switching between horizontal and vertical scrolling
[showToolbar] true Show or hide the toolbar
[showSecondaryToolbarButton] true Show or hide the secondary toolbar (the menu hiding behind the arrows at the right-hand side)
[showSelectToolButton] n/a This attribute has been removed with version 0.9.47. Use [showHandToolButton] instead.
[showSpreadButton] true Show or hide the "spread" menu items in the secondary toolbar. Also see the attribute [(spread)] below.
[showUnverifiedSignatures] false The base library, pdf.js, does not show signatures for a good reason. Signatures can't be verified (yet), so there's always the danger so show faked signatures, leading the readers to wrong conclusion. So proceed with care. If you insist, ngx-extended-pdf-viewer allows you to display signatures by setting [showUnverifiedSignatures]="true". Note that you also have to disable form support. Also note that ngx-extended-pdf-viewer adds a hint making the reader aware of the potentially falsy signature.
[showZoomButtons] true Show or hide the "zoom" area (containing of the buttons "+" and "-" and the dropdown menu)