@progress/kendo-angular-pdf-export
Version:
Kendo UI for Angular PDF Export Component
510 lines (499 loc) • 19.1 kB
JavaScript
/**-----------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the project root for more information
*-------------------------------------------------------------------------------------------*/
import * as i0 from '@angular/core';
import { Directive, Optional, Component, Input, ContentChild, NgModule } from '@angular/core';
import { drawDOM, exportPDF } from '@progress/kendo-drawing';
import { saveAs } from '@progress/kendo-file-saver';
import { validatePackage } from '@progress/kendo-licensing';
/**
* @hidden
*/
const packageMetadata = {
name: '@progress/kendo-angular-pdf-export',
productName: 'Kendo UI for Angular',
productCode: 'KENDOUIANGULAR',
productCodes: ['KENDOUIANGULAR'],
publishDate: 1764751545,
version: '21.2.0',
licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
};
/**
* Represents the directive for defining a custom page template in the PDF Export component ([see example](slug:multipagecontent_pdfexport#page-templates)).
*
* @example
* ```html
* <kendo-pdf-export paperSize="A4" margin="2cm">
* <ng-template kendoPDFTemplate let-pageNum="pageNum">
* <div>Page {{ pageNum }}</div>
* </ng-template>
* </kendo-pdf-export>
* ```
*/
class PDFExportTemplateDirective {
templateRef;
constructor(templateRef) {
this.templateRef = templateRef;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PDFExportTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: PDFExportTemplateDirective, isStandalone: true, selector: "[kendoPDFTemplate]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PDFExportTemplateDirective, decorators: [{
type: Directive,
args: [{
selector: '[kendoPDFTemplate]',
standalone: true
}]
}], ctorParameters: () => [{ type: i0.TemplateRef, decorators: [{
type: Optional
}] }] });
const FIELDS = ['bottom', 'left', 'right', 'top'];
/**
* Represents the Kendo UI PDFMargin component for Angular.
*
* @example
* ```html
* <kendo-pdf-export paperSize="A4">
* <kendo-pdf-export-margin top="2cm" left="1cm" right="1cm" bottom="2cm">
* </kendo-pdf-export-margin>
* </kendo-pdf-export>
* ```
*/
class PDFExportMarginComponent {
/**
* Sets the left margin of the PDF page. Accepts a `number` or `string` value.
*
* The supported units are `"mm"`, `"cm"`, `"in"`, and `"pt"`. Numbers use points (`"pt"`).
* @default "pt"
*/
left;
/**
* Sets the top margin of the PDF page. Accepts a `number` or `string` value.
*
* The supported units are `"mm"`, `"cm"`, `"in"`, and `"pt"`. Numbers use points (`"pt"`).
* @default "pt"
*/
top;
/**
* Sets the right margin of the PDF page. Accepts a `number` or `string` value.
*
* The supported units are `"mm"`, `"cm"`, `"in"`, and `"pt"`. Numbers use points (`"pt"`).
* @default "pt"
*/
right;
/**
* Sets the bottom margin of the PDF page. Accepts a `number` or `string` value.
*
* The supported units are `"mm"`, `"cm"`, `"in"`, and `"pt"`. Numbers use points (`"pt"`).
* @default "pt"
*/
bottom;
/**
* @hidden
*/
get options() {
const options = {};
for (let idx = 0; idx < FIELDS.length; idx++) {
const field = FIELDS[idx];
const value = this[field];
if (typeof value !== 'undefined') {
options[field] = value;
}
}
return options;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PDFExportMarginComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: PDFExportMarginComponent, isStandalone: true, selector: "kendo-pdf-export-margin", inputs: { left: "left", top: "top", right: "right", bottom: "bottom" }, ngImport: i0, template: ``, isInline: true });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PDFExportMarginComponent, decorators: [{
type: Component,
args: [{
selector: 'kendo-pdf-export-margin',
template: ``,
standalone: true
}]
}], propDecorators: { left: [{
type: Input
}], top: [{
type: Input
}], right: [{
type: Input
}], bottom: [{
type: Input
}] } });
/**
* @hidden
*/
const compileTemplate = (templateRef) => {
const context = {};
let embeddedView = templateRef.createEmbeddedView(context);
const result = (data) => {
Object.assign(context, data);
embeddedView.detectChanges();
const templateWrap = document.createElement('span');
embeddedView.rootNodes.forEach((rootNode) => {
templateWrap.appendChild(rootNode.cloneNode(true));
});
return templateWrap;
};
result.destroy = () => {
embeddedView.destroy();
embeddedView = null;
};
return result;
};
/**
* Represents the [Kendo UI PDF Export component for Angular](slug:overview_pdfexport).
*
* @example
* ```html
* <button kendoButton (click)="pdf.saveAs('document.pdf')">
* Save As PDF...
* </button>
*
* <kendo-pdf-export #pdf paperSize="A4" margin="2cm">
* Content goes here
* </kendo-pdf-export>
* ```
*
* @remarks
* Supported children components are: {@link PDFExportMarginComponent}
*/
class PDFExportComponent {
element;
/**
* If `true`, opens the Print dialog immediately after the PDF loads ([see example](slug:autoprint_pdfexport)).
* Requires `@progress/kendo-drawing` v1.9.0 or later.
* @default false
*/
autoPrint;
/**
* Sets the author metadata for the PDF document.
*/
author;
/**
* Specifies whether actual hyperlinks will be produced in the exported PDF file ([see example](slug:hyperlinks_pdfexport)). You can also set a CSS selector to ignore matching links.
*/
avoidLinks;
/**
* Sets a CSS selector for elements that cause page breaks
* ([see example](slug:multipagecontent_pdfexport#toc-manual-page-breaking)).
*/
forcePageBreak;
/**
* Sets a CSS selector for elements that should not split across pages
* ([see example](slug:multipagecontent_pdfexport#toc-preventing-page-breaking-in-elements)).
*/
keepTogether;
/**
* Sets the creator metadata for the PDF document.
* @default "Kendo UI PDF Generator"
*/
creator = 'Kendo UI PDF Generator';
/**
* Sets the creation date for the PDF document. Defaults to `new Date()`.
* @default new Date()
*/
date;
/**
* Sets the image resolution in the exported PDF ([see example](slug:embeddedimages_pdfexport)). By default, images use full resolution.
*/
imageResolution;
/**
* Sets the name of the exported PDF file.
* @default "export.pdf"
*/
fileName = 'export.pdf';
/**
* If `true`, forwards content to `proxyURL` even if the browser supports local file saving.
*/
forceProxy;
/**
* Sets the keywords metadata for the PDF document.
*/
keywords;
/**
* If `true`, sets the page orientation to landscape. The default page orientation is portrait.
* @default false
*/
landscape;
/**
* Sets the page margins. Numbers use points (`"pt"`).
*/
margin;
/**
* Sets the paper size for the PDF document. Defaults to `"auto"`, which means the content determines the size of the document.
* The size of the content in pixels matches the size of the output in points (1 pixel = 1/72 inch).
*
* If set, the content splits across pages, and allows you to use `repeatHeaders`, `scale`, and a template.
*
* The value can be a `PaperSize`, an array of two numbers (width and height in points), or an array of two strings (width and height in units: `"mm"`, `"cm"`, `"in"`, or `"pt"`).
* @default "auto"
*/
paperSize;
/**
* If `true`, repeats the `<thead>` elements of tables on each page. This helps keep table headers visible on every page
* ([see example](slug:recurrenttableheaders_pdfexport)).
*/
repeatHeaders;
/**
* Sets a scale factor for the PDF output. Use this to make the PDF content smaller or larger
* ([see example](slug:scalingofcontent_pdfexport)).
*
* @default 1
*/
scale;
/**
* Sets a key/value dictionary of form values sent to the proxy. Use this to send extra data, like Anti-Forgery tokens.
*/
proxyData;
/**
* Sets the server-side proxy URL for streaming the file to the user. You need to implement a proxy if
* the browser is not capable of saving files locally.
* The proxy returns the decoded file with the `"Content-Disposition"` header set to `attachment; filename="<fileName.pdf>"`.
*
* In the request body, the proxy receives a POST request with the specific parameters
* ([see example](slug:server_proxy#toc-implementations)).
*/
proxyURL;
/**
* Sets where to display the document returned from the proxy. Use `"_self"` to display in the same window.
* To display the document in a new window or iframe,
* the proxy must have the `"Content-Disposition"` header set to `inline; filename="<fileName.pdf>"`.
* @default "_self"
*/
proxyTarget;
/**
* Sets the producer metadata for the PDF document.
*/
producer;
/**
* Sets the subject metadata for the PDF document.
*/
subject;
/**
* Sets the title metadata for the PDF document.
*/
title;
/**
* @hidden
*/
pageTemplateDirective;
/**
* @hidden
*/
marginComponent;
get drawMargin() {
const marginComponent = this.marginComponent;
let margin = this.margin;
if (marginComponent) {
margin = Object.assign(margin || {}, marginComponent.options);
}
return margin;
}
pageTemplate;
constructor(element) {
this.element = element;
validatePackage(packageMetadata);
}
/**
* Saves the content as a PDF file with the specified name.
* @param fileName - The name of the exported file.
*/
saveAs(fileName = this.fileName) {
this.save(this.element.nativeElement, fileName);
}
/**
* Exports the content as a `Group` for further processing.
*
* @return The root group of the exported scene.
*/
export() {
return this.exportElement(this.element.nativeElement);
}
save(element, fileName) {
this.exportElement(element)
.then(group => this.exportGroup(group, this.pdfOptions()))
.then(dataUri => this.saveDataUri(dataUri, fileName, this.saveOptions()));
}
exportElement(element) {
const promise = this.drawElement(element, this.drawOptions());
const cleanup = this.cleanup.bind(this);
promise.then(cleanup, cleanup);
return promise;
}
cleanup() {
if (this.pageTemplate) {
this.pageTemplate.destroy();
delete this.pageTemplate;
}
}
drawOptions() {
if (this.pageTemplateDirective) {
this.pageTemplate = compileTemplate(this.pageTemplateDirective.templateRef);
}
return {
avoidLinks: this.avoidLinks,
forcePageBreak: this.forcePageBreak,
keepTogether: this.keepTogether,
margin: this.drawMargin,
paperSize: this.paperSize,
landscape: this.landscape,
repeatHeaders: this.repeatHeaders,
scale: this.scale,
template: this.pageTemplate
};
}
pdfOptions() {
return {
autoPrint: this.autoPrint,
author: this.author,
creator: this.creator,
date: this.date,
imgDPI: this.imageResolution,
keywords: this.keywords,
landscape: this.landscape,
margin: this.drawMargin,
multiPage: true,
paperSize: this.paperSize,
producer: this.producer,
subject: this.subject,
title: this.title
};
}
saveOptions() {
return {
forceProxy: this.forceProxy,
proxyData: this.proxyData,
proxyTarget: this.proxyTarget,
proxyURL: this.proxyURL
};
}
drawElement(element, options) {
return drawDOM(element, options);
}
exportGroup(group, options) {
return exportPDF(group, options);
}
saveDataUri(dataUri, fileName, options) {
saveAs(dataUri, fileName, options);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PDFExportComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: PDFExportComponent, isStandalone: true, selector: "kendo-pdf-export", inputs: { autoPrint: "autoPrint", author: "author", avoidLinks: "avoidLinks", forcePageBreak: "forcePageBreak", keepTogether: "keepTogether", creator: "creator", date: "date", imageResolution: "imageResolution", fileName: "fileName", forceProxy: "forceProxy", keywords: "keywords", landscape: "landscape", margin: "margin", paperSize: "paperSize", repeatHeaders: "repeatHeaders", scale: "scale", proxyData: "proxyData", proxyURL: "proxyURL", proxyTarget: "proxyTarget", producer: "producer", subject: "subject", title: "title" }, queries: [{ propertyName: "pageTemplateDirective", first: true, predicate: PDFExportTemplateDirective, descendants: true }, { propertyName: "marginComponent", first: true, predicate: PDFExportMarginComponent, descendants: true }], ngImport: i0, template: `<div><ng-content></ng-content></div>`, isInline: true });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PDFExportComponent, decorators: [{
type: Component,
args: [{
selector: 'kendo-pdf-export',
template: `<div><ng-content></ng-content></div>`,
standalone: true
}]
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { autoPrint: [{
type: Input
}], author: [{
type: Input
}], avoidLinks: [{
type: Input
}], forcePageBreak: [{
type: Input
}], keepTogether: [{
type: Input
}], creator: [{
type: Input
}], date: [{
type: Input
}], imageResolution: [{
type: Input
}], fileName: [{
type: Input
}], forceProxy: [{
type: Input
}], keywords: [{
type: Input
}], landscape: [{
type: Input
}], margin: [{
type: Input
}], paperSize: [{
type: Input
}], repeatHeaders: [{
type: Input
}], scale: [{
type: Input
}], proxyData: [{
type: Input
}], proxyURL: [{
type: Input
}], proxyTarget: [{
type: Input
}], producer: [{
type: Input
}], subject: [{
type: Input
}], title: [{
type: Input
}], pageTemplateDirective: [{
type: ContentChild,
args: [PDFExportTemplateDirective, { static: false }]
}], marginComponent: [{
type: ContentChild,
args: [PDFExportMarginComponent, { static: false }]
}] } });
/**
* Use the `KENDO_PDFEXPORT` utility array to add all `@progress/kendo-angular-pdf-export`-related components and directives to a standalone Angular component.
*
* @example
* ```typescript
* import { Component } from '@angular/core';
* import { KENDO_PDFEXPORT } from "@progress/kendo-angular-pdf-export";
*
* @Component({
* standalone: true,
* imports: [KENDO_PDFEXPORT],
* selector: 'my-app',
* template: `<kendo-pdf-export></kendo-pdf-export>`
* })
* export class AppComponent {}
* ```
*/
const KENDO_PDFEXPORT = [
PDFExportComponent,
PDFExportMarginComponent,
PDFExportTemplateDirective
];
// IMPORTANT: NgModule export kept for backwards compatibility
/**
* Represents the [`NgModule`](link:site.data.urls.angular['ngmoduleapi']) definition for the PDF Export component.
*
* @example
* ```typescript
* import { NgModule } from '@angular/core';
* import { BrowserModule } from '@angular/platform-browser';
* import { PDFExportModule } from '@progress/kendo-angular-pdf-export';
* import { AppComponent } from './app.component';
*
* @NgModule({
* declarations: [AppComponent],
* imports: [BrowserModule, PDFExportModule],
* bootstrap: [AppComponent]
* })
* export class AppModule {}
* ```
*/
class PDFExportModule {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PDFExportModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: PDFExportModule, imports: [PDFExportComponent, PDFExportMarginComponent, PDFExportTemplateDirective], exports: [PDFExportComponent, PDFExportMarginComponent, PDFExportTemplateDirective] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PDFExportModule });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PDFExportModule, decorators: [{
type: NgModule,
args: [{
imports: [...KENDO_PDFEXPORT],
exports: [...KENDO_PDFEXPORT]
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { KENDO_PDFEXPORT, PDFExportComponent, PDFExportMarginComponent, PDFExportModule, PDFExportTemplateDirective, compileTemplate };