@aprova.ch/ngx-next-pdf-viewer
v21.0.7
Published
Angular PDF viewer with bounding-box annotations, search, zoom and page rotation
Downloads
1,119
Maintainers
Readme
ngx-next-pdf-viewer
An Angular component for rendering PDFs with bounding-box annotations, drag-to-select, search, zoom, and rotation — powered by PDF.js.
Features
- Canvas-based PDF rendering with HiDPI (devicePixelRatio) support
- Bounding-box annotation overlay (SVG polygons)
- Single-click highlight +
boxClickedoutput event - Drag-to-select multiple boxes + context menu +
boxesSelectedoutput event - Toolbar: zoom in/out, rotate left/right, previous/next page, text search
- Ctrl + scroll wheel zoom
- Configurable worker URL via injection token
Installation
npm install ngx-next-pdf-viewerCopy the PDF.js worker to your assets (once):
cp node_modules/pdfjs-dist/build/pdf.worker.min.mjs src/assets/Or add it to angular.json assets:
{
"glob": "pdf.worker.min.mjs",
"input": "node_modules/pdfjs-dist/build",
"output": "/assets/"
}Usage
import { NgxNextPdfViewerComponent } from 'ngx-next-pdf-viewer';
@Component({
imports: [NgxNextPdfViewerComponent],
template: `
<ngx-next-pdf-viewer
style="height: 600px; display: block;"
[blob]="myBlob"
[annotations]="myBoxes"
[contextMenuItems]="[{ label: 'Copy', action: 'copy' }]"
(boxClicked)="onBoxClicked($event)"
(boxesSelected)="onBoxesSelected($event)"
/>
`
})
export class AppComponent { ... }Inputs
| Input | Type | Default | Description |
|--------------------|----------------------------|-----------------------------|---------------------------------------------------|
| blob | Blob \| undefined | undefined | The PDF file as a Blob |
| annotations | BoundingBox[] | [] | Annotation boxes to render as SVG polygons |
| contextMenuItems | ContextMenuItem[] | [] | Items shown in right-click menu after drag-select |
| highlightingColor| string | 'rgba(255,200,0,0.35)' | Fill color of the clicked/highlighted box |
| selectedColor | string | 'rgba(0,120,215,0.35)' | Fill color of multi-selected boxes |
| annotationStroke | string | '#e97332' | Stroke color of annotation polygons |
| initialZoom | number or string | 1.5 or fit-to-width or fit-to-height or fit-to-page | Zoom level applied when the PDF first loads |
| page | number \| undefined | undefined | When set or changed, scrolls to this page number |
| labels | Partial<PdfViewerLabels> | see below | Override any subset of the viewer's UI strings |
Outputs
License required — The output events (
boxClicked,boxesSelected) are only available with a valid license.
- 30-day trial: Contact the Telegram bot @AprovaLicenceBot
- Permanent license: Email [email protected]
| Output | Type | Description |
|-----------------|--------------------------------------------------------|-------------------------------------------------------|
| boxClicked | EventEmitter<{ box: BoundingBox; selected: boolean }> | Emitted when a box is clicked (select or deselect) |
| boxesSelected | EventEmitter<{ boxes: BoundingBox[]; action: string }> | Emitted when drag-select + context menu action chosen |
Configuring the worker URL
By default the worker is loaded from assets/pdf.worker.min.mjs. Override:
providers: [
{ provide: NGX_PDF_WORKER_SRC, useValue: 'assets/custom/pdf.worker.min.mjs' }
]Localisation
Pass a Partial<PdfViewerLabels> to override any subset of the built-in English strings:
<ngx-next-pdf-viewer
[blob]="myBlob"
[labels]="{
zoomOut: 'Verkleinern',
zoomIn: 'Vergrößern',
rotateLeft: 'Links drehen',
rotateRight: 'Rechts drehen',
previousPage: 'Vorherige Seite',
nextPage: 'Nächste Seite',
search: 'Suchen',
previousResult: 'Vorheriges Ergebnis',
nextResult: 'Nächstes Ergebnis',
searchPlaceholder: 'Im PDF suchen…',
noResults: 'Keine Ergebnisse',
loading: 'PDF wird geladen…',
noDocument: 'Kein PDF geladen',
loadError: 'PDF konnte nicht geladen werden',
}"
/>Models
interface BoundingBox {
page: number; // 1-based page number
width: number; // page width in the unit given by `unit`
height: number; // page height in the unit given by `unit`
polygon: number[]; // [x1,y1, x2,y2, x3,y3, x4,y4] – clockwise, y=0 at top
unit?: string; // "inch" (Azure DI) or "pixel" / omit for pixel-space
angle?: number; // page rotation when the polygon was extracted
content?: string;
[key: string]: any;
}
interface PdfViewerLabels {
zoomOut: string; zoomIn: string;
rotateLeft: string; rotateRight: string;
previousPage: string; nextPage: string;
search: string; previousResult: string; nextResult: string;
searchPlaceholder: string; noResults: string;
loading: string; noDocument: string; loadError: string;
}
interface ContextMenuItem {
label: string;
action: string;
}License
MIT
