Pdf view based on pdf.js.

pdf.js libary is lazy loading by default,you can change the default root CDN path via Global Configuration.

The component inspired by ng2-pdf-viewer.

Use local path

// angular.json
  "glob": "**/(build|web)/**",
  "input": "./node_modules/pdfjs-dist/",
  "ignore": ["*.js.map", "*.d.ts"],
  "output": "assets/pdfjs/"
// global-config.module.ts
const alainConfig: AlainConfig = {
  pdf: {
    lib: '/assets/pdfjs/'


Basic Usage

Simplest of usage.

expand codeexpand code
import { Component } from '@angular/core';

import type { PdfChangeEvent } from '@delon/abc/pdf';

  selector: 'components-pdf-basic',
  template: `
    <button nz-button nzType="primary" (click)="src = src === one ? two : one">Change File</button>
    <pdf [src]="src" style="height: 300px" (change)="handle($event)"></pdf>
export class ComponentsPdfBasicComponent {
  one = `https://raw.githubusercontent.com/mozilla/pdf.js/master/web/compressed.tracemonkey-pldi-09.pdf`;
  two = `https://raw.githubusercontent.com/mozilla/pdf.js/master/examples/learning/helloworld.pdf`;
  src = this.one;

  handle(ev: PdfChangeEvent): void {


Provide rich interfaces for customization.

expand codeexpand code
import { ChangeDetectorRef, Component, OnInit, ViewChild } from '@angular/core';
import { Subject } from 'rxjs';

import { PdfChangeEvent, PdfComponent, PdfZoomScale } from '@delon/abc/pdf';
import type { NzSafeAny } from 'ng-zorro-antd/core/types';
import { NzUploadFile } from 'ng-zorro-antd/upload';

  selector: 'components-pdf-design',
  template: `
    <div nz-row [nzGutter]="16">
      <div nz-col nzSpan="8">
        <div se-container col="1">
          <se label="Url of the pdf file (Press enter to run)">
            <input #url nz-input [ngModel]="src" (keyup.enter)="uploadSrc(url.value)" />
          <se label="Local of the pdf file">
            <nz-upload nzAccept=".pdf" [nzBeforeUpload]="beforeUpload">
              <button nz-button><i nz-icon nzType="upload"></i>Select File</button>
          <se label="Render Text">
            <nz-switch [(ngModel)]="renderText"></nz-switch>
          <se label="Original size">
            <nz-switch [(ngModel)]="originalSize"></nz-switch>
          <se *ngIf="originalSize" label="Fit to page">
            <nz-switch [(ngModel)]="fitToPage"></nz-switch>
          <se label="Auto size">
            <nz-switch [(ngModel)]="autoReSize"></nz-switch>
          <se label="Show All Pages">
            <nz-switch [(ngModel)]="showAll" (ngModelChange)="changeShowAllPages($event)"></nz-switch>
          <se *ngIf="!originalSize" label="Zoom Scale">
            <nz-select [(ngModel)]="zoomScale">
              <nz-option nzValue="page-height" nzLabel="Page Height"></nz-option>
              <nz-option nzValue="page-fit" nzLabel="Page Fit"></nz-option>
              <nz-option nzValue="page-width" nzLabel="Page Width"></nz-option>
          <se label="Zoom">
            <nz-input-number [(ngModel)]="zoom" [nzStep]="0.1"></nz-input-number>
          <se *ngIf="showAll" label="Stick to page ">
            <nz-switch [(ngModel)]="stickToPage"></nz-switch>
          <se *ngIf="stickToPage" label="Page">
            <nz-pagination [(nzPageIndex)]="pi" [nzPageSize]="1" [nzTotal]="total" nzSimple></nz-pagination>
          <se label="Rotation">
            <nz-input-number [(ngModel)]="rotation" [nzStep]="90"></nz-input-number>
          <se label="Outline">
            <nz-switch [(ngModel)]="outline"></nz-switch>
          <se *ngIf="outline" [label]="null">
            <nz-empty *ngIf="outlineList === null"></nz-empty>
            <ng-template #outlineTpl let-ls let-level="level">
              <li *ngFor="let i of ls" [style.paddingLeft.px]="level * 16">
                <a (click)="navigateTo(i.dest)">{{ i.title }}</a>
                <ul *ngIf="i.items && i.items.length > 0">
                    *ngTemplateOutlet="outlineTpl; context: { $implicit: i.items, level: level + 1 }"
            <ul *ngIf="outlineList">
                *ngTemplateOutlet="outlineTpl; context: { $implicit: outlineList, level: 0 }"
          <se label="Search pdf">
      <div nz-col nzSpan="16" style="background-color: #fafafa; padding: 32px 0;">
          style="height: 600px"
export class ComponentsPdfDesignComponent implements OnInit {
  @ViewChild('pdf') private comp!: PdfComponent;
  src = `https://raw.githubusercontent.com/mozilla/pdf.js/master/web/compressed.tracemonkey-pldi-09.pdf`;
  pi = 1;
  total = 0;
  renderText = true;
  stickToPage = true;
  originalSize = true;
  fitToPage = false;
  showAll = true;
  zoomScale: PdfZoomScale = 'page-width';
  rotation = 0;
  zoom = 1;
  autoReSize = true;
  outline = false;
  outlineList: NzSafeAny = null;
  q = '';
  search$ = new Subject<string>();

  constructor(private cdr: ChangeDetectorRef) {}

  ngOnInit(): void {
    this.search$.subscribe((q: string) => {
      if (q !== this.q) {
        this.q = q;
        this.comp.eventBus?.dispatch('find', {
          query: this.q,
          highlightAll: true
      } else {
        this.comp.eventBus?.dispatch('findagain', {
          query: this.q,
          highlightAll: true

  change(ev: PdfChangeEvent): void {
    switch (ev.type) {
      case 'loaded':
        this.total = ev.total!;
      case 'pi':
        this.pi = ev.pi!;

    if (ev.type !== 'load-progress') console.log(ev);

  uploadSrc(src: string): void {
    this.src = src;

  changeShowAllPages(_val: boolean): void {
    this.stickToPage = true;

  beforeUpload = (file: NzUploadFile): boolean => {
    const reader = new FileReader();
    reader.onload = (e: ProgressEvent<FileReader>) => {
      this.src = e.target!.result as string;
    reader.readAsArrayBuffer(file as unknown as Blob);
    return false;

  loadOutline(): void {
    this.comp.pdf?.getOutline().then(outline => {
      this.outlineList = outline;

  navigateTo(dest: string): void {



PropertyDescriptionTypeDefaultGlobal Config
[src]Specify path of the pdfstring, object, UInt8Array--
[pi]Current pagenumber1-
[showAll]Whether to show all pagesbooleantrue
[renderText]Enable text rendering, allows to select textbooleantrue
[textLayerMode]Text rendering modePdfTextLayerModeENABLE-
[showBorders]Show page bordersbooleanfalse
[stickToPage]Sticks view to the pagebooleanfalse-
[originalSize]Control document display size, true size will be as same as original document, false size will be as same as container blockbooleantrue
[fitToPage]Works in combination with originalSize. You can show your document in original size, and make sure that it's not bigger then container block.booleanfalse
[zoom]Zoom pdfnumber1-
[zoomScale]Defines how the Zoom scale is computedPdfZoomScalepage-width-
[rotation]Rotate PDF, Allowed step is 90 degree, ex. 0, 90, 180number0-
[autoReSize]Turn on or off auto resizebooleantrue
[externalLinkTarget]Link target of the externalPdfExternalLinkTargetBLANK-
[delay]Delayed rendering, unit: msnumber0-
(change)change eventEventEmitter<PdfChangeEvent>--

Component properties

Used API interfaces.

pdfCurrent PDF instance
eventBusEvent bus for PDF files, eg: find document, etc.
findControllerFind controller, now instead by eventBus
pageViewerView Controls
linkServiceNavigation Service


Why need to specify the height of the pdf component

When showAll is enabled, if you want to make the page number control effective, you need to ensure that the height of the component is a valid value.