import { ChangeDetectorRef, Component, OnInit, ViewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { Subject } from 'rxjs';
import { PdfChangeEvent, PdfComponent, PdfZoomScale } from '@delon/abc/pdf';
import { SEModule } from '@delon/abc/se';
import { NzButtonModule } from 'ng-zorro-antd/button';
import type { NzSafeAny } from 'ng-zorro-antd/core/types';
import { NzEmptyModule } from 'ng-zorro-antd/empty';
import { NzGridModule } from 'ng-zorro-antd/grid';
import { NzIconModule } from 'ng-zorro-antd/icon';
import { NzInputModule } from 'ng-zorro-antd/input';
import { NzInputNumberModule } from 'ng-zorro-antd/input-number';
import { NzPaginationModule } from 'ng-zorro-antd/pagination';
import { NzSelectModule } from 'ng-zorro-antd/select';
import { NzSwitchModule } from 'ng-zorro-antd/switch';
import { NzUploadFile, NzUploadModule } from 'ng-zorro-antd/upload';
@Component({
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>
<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>
</nz-upload>
</se>
<se label="Render Text">
<nz-switch [(ngModel)]="renderText" />
</se>
<se label="Original size">
<nz-switch [(ngModel)]="originalSize" />
</se>
@if (originalSize) {
<se label="Fit to page">
<nz-switch [(ngModel)]="fitToPage" />
</se>
}
<se label="Auto size">
<nz-switch [(ngModel)]="autoReSize" />
</se>
<se label="Show All Pages">
<nz-switch [(ngModel)]="showAll" (ngModelChange)="changeShowAllPages($event)" />
</se>
@if (!originalSize) {
<se label="Zoom Scale">
<nz-select [(ngModel)]="zoomScale">
<nz-option nzValue="page-height" nzLabel="Page Height" />
<nz-option nzValue="page-fit" nzLabel="Page Fit" />
<nz-option nzValue="page-width" nzLabel="Page Width" />
</nz-select>
</se>
}
<se label="Zoom">
<nz-input-number [(ngModel)]="zoom" [nzStep]="0.1" />
</se>
@if (showAll) {
<se label="Stick to page ">
<nz-switch [(ngModel)]="stickToPage" />
</se>
}
@if (stickToPage) {
<se label="Page">
<nz-pagination [(nzPageIndex)]="pi" [nzPageSize]="1" [nzTotal]="total" nzSimple />
</se>
}
<se label="Rotation">
<nz-input-number [(ngModel)]="rotation" [nzStep]="90" />
</se>
<se label="Outline">
<nz-switch [(ngModel)]="outline" />
</se>
@if (outline) {
<se [label]="null">
@if (outlineList === null) {
<nz-empty />
}
<ng-template #outlineTpl let-ls let-level="level">
@for (i of ls; track $index) {
<li [style.paddingLeft.px]="level * 16">
<a (click)="navigateTo(i.dest)">{{ i.title }}</a>
@if (i.items && i.items.length > 0) {
<ul>
<ng-container
*ngTemplateOutlet="outlineTpl; context: { $implicit: i.items, level: level + 1 }"
/>
</ul>
}
</li>
}
</ng-template>
@if (outlineList) {
<ul>
<ng-container *ngTemplateOutlet="outlineTpl; context: { $implicit: outlineList, level: 0 }" />
</ul>
}
</se>
}
<se label="Search pdf">
<input
#qIpt
nz-input
placeholder="Search..."
(input)="search$.next(qIpt.value)"
(keyup.enter)="search$.next(qIpt.value)"
/>
</se>
</div>
</div>
<div nz-col nzSpan="16" style="background-color: #fafafa; padding: 32px 0;">
<pdf
#pdf
[src]="src"
[pi]="pi"
[renderText]="renderText"
[showAll]="showAll"
[originalSize]="originalSize"
[fitToPage]="fitToPage"
[stickToPage]="stickToPage"
[zoomScale]="zoomScale"
[zoom]="zoom"
[rotation]="rotation"
[autoReSize]="autoReSize"
(change)="change($event)"
style="height: 600px"
/>
</div>
</div>
`,
standalone: true,
imports: [
NzButtonModule,
PdfComponent,
NzGridModule,
NzInputModule,
FormsModule,
NzUploadModule,
SEModule,
NzIconModule,
NzSwitchModule,
NzSelectModule,
NzInputNumberModule,
NzPaginationModule,
NzEmptyModule
]
})
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!;
this.loadOutline();
break;
case 'pi':
this.pi = ev.pi!;
break;
}
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;
this.cdr.detectChanges();
};
reader.readAsArrayBuffer(file as unknown as Blob);
return false;
};
loadOutline(): void {
this.comp.pdf?.getOutline().then((outline: NzSafeAny) => {
this.outlineList = outline;
});
}
navigateTo(dest: string): void {
this.comp.linkService?.goToDestination(dest);
}
}