UNPKG

@progress/kendo-angular-pdf-export

Version:

Kendo UI for Angular PDF Export Component

510 lines (499 loc) 19.1 kB
/**----------------------------------------------------------------------------------------- * 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 };