From bd765ebe523f8a2efce4fa47e61582ef19de5a9f Mon Sep 17 00:00:00 2001 From: "AzureAD\\DhakshinPrasathDhanr" Date: Mon, 31 Aug 2026 15:41:23 +0530 Subject: [PATCH 01/11] Task(1050196): Added contents for newly added features --- .../PDF/PDF-Library/javascript/Annotations.md | 290 +++++++++ .../javascript/DigitalSignature.md | 248 ++++++++ .../PDF/PDF-Library/javascript/Encryption.md | 558 ++++++++++++++++++ .../PDF/PDF-Library/javascript/Lists.md | 83 +++ .../PDF-Library/javascript/Text-Extraction.md | 96 +++ .../PDF/PDF-Library/javascript/Text.md | 41 ++ 6 files changed, 1316 insertions(+) create mode 100644 Document-Processing/PDF/PDF-Library/javascript/Encryption.md diff --git a/Document-Processing/PDF/PDF-Library/javascript/Annotations.md b/Document-Processing/PDF/PDF-Library/javascript/Annotations.md index 8ae876e087..ba73e1d681 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/Annotations.md +++ b/Document-Processing/PDF/PDF-Library/javascript/Annotations.md @@ -1019,6 +1019,296 @@ document.destroy(); {% endhighlight %} {% endtabs %} +## Cloud Border Style Annotation + +A cloud border style can be applied to rectangle, polygon, circle, and ellipse annotations in an existing PDF document by using the [PdfBorderEffect](https://ej2.syncfusion.com/documentation/api/pdf/pdfbordereffect) class. Set the `intensity` property to control the intensity of the cloud effect and set the `style` property to `PdfBorderEffectStyle.cloudy`. + +### PdfRectangleAnnotation + +A cloud border style can be applied to an existing [PdfRectangleAnnotation](https://ej2.syncfusion.com/documentation/api/pdf/pdfrectangleannotation) by using the [PdfBorderEffect](https://ej2.syncfusion.com/documentation/api/pdf/pdfbordereffect) class. + +The following code example demonstrates how to apply a cloud border style to an existing rectangle annotation in a PDF document. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import {PdfBorderEffect, PdfBorderEffectStyle, PdfDocument, PdfPage, PdfRectangleAnnotation} from '@syncfusion/ej2-pdf'; + +// Load an existing PDF document +let document: PdfDocument = new PdfDocument(data, password); +// Get the first page +let page: PdfPage = document.getPage(0) as PdfPage; +// Get the first rectangle annotation of the page +let annotation: PdfRectangleAnnotation = page.annotations.at(0) as PdfRectangleAnnotation; +// Initialize a new instance of the `PdfBorderEffect` class +let borderEffect: PdfBorderEffect = new PdfBorderEffect(); +// Set the intensity of the annotation border +borderEffect.intensity = 2; +// Set the cloud style of the annotation border +borderEffect.style = PdfBorderEffectStyle.cloudy; +// Set the border effect to the annotation +annotation.borderEffect = borderEffect; +// Save the document +document.save('Output.pdf'); +// Destroy the document +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load an existing PDF document +var document = new ej.pdf.PdfDocument(data, password); +// Get the first page +var page = document.getPage(0); +// Get the first rectangle annotation of the page +var annotation = page.annotations.at(0); +// Initialize a new instance of the PdfBorderEffect class +var borderEffect = new ej.pdf.PdfBorderEffect(); +// Set the intensity of the annotation border +borderEffect.intensity = 2; +// Set the cloud style of the annotation border +borderEffect.style = ej.pdf.PdfBorderEffectStyle.cloudy; +// Set the border effect to the annotation +annotation.borderEffect = borderEffect; +// Save the document +document.save('Output.pdf'); +// Destroy the document +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +### PdfPolygonAnnotation + +A cloud border style can be applied to an existing [PdfPolygonAnnotation](https://ej2.syncfusion.com/documentation/api/pdf/pdfpolygonannotation) by using the [PdfBorderEffect](https://ej2.syncfusion.com/documentation/api/pdf/pdfbordereffect) class. + +The following code example demonstrates how to apply a cloud border style to an existing polygon annotation in a PDF document. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import {PdfBorderEffect, PdfBorderEffectStyle, PdfDocument, PdfPage, PdfPolygonAnnotation} from '@syncfusion/ej2-pdf'; + +// Load an existing PDF document +let document: PdfDocument = new PdfDocument(data, password); +// Get the first page +let page: PdfPage = document.getPage(0) as PdfPage; +// Get the first polygon annotation of the page +let annotation: PdfPolygonAnnotation = page.annotations.at(0) as PdfPolygonAnnotation; +// Initialize a new instance of the `PdfBorderEffect` class +let borderEffect: PdfBorderEffect = new PdfBorderEffect(); +// Set the intensity of the annotation border +borderEffect.intensity = 2; +// Set the cloud style of the annotation border +borderEffect.style = PdfBorderEffectStyle.cloudy; +// Set the border effect to the annotation +annotation.borderEffect = borderEffect; +// Save the document +document.save('Output.pdf'); +// Destroy the document +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load an existing PDF document +var document = new ej.pdf.PdfDocument(data, password); +// Get the first page +var page = document.getPage(0); +// Get the first polygon annotation of the page +var annotation = page.annotations.at(0); +// Initialize a new instance of the PdfBorderEffect class +var borderEffect = new ej.pdf.PdfBorderEffect(); +// Set the intensity of the annotation border +borderEffect.intensity = 2; +// Set the cloud style of the annotation border +borderEffect.style = ej.pdf.PdfBorderEffectStyle.cloudy; +// Set the border effect to the annotation +annotation.borderEffect = borderEffect; +// Save the document +document.save('Output.pdf'); +// Destroy the document +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +### PdfCircleAnnotation + +A cloud border style can be applied to an existing [PdfCircleAnnotation](https://ej2.syncfusion.com/documentation/api/pdf/pdfcircleannotation) by using the [PdfBorderEffect](https://ej2.syncfusion.com/documentation/api/pdf/pdfbordereffect) class. + +The following code example demonstrates how to apply a cloud border style to an existing circle annotation in a PDF document. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import {PdfBorderEffect, PdfBorderEffectStyle, PdfCircleAnnotation, PdfDocument, PdfPage} from '@syncfusion/ej2-pdf'; + +// Load an existing PDF document +let document: PdfDocument = new PdfDocument(data, password); +// Get the first page +let page: PdfPage = document.getPage(0) as PdfPage; +// Get the first circle annotation of the page +let annotation: PdfCircleAnnotation = page.annotations.at(0) as PdfCircleAnnotation; +// Initialize a new instance of the `PdfBorderEffect` class +let borderEffect: PdfBorderEffect = new PdfBorderEffect(); +// Set the intensity of the annotation border +borderEffect.intensity = 2; +// Set the cloud style of the annotation border +borderEffect.style = PdfBorderEffectStyle.cloudy; +// Set the border effect to the annotation +annotation.borderEffect = borderEffect; +// Generate the annotation appearance +annotation.setAppearance(true); +// Save the document +document.save('Output.pdf'); +// Destroy the document +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load an existing PDF document +var document = new ej.pdf.PdfDocument(data, password); +// Get the first page +var page = document.getPage(0); +// Get the first circle annotation of the page +var annotation = page.annotations.at(0); +// Initialize a new instance of the PdfBorderEffect class +var borderEffect = new ej.pdf.PdfBorderEffect(); +// Set the intensity of the annotation border +borderEffect.intensity = 2; +// Set the cloud style of the annotation border +borderEffect.style = ej.pdf.PdfBorderEffectStyle.cloudy; +// Set the border effect to the annotation +annotation.borderEffect = borderEffect; +// Generate the annotation appearance +annotation.setAppearance(true); +// Save the document +document.save('Output.pdf'); +// Destroy the document +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +### PdfEllipseAnnotation + +A cloud border style can be applied to an existing [PdfEllipseAnnotation](https://ej2.syncfusion.com/documentation/api/pdf/pdfellipseannotation) by using the [PdfBorderEffect](https://ej2.syncfusion.com/documentation/api/pdf/pdfbordereffect) class. + +The following code example demonstrates how to apply a cloud border style to an existing ellipse annotation in a PDF document. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import {PdfBorderEffect, PdfBorderEffectStyle, PdfDocument, PdfEllipseAnnotation, PdfPage} from '@syncfusion/ej2-pdf'; + +// Load an existing PDF document +let document: PdfDocument = new PdfDocument(data, password); +// Get the first page +let page: PdfPage = document.getPage(0) as PdfPage; +// Get the first ellipse annotation of the page +let annotation: PdfEllipseAnnotation = page.annotations.at(0) as PdfEllipseAnnotation; +// Initialize a new instance of the `PdfBorderEffect` class +let borderEffect: PdfBorderEffect = new PdfBorderEffect(); +// Set the intensity of the annotation border +borderEffect.intensity = 2; +// Set the cloud style of the annotation border +borderEffect.style = PdfBorderEffectStyle.cloudy; +// Set the border effect to the annotation +annotation.borderEffect = borderEffect; +// Generate the annotation appearance +annotation.setAppearance(true); +// Save the document +document.save('Output.pdf'); +// Destroy the document +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load an existing PDF document +var document = new ej.pdf.PdfDocument(data, password); +// Get the first page +var page = document.getPage(0); +// Get the first ellipse annotation of the page +var annotation = page.annotations.at(0); +// Initialize a new instance of the PdfBorderEffect class +var borderEffect = new ej.pdf.PdfBorderEffect(); +// Set the intensity of the annotation border +borderEffect.intensity = 2; +// Set the cloud style of the annotation border +borderEffect.style = ej.pdf.PdfBorderEffectStyle.cloudy; +// Set the border effect to the annotation +annotation.borderEffect = borderEffect; +// Generate the annotation appearance +annotation.setAppearance(true); +// Save the document +document.save('Output.pdf'); +// Destroy the document +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +### PdfFreeTextAnnotation + +A cloud border style can be applied to an existing [PdfFreeTextAnnotation](https://ej2.syncfusion.com/documentation/api/pdf/pdffreetextannotation) by using the [PdfBorderEffect](https://ej2.syncfusion.com/documentation/api/pdf/pdfbordereffect) class. + +The following code example demonstrates how to apply a cloud border style to an existing free text annotation in a PDF document. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfBorderEffect, PdfBorderEffectStyle, PdfDocument, PdfFreeTextAnnotation, PdfPage } from '@syncfusion/ej2-pdf'; + +// Load an existing PDF document +let document: PdfDocument = new PdfDocument(data, password); +// Get the first page +let page: PdfPage = document.getPage(0) as PdfPage; +// Get the first free text annotation of the page +let annotation: PdfFreeTextAnnotation = page.annotations.at(0) as PdfFreeTextAnnotation; +// Initialize a new instance of the `PdfBorderEffect` class +let borderEffect: PdfBorderEffect = new PdfBorderEffect(); +// Set the intensity of the annotation border +borderEffect.intensity = 2; +// Set the cloud style of the annotation border +borderEffect.style = PdfBorderEffectStyle.cloudy; +// Set the border effect to the annotation +annotation.borderEffect = borderEffect; +// Generate the annotation appearance +annotation.setAppearance(true); +// Save the document +document.save('Output.pdf'); +// Destroy the document +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load an existing PDF document +var document = new ej.pdf.PdfDocument(data, password); +// Get the first page +var page = document.getPage(0); +// Get the first free text annotation of the page +var annotation = page.annotations.at(0); +// Initialize a new instance of the PdfBorderEffect class +var borderEffect = new ej.pdf.PdfBorderEffect(); +// Set the intensity of the annotation border +borderEffect.intensity = 2; +// Set the cloud style of the annotation border +borderEffect.style = ej.pdf.PdfBorderEffectStyle.cloudy; +// Set the border effect to the annotation +annotation.borderEffect = borderEffect; +// Generate the annotation appearance +annotation.setAppearance(true); +// Save the document +document.save('Output.pdf'); +// Destroy the document +document.destroy(); + +{% endhighlight %} +{% endtabs %} ## Custom appearance in stamp annotation diff --git a/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md b/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md index 5796f43144..a8ef8e197e 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md +++ b/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md @@ -803,6 +803,254 @@ document.destroy(); {% endhighlight %} {% endtabs %} +## Digital signature validation + +The JavaScript PDF Library supports validating digital signatures in an existing PDF document. Digital signature validation verifies the following information to determine the validity of each signature: + +* Document modifications made after signing. +* The certificate chain against the provided trusted certificates. +* Timestamp information associated with the signature. +* Certificate revocation status using Online Certificate Status Protocol (OCSP) and Certificate Revocation List (CRL) information. +* Multiple digital signatures available in the PDF document. + +Use the `validateSignatures` method of `PdfForm` to validate the digital signatures in a PDF document. Configure the trusted certificates and their passwords using `PdfSignatureValidationOptions`. + +The `validateSignatures` method returns the overall validation status and the individual validation results. The `isValid` property indicates whether all the validated signatures are valid. The `results` property contains details such as the signature name, signature status, document modification status, and revocation result for each signature. + +The following code example shows how to validate the digital signatures in an existing PDF document. + +{% tabs %} + +{% highlight javascript tabtitle="JavaScript" %} + +import { + PdfDocument +} from '@syncfusion/ej2-pdf'; + +// Fetch a file and return its content as a Uint8Array. +async function fetchAsUint8Array(url) { + const response = await fetch(url); + if (!response.ok) { + throw new Error(`Failed to load the file: ${response.statusText}`); + } + return new Uint8Array(await response.arrayBuffer()); +} + +// Load the signed PDF document. +const documentData = await fetchAsUint8Array('Input.pdf'); +const document = new PdfDocument(documentData); + +// Load the trusted certificate. +const certificateData = await fetchAsUint8Array('PDF.pfx'); + +// Configure the signature validation options. +const options = { + trustedCertificates: [certificateData], + passwords: ['syncfusion'] +}; + +// Validate the digital signatures in the PDF document. +const validationResult = document.form.validateSignatures(options); + +// Check the validation result of each signature. +if (validationResult.results !== null && + validationResult.results !== undefined) { + validationResult.results.forEach((result) => { + console.log('Signature name: ' + result.signatureName); + console.log('Signature valid: ' + result.isSignatureValid); + console.log('Signature status: ' + result.signatureStatus); + console.log('Document modified: ' + result.isDocumentModified); + console.log('Revocation result: ', result.revocationResult); + }); +} + +// Get the overall signature validation status. +console.log('All signatures valid: ' + validationResult.isValid); + +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} + +{% highlight typescript tabtitle="TypeScript" %} + +import { + PdfDocument, + PdfSignatureValidationOptions +} from '@syncfusion/ej2-pdf'; + +// Fetch a file and return its content as a Uint8Array. +async function fetchAsUint8Array(url: string): Promise { + const response: Response = await fetch(url); + if (!response.ok) { + throw new Error(`Failed to load the file: ${response.statusText}`); + } + return new Uint8Array(await response.arrayBuffer()); +} + +// Load the signed PDF document. +const documentData: Uint8Array = await fetchAsUint8Array('Input.pdf'); +const document: PdfDocument = new PdfDocument(documentData); + +// Load the trusted certificate. +const certificateData: Uint8Array = await fetchAsUint8Array('PDF.pfx'); + +// Configure the signature validation options. +const options: PdfSignatureValidationOptions = { + trustedCertificates: [certificateData], + passwords: ['syncfusion'] +}; + +// Validate the digital signatures in the PDF document. +const validationResult = document.form.validateSignatures(options); + +// Check the validation result of each signature. +if (validationResult.results !== null && + validationResult.results !== undefined) { + validationResult.results.forEach((result) => { + console.log('Signature name: ' + result.signatureName); + console.log('Signature valid: ' + result.isSignatureValid); + console.log('Signature status: ' + result.signatureStatus); + console.log('Document modified: ' + result.isDocumentModified); + console.log('Revocation result: ', result.revocationResult); + }); +} + +// Get the overall signature validation status. +console.log('All signatures valid: ' + validationResult.isValid); + +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} + +{% endtabs %} + +## Validate all signatures in a PDF document + +You can validate all digital signatures in a PDF document by calling the `validateSignatures` method. The method validates every signature field in the document and returns the individual results through the `results` collection. + +The following code example shows how to validate all signatures and determine whether the complete PDF document has valid signatures. + +{% tabs %} + +{% highlight javascript tabtitle="JavaScript" %} + +import { + PdfDocument +} from '@syncfusion/ej2-pdf'; + +// Fetch a file and return its content as a Uint8Array. +async function fetchAsUint8Array(url) { + const response = await fetch(url); + if (!response.ok) { + throw new Error(`Failed to load the file: ${response.statusText}`); + } + return new Uint8Array(await response.arrayBuffer()); +} + +// Load the PDF document that contains multiple signatures. +const documentData = await fetchAsUint8Array('Input.pdf'); +const document = new PdfDocument(documentData); + +// Load the trusted certificate used for signature validation. +const certificateData = await fetchAsUint8Array('PDF.pfx'); + +// Configure the validation options. +const options = { + trustedCertificates: [certificateData], + passwords: ['syncfusion'] +}; + +// Validate all signatures in the PDF document. +const validationResult = document.form.validateSignatures(options); + +if (validationResult.results !== null && + validationResult.results !== undefined) { + console.log( + 'Number of validated signatures: ' + + validationResult.results.length + ); + + validationResult.results.forEach((result) => { + console.log( + `${result.signatureName}: ${result.isSignatureValid}` + ); + }); +} + +// Determine whether all signatures are valid. +if (validationResult.isValid) { + console.log('All signatures in the PDF document are valid.'); +} else { + console.log('One or more signatures in the PDF document are invalid.'); +} + +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} + +{% highlight typescript tabtitle="TypeScript" %} + +import { + PdfDocument, + PdfSignatureValidationOptions +} from '@syncfusion/ej2-pdf'; + +// Fetch a file and return its content as a Uint8Array. +async function fetchAsUint8Array(url: string): Promise { + const response: Response = await fetch(url); + if (!response.ok) { + throw new Error(`Failed to load the file: ${response.statusText}`); + } + return new Uint8Array(await response.arrayBuffer()); +} + +// Load the PDF document that contains multiple signatures. +const documentData: Uint8Array = await fetchAsUint8Array('Input.pdf'); +const document: PdfDocument = new PdfDocument(documentData); + +// Load the trusted certificate used for signature validation. +const certificateData: Uint8Array = await fetchAsUint8Array('PDF.pfx'); + +// Configure the validation options. +const options: PdfSignatureValidationOptions = { + trustedCertificates: [certificateData], + passwords: ['syncfusion'] +}; + +// Validate all signatures in the PDF document. +const validationResult = document.form.validateSignatures(options); + +if (validationResult.results !== null && + validationResult.results !== undefined) { + console.log( + 'Number of validated signatures: ' + + validationResult.results.length + ); + + validationResult.results.forEach((result) => { + console.log( + `${result.signatureName}: ${result.isSignatureValid}` + ); + }); +} + +// Determine whether all signatures are valid. +if (validationResult.isValid) { + console.log('All signatures in the PDF document are valid.'); +} else { + console.log('One or more signatures in the PDF document are invalid.'); +} + +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} + +{% endtabs %} + ## Inspecting signatures The following examples demonstrate how to read information from existing signatures in a PDF document. diff --git a/Document-Processing/PDF/PDF-Library/javascript/Encryption.md b/Document-Processing/PDF/PDF-Library/javascript/Encryption.md new file mode 100644 index 0000000000..bb12e1b207 --- /dev/null +++ b/Document-Processing/PDF/PDF-Library/javascript/Encryption.md @@ -0,0 +1,558 @@ +--- +title: Encryption in JavaScript PDF Library | Syncfusion +description: Learn how to protect PDF documents with encryption and set permissions for printing, editing, and copying using Syncfusion JavaScript PDF Library. +platform: document-processing +control: PDF +documentation: UG +--- + +# Encryption in JavaScript PDF Library + +The Syncfusion JavaScript PDF Library allows you to secure PDF documents using RC4 and AES encryption algorithms. You can also apply user and owner passwords and define permissions for operations such as printing, editing, copying content, filling form fields, and assembling documents. + +A **user password** controls whether a user can open the PDF document. An **owner password** controls whether a user can change the document permissions. When both passwords are used, specify different values for better security. + +The supported encryption algorithms are: + +- Rivest Cipher 4 (RC4) +- Advanced Encryption Standard (AES) + +## Working with RC4 encryption + +You can encrypt a PDF document using 40-bit or 128-bit RC4 encryption by setting the `encryptionType` property of `PdfSecurityOptions` to `PdfEncryptionType.rc4Bit40` or `PdfEncryptionType.rc4Bit128`. + +The following example encrypts a new PDF document using RC4 128-bit encryption and a user password. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { + PdfBrush, + PdfDocument, + PdfEncryptionType, + PdfFontFamily, + PdfFontStyle, + PdfSecurityOptions, + PdfStandardFont +} from '@syncfusion/ej2-pdf'; + +// Create a new PDF document. +const document: PdfDocument = new PdfDocument(); +// Add a page to the document. +const page = document.addPage(); +// Draw text on the page. +page.graphics.drawString( + 'Encrypted with RC4 128-bit encryption', + new PdfStandardFont(PdfFontFamily.helvetica, 12, PdfFontStyle.regular), + { x: 10, y: 20, width: 300, height: 50 }, + new PdfBrush({ r: 0, g: 0, b: 0 }) +); +// Configure RC4 security using a user password. +const options: PdfSecurityOptions = { + encryptionType: PdfEncryptionType.rc4Bit128, + userPassword: 'password' +}; +document.setSecurity(options); +// Save the encrypted PDF document. +const data: Uint8Array = document.save('Output.pdf'); +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} + +{% highlight javascript tabtitle="JavaScript" %} + +// Create a new PDF document. +const document = new ej.pdf.PdfDocument(); +// Add a page to the document. +const page = document.addPage(); +// Draw text on the page. +page.graphics.drawString( + 'Encrypted with RC4 128-bit encryption', + new ej.pdf.PdfStandardFont(ej.pdf.PdfFontFamily.helvetica, 12, ej.pdf.PdfFontStyle.regular), + { x: 10, y: 20, width: 300, height: 50 }, + new PdfBrush({ r: 0, g: 0, b: 0 }) +); +// Configure RC4 security using a user password. +document.setSecurity({ + encryptionType: ej.pdf.PdfEncryptionType.rc4Bit128, + userPassword: 'password' +}); +// Save the encrypted PDF document. +const data = document.save('Output.pdf'); +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +You can restrict document operations by specifying an owner password and permission flags. The following security configuration permits printing and accessibility-based content copying. + +```typescript +const options: PdfSecurityOptions = { + encryptionType: PdfEncryptionType.rc4Bit128, + ownerPassword: 'ownerPassword', + userPassword: 'userPassword', + permissions: PdfPermissionFlag.print | + PdfPermissionFlag.accessibilityCopyContent +}; +document.setSecurity(options); +``` + +N> When both user and owner passwords are specified, use different values for the two passwords. + +## Working with AES encryption + +You can encrypt a PDF document using AES encryption by setting the `encryptionType` property to a supported AES value such as `PdfEncryptionType.aesBit128`, `PdfEncryptionType.aesBit256Rev5`, or `PdfEncryptionType.aesBit256Rev6`. + +The following example encrypts a new PDF document using AES 256-bit Revision 5 encryption and an owner password. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { + PdfDocument, + PdfEncryptionType, + PdfSecurityOptions +} from '@syncfusion/ej2-pdf'; + +// Create a new PDF document. +const document: PdfDocument = new PdfDocument(); +// Add a page to the document. +document.addPage(); +// Configure AES security using an owner password. +const options: PdfSecurityOptions = { + encryptionType: PdfEncryptionType.aesBit256Rev5, + ownerPassword: 'ownerPassword' +}; +document.setSecurity(options); +// Save the encrypted PDF document. +document.save('Output.pdf'); +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +import { + PdfDocument, + PdfEncryptionType +} from '@syncfusion/ej2-pdf'; + +// Create a new PDF document. +const document = new ej.pdf.PdfDocument(); +// Add a page to the document. +document.addPage(); +// Configure AES security using an owner password. +document.setSecurity({ + encryptionType: ej.pdf.PdfEncryptionType.aesBit256Rev5, + ownerPassword: 'ownerPassword' +}); +// Save the encrypted PDF document. +document.save('Output.pdf'); +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Decrypting an encrypted PDF document + +The JavaScript PDF Library supports decrypting a secured PDF document by loading it with a valid password, clearing its passwords, and saving it again. Reset the permission flags when the document restrictions must also be removed. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { + PdfDocument, + PdfPermissionFlag, + PdfSecurityOptions +} from '@syncfusion/ej2-pdf'; + +// Load the encrypted PDF document data. +const response: Response = await fetch('Input.pdf'); +const inputData: Uint8Array = new Uint8Array(await response.arrayBuffer()); +// Open the document using a valid password. +const document: PdfDocument = new PdfDocument(inputData, 'syncfusion'); +// Clear the passwords and restore all supported permissions. +const options: PdfSecurityOptions = { + userPassword: '', + ownerPassword: '', + permissions: PdfPermissionFlag.print | + PdfPermissionFlag.copyContent | + PdfPermissionFlag.editContent | + PdfPermissionFlag.editAnnotations | + PdfPermissionFlag.fillFields | + PdfPermissionFlag.accessibilityCopyContent | + PdfPermissionFlag.assembleDocument | + PdfPermissionFlag.fullQualityPrint +}; +document.setSecurity(options); +// Save the decrypted PDF document. +document.save('Output.pdf'); +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load the encrypted PDF document data. +const response = await fetch('Input.pdf'); +const inputData = new Uint8Array(await response.arrayBuffer()); +// Open the document using a valid password. +const document = new ej.pdf.PdfDocument(inputData, 'syncfusion'); +// Clear the passwords and restore all supported permissions. +document.setSecurity({ + userPassword: '', + ownerPassword: '', + permissions: ej.pdf.PdfPermissionFlag.print | + ej.pdf.PdfPermissionFlag.copyContent | + ej.pdf.PdfPermissionFlag.editContent | + ej.pdf.PdfPermissionFlag.editAnnotations | + ej.pdf.PdfPermissionFlag.fillFields | + ej.pdf.PdfPermissionFlag.accessibilityCopyContent | + ej.pdf.PdfPermissionFlag.assembleDocument | + ej.pdf.PdfPermissionFlag.fullQualityPrint +}); +// Save the decrypted PDF document. +document.save('Output.pdf'); +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Protect an existing PDF document + +You can protect an existing PDF document by loading its data, configuring the required encryption type and passwords, and saving the document. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { + PdfDocument, + PdfEncryptionType, + PdfSecurityOptions +} from '@syncfusion/ej2-pdf'; + +// Load an existing PDF document. +const response: Response = await fetch('Input.pdf'); +const inputData: Uint8Array = new Uint8Array(await response.arrayBuffer()); +const document: PdfDocument = new PdfDocument(inputData); +// Protect the document using AES encryption. +const options: PdfSecurityOptions = { + encryptionType: PdfEncryptionType.aesBit256Rev5, + ownerPassword: 'ownerPassword256', + userPassword: 'userPassword256' +}; +document.setSecurity(options); +// Save the protected PDF document. +document.save('Output.pdf'); +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load an existing PDF document. +const response = await fetch('Input.pdf'); +const inputData = new Uint8Array(await response.arrayBuffer()); +const document = new ej.pdf.PdfDocument(inputData); +// Protect the document using AES encryption. +document.setSecurity({ + encryptionType: ej.pdf.PdfEncryptionType.aesBit256Rev5, + ownerPassword: 'ownerPassword256', + userPassword: 'userPassword256' +}); +// Save the protected PDF document. +document.save('Output.pdf'); +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Changing the password of a PDF document + +You can change the user password of an existing encrypted PDF document by loading it with the current password and applying the new password through `setSecurity`. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { + PdfDocument, + PdfSecurityOptions +} from '@syncfusion/ej2-pdf'; + +// Load the password-protected PDF document. +const response: Response = await fetch('Input.pdf'); +const inputData: Uint8Array = new Uint8Array(await response.arrayBuffer()); +const document: PdfDocument = new PdfDocument(inputData, 'password'); +// Change the user password. +const options: PdfSecurityOptions = { + userPassword: 'NewPassword' +}; +document.setSecurity(options); +// Save the password-changed PDF document. +document.save('Output.pdf'); +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load the password-protected PDF document. +const response = await fetch('Input.pdf'); +const inputData = new Uint8Array(await response.arrayBuffer()); +const document = new ej.pdf.PdfDocument(inputData, 'password'); +// Change the user password. +document.setSecurity({ + userPassword: 'NewPassword' +}); +// Save the password-changed PDF document. +document.save('Output.pdf'); +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Change the permissions of a PDF document + +You can change the permissions of an existing secured PDF document using the `permissions` property of `PdfSecurityOptions`. Load the document using a valid password before updating the permission flags. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { + PdfDocument, + PdfPermissionFlag, + PdfSecurityOptions +} from '@syncfusion/ej2-pdf'; + +// Load the secured PDF document. +const response: Response = await fetch('Input.pdf'); +const inputData: Uint8Array = new Uint8Array(await response.arrayBuffer()); +const document: PdfDocument = new PdfDocument(inputData, 'syncfusion'); +// Allow content copying and document assembly. +const options: PdfSecurityOptions = { + permissions: PdfPermissionFlag.copyContent | + PdfPermissionFlag.assembleDocument +}; +document.setSecurity(options); +// Save the PDF document with the updated permissions. +const data: Uint8Array = document.save('Output.pdf'); +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load the secured PDF document. +const response = await fetch('Input.pdf'); +const inputData = new Uint8Array(await response.arrayBuffer()); +const document = new PdfDocument(inputData, 'syncfusion'); +// Allow content copying and document assembly. +document.setSecurity({ + permissions: ej.pdf.PdfPermissionFlag.copyContent | + ej.pdf.PdfPermissionFlag.assembleDocument +}); +// Save the PDF document with the updated permissions. +document.save('Output.pdf'); +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## View document permission flags + +The `permissions` property of `PdfDocument` returns the permission flags available in the loaded PDF document. Since `PdfPermissionFlag` is a bitwise enumeration, use the bitwise AND operator to determine whether an individual permission is enabled. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { + PdfDocument, + PdfPermissionFlag +} from '@syncfusion/ej2-pdf'; + +// Load the secured PDF document. +const response: Response = await fetch('Input.pdf'); +const inputData: Uint8Array = new Uint8Array(await response.arrayBuffer()); +const document: PdfDocument = new PdfDocument(inputData, 'password'); +// Get the document permission flags. +const permissions: PdfPermissionFlag = document.permissions; +// Check the required permission flags. +const canPrint: boolean = + (permissions & PdfPermissionFlag.print) !== 0; +const canCopyContent: boolean = + (permissions & PdfPermissionFlag.copyContent) !== 0; +const canEditContent: boolean = + (permissions & PdfPermissionFlag.editContent) !== 0; +const canEditAnnotations: boolean = + (permissions & PdfPermissionFlag.editAnnotations) !== 0; +const canFillFields: boolean = + (permissions & PdfPermissionFlag.fillFields) !== 0; +const canCopyForAccessibility: boolean = + (permissions & PdfPermissionFlag.accessibilityCopyContent) !== 0; +const canAssembleDocument: boolean = + (permissions & PdfPermissionFlag.assembleDocument) !== 0; +const canPrintInFullQuality: boolean = + (permissions & PdfPermissionFlag.fullQualityPrint) !== 0; +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load the secured PDF document. +const response = await fetch('Input.pdf'); +const inputData = new Uint8Array(await response.arrayBuffer()); +const document = new ej.pdf.PdfDocument(inputData, 'password'); +// Get the document permission flags. +const permissions = document.permissions; +// Check the required permission flags. +const canPrint = (permissions & ej.pdf.PdfPermissionFlag.print) !== 0; +const canCopyContent = + (permissions & ej.pdf.PdfPermissionFlag.copyContent) !== 0; +const canEditContent = + (permissions & ej.pdf.PdfPermissionFlag.editContent) !== 0; +const canEditAnnotations = + (permissions & ej.pdf.PdfPermissionFlag.editAnnotations) !== 0; +const canFillFields = + (permissions & ej.pdf.PdfPermissionFlag.fillFields) !== 0; +const canCopyForAccessibility = + (permissions & ej.pdf.PdfPermissionFlag.accessibilityCopyContent) !== 0; +const canAssembleDocument = + (permissions & ej.pdf.PdfPermissionFlag.assembleDocument) !== 0; +const canPrintInFullQuality = + (permissions & ej.pdf.PdfPermissionFlag.fullQualityPrint) !== 0; +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +The following flags can be combined when configuring document permissions: + +- `PdfPermissionFlag.print` +- `PdfPermissionFlag.copyContent` +- `PdfPermissionFlag.editContent` +- `PdfPermissionFlag.editAnnotations` +- `PdfPermissionFlag.fillFields` +- `PdfPermissionFlag.accessibilityCopyContent` +- `PdfPermissionFlag.assembleDocument` +- `PdfPermissionFlag.fullQualityPrint` + +## Remove the password from a user-password-protected PDF document + +You can remove the user password from an encrypted PDF document by loading it with the current password, setting `userPassword` to an empty string, and saving the document. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { + PdfDocument, + PdfSecurityOptions +} from '@syncfusion/ej2-pdf'; + +// Load the password-protected PDF document. +const response: Response = await fetch('Input.pdf'); +const inputData: Uint8Array = new Uint8Array(await response.arrayBuffer()); +const document: PdfDocument = new PdfDocument(inputData, 'password'); +// Remove the user password. +const options: PdfSecurityOptions = { + userPassword: '' +}; +document.setSecurity(options); +// Save the PDF document without the user password. +document.save('Output.pdf'); +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load the password-protected PDF document. +const response = await fetch('Input.pdf'); +const inputData = new Uint8Array(await response.arrayBuffer()); +const document = new ej.pdf.PdfDocument(inputData, 'password'); +// Remove the user password. +document.setSecurity({ + userPassword: '' +}); +// Save the PDF document without the user password. +document.save('Output.pdf'); +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +N> If the document also has an owner password or permission restrictions, clear the owner password and update the permissions when complete decryption is required. + +## How to determine whether a PDF document is password protected + +To determine whether a PDF document requires a password, try loading it without a password and handle the error raised for an encrypted document. Avoid depending on an exact error-message string because the message can change between versions. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfDocument } from '@syncfusion/ej2-pdf'; + +// Load the PDF document data. +const response: Response = await fetch('Input.pdf'); +const inputData: Uint8Array = new Uint8Array(await response.arrayBuffer()); +let isPasswordProtected: boolean = false; +let document: PdfDocument | undefined; +try { + // Loading without a password fails when a valid password is required. + document = new PdfDocument(inputData); +} catch (error) { + isPasswordProtected = true; +} +if (document) { + document.destroy(); +} + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load the PDF document data. +const response = await fetch('Input.pdf'); +const inputData = new Uint8Array(await response.arrayBuffer()); +let isPasswordProtected = false; +let document; +try { + // Loading without a password fails when a valid password is required. + document = new ej.pdf.PdfDocument(inputData); +} catch (error) { + isPasswordProtected = true; +} +if (document) { + document.destroy(); +} + +{% endhighlight %} +{% endtabs %} + +N> A loading error can also occur for a damaged or unsupported PDF document. If an application needs to distinguish these cases, inspect the reported error and handle other load failures separately. + +## How to determine whether a PDF document is protected by a user or owner password + +The following table describes the values available after loading a secured PDF document with either its user password or owner password. No code sample is required for this behavior. + +| Document type | Opened with | User password value | Owner password value | +|----------|----------|----------|----------| +| PDF document secured with both owner and user passwords | User password | Returns the user password | Returns null | +| PDF document secured with both owner and user passwords | Owner password | Returns the user password. **Note:** Returns null for AES 256-bit and AES 256-bit Revision 6 encryption. | Returns the owner password | +| PDF document secured only with an owner password | Owner password | Returns null | Returns the owner password | +| PDF document secured only with a user password | User password | Returns the user password | Returns the owner password. The owner password is the same as the user password and grants full permission to the user. | + +## Additional Resources + +- [JavaScript PDF Library](https://www.syncfusion.com/document-sdk/javascript-pdf-library) +- [JavaScript PDF Library documentation](https://help.syncfusion.com/document-processing/pdf/pdf-library/javascript/overview) +- [JavaScript PDF Library API reference](https://ej2.syncfusion.com/documentation/api/pdf) +- [JavaScript PDF Library examples](https://document.syncfusion.com/demos/pdf/javascript/#/tailwind3/pdf/default) \ No newline at end of file diff --git a/Document-Processing/PDF/PDF-Library/javascript/Lists.md b/Document-Processing/PDF/PDF-Library/javascript/Lists.md index f8070171fa..73274e2ead 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/Lists.md +++ b/Document-Processing/PDF/PDF-Library/javascript/Lists.md @@ -147,6 +147,89 @@ document.destroy(); This example demonstrates how to change the marker style of an unordered list in a PDF document using the [PdfUnorderedList](https://ej2.syncfusion.com/documentation/api/pdf/pdfunorderedlist) class. The marker defines the symbol that appears before each list item. You can choose from the predefined marker styles listed below to visually distinguish different list types or emphasize specific content. +### Set image marker + +You can use an image as the marker for an unordered list by creating a `PdfImageMarker` with a `PdfBitmap` and passing it to the `setMarker` method of `PdfUnorderedList`. + +The following code example shows how to create a PDF document, add an unordered list, set an image as the list marker, and save the document. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { + PdfBitmap, + PdfDocument, + PdfImageMarker, + PdfListItemCollection, + PdfUnorderedList +} from '@syncfusion/ej2-pdf'; + +// Create a new PDF document. +const document: PdfDocument = new PdfDocument(); +// Add a new page to the document. +const page = document.addPage(); +// Create the items for the unordered list. +const items: PdfListItemCollection = new PdfListItemCollection([ + 'Essential PDF', + 'Essential DocIO', + 'Essential XlsIO' +]); +// Create an unordered list. +const unorderedList: PdfUnorderedList = new PdfUnorderedList(items); +// Create an image marker using the loaded image. +const imageMarker: PdfImageMarker = { + image: new PdfBitmap(imageData) +}; +// Set the image as the marker for the unordered list. +unorderedList.setMarker(imageMarker); +// Draw the unordered list on the PDF page. +unorderedList.draw(page, { + x: 10, + y: 20, + width: page.graphics.clientSize.width - 20, + height: page.graphics.clientSize.height - 40 +}); +// Save the PDF document. +document.save('SetImageMarker.pdf'); +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Create a new PDF document. +const document = new ej.pdf.PdfDocument(); +// Add a new page to the document. +const page = document.addPage(); +// Create the items for the unordered list. +const items = new ej.pdf.PdfListItemCollection([ + 'Essential PDF', + 'Essential DocIO', + 'Essential XlsIO' +]); +// Create an unordered list. +const unorderedList = new ej.pdf.PdfUnorderedList(items); +// Create an image marker using the loaded image. +const imageMarker = { + image: new ej.pdf.PdfBitmap(imageData) +}; +// Set the image as the marker for the unordered list. +unorderedList.setMarker(imageMarker); +// Draw the unordered list on the PDF page. +unorderedList.draw(page, { + x: 10, + y: 20, + width: page.graphics.clientSize.width - 20, + height: page.graphics.clientSize.height - 40 +}); +// Save the PDF document. +document.save('SetImageMarker.pdf'); +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} +{% endtabs %} + ### PdfUnorderedListStyle values | Value | Rendered marker | diff --git a/Document-Processing/PDF/PDF-Library/javascript/Text-Extraction.md b/Document-Processing/PDF/PDF-Library/javascript/Text-Extraction.md index 666aaf3ca5..33ce8f3cc8 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/Text-Extraction.md +++ b/Document-Processing/PDF/PDF-Library/javascript/Text-Extraction.md @@ -333,6 +333,102 @@ document.destroy(); {% endhighlight %} {% endtabs %} +## Find Text + +The [findText](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtext) method of the [PdfDataExtractor](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor) class locates specific text in a PDF document. The method returns the page index and rectangular bounds of each matching text occurrence. These details are useful for highlighting text, applying redaction, adding annotations, navigating between search results, and building custom search features. + +The following code example demonstrates how to search for text in a PDF document using the `findText` method. + +{% tabs %} + +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfDocument } from '@syncfusion/ej2-pdf'; +import { PdfDataExtractor } from '@syncfusion/ej2-pdf-data-extract'; + +// Load an existing PDF document +let document: PdfDocument = new PdfDocument(data); +// Initialize a new instance of the `PdfDataExtractor` class +let extractor: PdfDataExtractor = new PdfDataExtractor(document); +// Search for the specified text and retrieve the matching occurrences +let searchResults = await extractor.findText('document'); +// Release document resources +document.destroy(); + +{% endhighlight %} + +{% highlight javascript tabtitle="JavaScript" %} + +// Load an existing PDF document +var document = new ej.pdf.PdfDocument(data); +// Initialize a new instance of the PdfDataExtractor class +var extractor = new ej.pdfdataextract.PdfDataExtractor(document); +// Search for the specified text and retrieve the matching occurrences +var searchResults = await extractor.findText('document'); +// Release document resources +document.destroy(); + +{% endhighlight %} + +{% endtabs %} + +N> The page index returned in a text search result is zero-based. + +N> The `findText` method searches the text content available in the PDF document. It does not perform optical character recognition on scanned or image-only PDF pages. + +N> Searching a large PDF document may require additional processing time depending on the number of pages and matching text occurrences. + +### Find text synchronously + +The [findTextSync](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtextsync) method searches for text and returns the matching occurrences synchronously. + +The following code example demonstrates how to search for text synchronously in a PDF document. + +{% tabs %} + +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfDocument } from '@syncfusion/ej2-pdf'; +import { PdfDataExtractor } from '@syncfusion/ej2-pdf-data-extract'; + +// Load an existing PDF document +let document: PdfDocument = new PdfDocument(data); +// Initialize a new instance of the `PdfDataExtractor` class +let extractor: PdfDataExtractor = new PdfDataExtractor(document); +// Search for the specified text and retrieve the matching occurrences synchronously +let searchResults = extractor.findTextSync('document'); +// Release document resources +document.destroy(); + +{% endhighlight %} + +{% highlight javascript tabtitle="JavaScript" %} + +// Load an existing PDF document +var document = new ej.pdf.PdfDocument(data); +// Initialize a new instance of the PdfDataExtractor class +var extractor = new ej.pdfdataextract.PdfDataExtractor(document); +// Search for the specified text and retrieve the matching occurrences synchronously +var searchResults = extractor.findTextSync('document'); +// Release document resources +document.destroy(); + +{% endhighlight %} + +{% endtabs %} + +N> Use `findTextSync` when the search result is required immediately. For large PDF documents, use the asynchronous `findText` method to avoid blocking execution. + +## FindText Module API Reference + +Use the following table to select the text-search method that matches your requirement. + +| Method | Return Type | Description | +|---|---|---| +| [`findText(text: string)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtext) | Promise | Searches for the specified text asynchronously throughout the PDF document and returns all matching occurrences with their page indexes and bounds. | +| [`findText(text: string, options)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtext) | Promise | Searches for the specified text asynchronously using the supplied text-search options and returns the matching occurrences. | +| [`findTextSync(text: string)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtextsync) | Text search result collection | Searches for the specified text synchronously throughout the PDF document and returns all matching occurrences with their page indexes and bounds. | +| [`findTextSync(text: string, options)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtextsync) | Text search result collection | Searches for the specified text synchronously using the supplied text-search options and returns the matching occurrences. | ## Additional Resources - [JavaScript PDF Library](https://www.syncfusion.com/document-sdk/javascript-pdf-library) diff --git a/Document-Processing/PDF/PDF-Library/javascript/Text.md b/Document-Processing/PDF/PDF-Library/javascript/Text.md index 1d78778541..c63d138dbd 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/Text.md +++ b/Document-Processing/PDF/PDF-Library/javascript/Text.md @@ -583,6 +583,47 @@ document.destroy(); {% endhighlight %} {% endtabs %} +## Search and get the bounds of text in a PDF document + +You can search for specific text in a PDF document and retrieve the location of every occurrence using the [findText](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtext) method of the [PdfDataExtractor](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor) class. + +The `findText` method searches the PDF document for the specified text and returns the matching text occurrences along with their page index and bounding rectangles. The returned bounds can be used for operations such as highlighting, redaction, annotation, and document navigation. + +The following code example demonstrates how to search for text and retrieve the bounds of all matching occurrences in a PDF document. + +{% tabs %} + +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfDocument } from '@syncfusion/ej2-pdf'; +import { PdfDataExtractor } from '@syncfusion/ej2-pdf-data-extract'; + +// Load an existing PDF document +let document: PdfDocument = new PdfDocument(data); +// Initialize a new instance of the `PdfDataExtractor` class +let extractor: PdfDataExtractor = new PdfDataExtractor(document); +// Search for the specified text and retrieve all matching occurrences +let textSearch = extractor.findText('hello'); +// Release document resources +document.destroy(); + +{% endhighlight %} + +{% highlight javascript tabtitle="JavaScript" %} + +// Load an existing PDF document +var document = new ej.pdf.PdfDocument(data); +// Initialize a new instance of the PdfDataExtractor class +var extractor = new ej.pdfdataextract.PdfDataExtractor(document); +// Search for the specified text and retrieve all matching occurrences +var textSearch = extractor.findText('hello'); +// Release document resources +document.destroy(); + +{% endhighlight %} + +{% endtabs %} + ## Additional Resources - [JavaScript PDF Library](https://www.syncfusion.com/document-sdk/javascript-pdf-library) From b7d17f88b3294804fb57cc49ad684e53021f987a Mon Sep 17 00:00:00 2001 From: "AzureAD\\DhakshinPrasathDhanr" Date: Mon, 31 Aug 2026 16:02:17 +0530 Subject: [PATCH 02/11] 1050196: Referred file name in TOC --- Document-Processing-toc.html | 1 + 1 file changed, 1 insertion(+) diff --git a/Document-Processing-toc.html b/Document-Processing-toc.html index 37c293bfdf..fe7f9a1a87 100644 --- a/Document-Processing-toc.html +++ b/Document-Processing-toc.html @@ -3450,6 +3450,7 @@
  • Shapes
  • Annotations
  • Form Fields
  • +
  • Encryption
  • Digital Signature
  • Bookmarks
  • Hyperlinks
  • From 7221df00f4aa41aec6837b2196ea08c3469d0fa9 Mon Sep 17 00:00:00 2001 From: "AzureAD\\DhakshinPrasathDhanr" Date: Tue, 1 Sep 2026 15:42:49 +0530 Subject: [PATCH 03/11] 1050196: Addressed feedback corrections --- .../javascript/DigitalSignature.md | 121 ++------- .../PDF/PDF-Library/javascript/Encryption.md | 234 ++++++------------ 2 files changed, 92 insertions(+), 263 deletions(-) diff --git a/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md b/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md index a8ef8e197e..75512d0d4b 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md +++ b/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md @@ -820,38 +820,19 @@ The `validateSignatures` method returns the overall validation status and the in The following code example shows how to validate the digital signatures in an existing PDF document. {% tabs %} +{% highlight typescript tabtitle="TypeScript" %} -{% highlight javascript tabtitle="JavaScript" %} - -import { - PdfDocument -} from '@syncfusion/ej2-pdf'; - -// Fetch a file and return its content as a Uint8Array. -async function fetchAsUint8Array(url) { - const response = await fetch(url); - if (!response.ok) { - throw new Error(`Failed to load the file: ${response.statusText}`); - } - return new Uint8Array(await response.arrayBuffer()); -} +import { PdfDocument, PdfSignatureValidationOptions } from '@syncfusion/ej2-pdf'; // Load the signed PDF document. -const documentData = await fetchAsUint8Array('Input.pdf'); -const document = new PdfDocument(documentData); - -// Load the trusted certificate. -const certificateData = await fetchAsUint8Array('PDF.pfx'); - +const document: PdfDocument = new PdfDocument(documentData); // Configure the signature validation options. -const options = { +const options: PdfSignatureValidationOptions = { trustedCertificates: [certificateData], passwords: ['syncfusion'] }; - // Validate the digital signatures in the PDF document. const validationResult = document.form.validateSignatures(options); - // Check the validation result of each signature. if (validationResult.results !== null && validationResult.results !== undefined) { @@ -863,47 +844,23 @@ if (validationResult.results !== null && console.log('Revocation result: ', result.revocationResult); }); } - // Get the overall signature validation status. console.log('All signatures valid: ' + validationResult.isValid); - // Destroy the document and release its resources. document.destroy(); {% endhighlight %} - -{% highlight typescript tabtitle="TypeScript" %} - -import { - PdfDocument, - PdfSignatureValidationOptions -} from '@syncfusion/ej2-pdf'; - -// Fetch a file and return its content as a Uint8Array. -async function fetchAsUint8Array(url: string): Promise { - const response: Response = await fetch(url); - if (!response.ok) { - throw new Error(`Failed to load the file: ${response.statusText}`); - } - return new Uint8Array(await response.arrayBuffer()); -} +{% highlight javascript tabtitle="JavaScript" %} // Load the signed PDF document. -const documentData: Uint8Array = await fetchAsUint8Array('Input.pdf'); -const document: PdfDocument = new PdfDocument(documentData); - -// Load the trusted certificate. -const certificateData: Uint8Array = await fetchAsUint8Array('PDF.pfx'); - +const document = new ej.pdf.PdfDocument(documentData); // Configure the signature validation options. -const options: PdfSignatureValidationOptions = { +const options = { trustedCertificates: [certificateData], passwords: ['syncfusion'] }; - // Validate the digital signatures in the PDF document. const validationResult = document.form.validateSignatures(options); - // Check the validation result of each signature. if (validationResult.results !== null && validationResult.results !== undefined) { @@ -915,10 +872,8 @@ if (validationResult.results !== null && console.log('Revocation result: ', result.revocationResult); }); } - // Get the overall signature validation status. console.log('All signatures valid: ' + validationResult.isValid); - // Destroy the document and release its resources. document.destroy(); @@ -933,122 +888,74 @@ You can validate all digital signatures in a PDF document by calling the `valida The following code example shows how to validate all signatures and determine whether the complete PDF document has valid signatures. {% tabs %} +{% highlight typescript tabtitle="TypeScript" %} -{% highlight javascript tabtitle="JavaScript" %} - -import { - PdfDocument -} from '@syncfusion/ej2-pdf'; - -// Fetch a file and return its content as a Uint8Array. -async function fetchAsUint8Array(url) { - const response = await fetch(url); - if (!response.ok) { - throw new Error(`Failed to load the file: ${response.statusText}`); - } - return new Uint8Array(await response.arrayBuffer()); -} +import { PdfDocument, PdfSignatureValidationOptions } from '@syncfusion/ej2-pdf'; // Load the PDF document that contains multiple signatures. -const documentData = await fetchAsUint8Array('Input.pdf'); -const document = new PdfDocument(documentData); - -// Load the trusted certificate used for signature validation. -const certificateData = await fetchAsUint8Array('PDF.pfx'); - +const document: PdfDocument = new PdfDocument(documentData); // Configure the validation options. -const options = { +const options: PdfSignatureValidationOptions = { trustedCertificates: [certificateData], passwords: ['syncfusion'] }; - // Validate all signatures in the PDF document. const validationResult = document.form.validateSignatures(options); - if (validationResult.results !== null && validationResult.results !== undefined) { console.log( 'Number of validated signatures: ' + validationResult.results.length ); - validationResult.results.forEach((result) => { console.log( `${result.signatureName}: ${result.isSignatureValid}` ); }); } - // Determine whether all signatures are valid. if (validationResult.isValid) { console.log('All signatures in the PDF document are valid.'); } else { console.log('One or more signatures in the PDF document are invalid.'); } - // Destroy the document and release its resources. document.destroy(); {% endhighlight %} - -{% highlight typescript tabtitle="TypeScript" %} - -import { - PdfDocument, - PdfSignatureValidationOptions -} from '@syncfusion/ej2-pdf'; - -// Fetch a file and return its content as a Uint8Array. -async function fetchAsUint8Array(url: string): Promise { - const response: Response = await fetch(url); - if (!response.ok) { - throw new Error(`Failed to load the file: ${response.statusText}`); - } - return new Uint8Array(await response.arrayBuffer()); -} +{% highlight javascript tabtitle="JavaScript" %} // Load the PDF document that contains multiple signatures. -const documentData: Uint8Array = await fetchAsUint8Array('Input.pdf'); -const document: PdfDocument = new PdfDocument(documentData); - -// Load the trusted certificate used for signature validation. -const certificateData: Uint8Array = await fetchAsUint8Array('PDF.pfx'); - +const document = new PdfDocument(documentData); // Configure the validation options. -const options: PdfSignatureValidationOptions = { +const options = { trustedCertificates: [certificateData], passwords: ['syncfusion'] }; - // Validate all signatures in the PDF document. const validationResult = document.form.validateSignatures(options); - if (validationResult.results !== null && validationResult.results !== undefined) { console.log( 'Number of validated signatures: ' + validationResult.results.length ); - validationResult.results.forEach((result) => { console.log( `${result.signatureName}: ${result.isSignatureValid}` ); }); } - // Determine whether all signatures are valid. if (validationResult.isValid) { console.log('All signatures in the PDF document are valid.'); } else { console.log('One or more signatures in the PDF document are invalid.'); } - // Destroy the document and release its resources. document.destroy(); {% endhighlight %} - {% endtabs %} ## Inspecting signatures diff --git a/Document-Processing/PDF/PDF-Library/javascript/Encryption.md b/Document-Processing/PDF/PDF-Library/javascript/Encryption.md index bb12e1b207..337ba90949 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/Encryption.md +++ b/Document-Processing/PDF/PDF-Library/javascript/Encryption.md @@ -26,24 +26,18 @@ The following example encrypts a new PDF document using RC4 128-bit encryption a {% tabs %} {% highlight typescript tabtitle="TypeScript" %} -import { - PdfBrush, - PdfDocument, - PdfEncryptionType, - PdfFontFamily, - PdfFontStyle, - PdfSecurityOptions, - PdfStandardFont -} from '@syncfusion/ej2-pdf'; +import { PdfBrush, PdfDocument, PdfEncryptionType, PdfFontFamily, PdfFontStyle, PdfSecurityOptions, PdfStandardFont } from '@syncfusion/ej2-pdf'; // Create a new PDF document. const document: PdfDocument = new PdfDocument(); // Add a page to the document. const page = document.addPage(); +// Embed the standard font used to draw text. +const font: PdfStandardFont = document.embedFont(PdfFontFamily.helvetica, 12, PdfFontStyle.regular); // Draw text on the page. page.graphics.drawString( 'Encrypted with RC4 128-bit encryption', - new PdfStandardFont(PdfFontFamily.helvetica, 12, PdfFontStyle.regular), + font, { x: 10, y: 20, width: 300, height: 50 }, new PdfBrush({ r: 0, g: 0, b: 0 }) ); @@ -54,24 +48,25 @@ const options: PdfSecurityOptions = { }; document.setSecurity(options); // Save the encrypted PDF document. -const data: Uint8Array = document.save('Output.pdf'); +document.save('Output.pdf'); // Destroy the document and release its resources. document.destroy(); {% endhighlight %} - {% highlight javascript tabtitle="JavaScript" %} // Create a new PDF document. const document = new ej.pdf.PdfDocument(); // Add a page to the document. const page = document.addPage(); +// Embed the standard font used to draw text. +const font = document.embedFont(ej.pdf.PdfFontFamily.helvetica, 12, ej.pdf.PdfFontStyle.regular); // Draw text on the page. page.graphics.drawString( 'Encrypted with RC4 128-bit encryption', - new ej.pdf.PdfStandardFont(ej.pdf.PdfFontFamily.helvetica, 12, ej.pdf.PdfFontStyle.regular), + font, { x: 10, y: 20, width: 300, height: 50 }, - new PdfBrush({ r: 0, g: 0, b: 0 }) + new ej.pdf.PdfBrush({ r: 0, g: 0, b: 0 }) ); // Configure RC4 security using a user password. document.setSecurity({ @@ -79,16 +74,25 @@ document.setSecurity({ userPassword: 'password' }); // Save the encrypted PDF document. -const data = document.save('Output.pdf'); +document.save('Output.pdf'); // Destroy the document and release its resources. document.destroy(); {% endhighlight %} {% endtabs %} -You can restrict document operations by specifying an owner password and permission flags. The following security configuration permits printing and accessibility-based content copying. +You can restrict document operations by specifying an owner password and permission flags. The following example encrypts a new PDF document using RC4 128-bit encryption and permits only printing and accessibility-based content copying. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} -```typescript +import { PdfDocument, PdfEncryptionType, PdfPermissionFlag, PdfSecurityOptions } from '@syncfusion/ej2-pdf'; + +// Create a new PDF document. +const document: PdfDocument = new PdfDocument(); +// Add a page to the document. +document.addPage(); +// Restrict the document operations using an owner password and permission flags. const options: PdfSecurityOptions = { encryptionType: PdfEncryptionType.rc4Bit128, ownerPassword: 'ownerPassword', @@ -97,7 +101,33 @@ const options: PdfSecurityOptions = { PdfPermissionFlag.accessibilityCopyContent }; document.setSecurity(options); -``` +// Save the encrypted PDF document. +document.save('Output.pdf'); +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Create a new PDF document. +const document = new ej.pdf.PdfDocument(); +// Add a page to the document. +document.addPage(); +// Restrict the document operations using an owner password and permission flags. +document.setSecurity({ + encryptionType: ej.pdf.PdfEncryptionType.rc4Bit128, + ownerPassword: 'ownerPassword', + userPassword: 'userPassword', + permissions: ej.pdf.PdfPermissionFlag.print | + ej.pdf.PdfPermissionFlag.accessibilityCopyContent +}); +// Save the encrypted PDF document. +document.save('Output.pdf'); +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} +{% endtabs %} N> When both user and owner passwords are specified, use different values for the two passwords. @@ -110,11 +140,7 @@ The following example encrypts a new PDF document using AES 256-bit Revision 5 e {% tabs %} {% highlight typescript tabtitle="TypeScript" %} -import { - PdfDocument, - PdfEncryptionType, - PdfSecurityOptions -} from '@syncfusion/ej2-pdf'; +import { PdfDocument, PdfEncryptionType, PdfSecurityOptions } from '@syncfusion/ej2-pdf'; // Create a new PDF document. const document: PdfDocument = new PdfDocument(); @@ -134,11 +160,6 @@ document.destroy(); {% endhighlight %} {% highlight javascript tabtitle="JavaScript" %} -import { - PdfDocument, - PdfEncryptionType -} from '@syncfusion/ej2-pdf'; - // Create a new PDF document. const document = new ej.pdf.PdfDocument(); // Add a page to the document. @@ -158,22 +179,15 @@ document.destroy(); ## Decrypting an encrypted PDF document -The JavaScript PDF Library supports decrypting a secured PDF document by loading it with a valid password, clearing its passwords, and saving it again. Reset the permission flags when the document restrictions must also be removed. +The JavaScript PDF Library supports decrypting an encrypted PDF document by removing its owner or user password and restoring all supported permissions. This is particularly useful when you need to access or modify a secured PDF. {% tabs %} {% highlight typescript tabtitle="TypeScript" %} -import { - PdfDocument, - PdfPermissionFlag, - PdfSecurityOptions -} from '@syncfusion/ej2-pdf'; +import { PdfDocument, PdfPermissionFlag, PdfSecurityOptions } from '@syncfusion/ej2-pdf'; -// Load the encrypted PDF document data. -const response: Response = await fetch('Input.pdf'); -const inputData: Uint8Array = new Uint8Array(await response.arrayBuffer()); // Open the document using a valid password. -const document: PdfDocument = new PdfDocument(inputData, 'syncfusion'); +const document: PdfDocument = new PdfDocument(inputData, 'password'); // Clear the passwords and restore all supported permissions. const options: PdfSecurityOptions = { userPassword: '', @@ -197,10 +211,7 @@ document.destroy(); {% highlight javascript tabtitle="JavaScript" %} // Load the encrypted PDF document data. -const response = await fetch('Input.pdf'); -const inputData = new Uint8Array(await response.arrayBuffer()); -// Open the document using a valid password. -const document = new ej.pdf.PdfDocument(inputData, 'syncfusion'); +const document = new ej.pdf.PdfDocument(inputData, 'password'); // Clear the passwords and restore all supported permissions. document.setSecurity({ userPassword: '', @@ -224,20 +235,14 @@ document.destroy(); ## Protect an existing PDF document -You can protect an existing PDF document by loading its data, configuring the required encryption type and passwords, and saving the document. +You can make the existing PDF document password protected by configuring the required encryption type and passwords, and saving the document. {% tabs %} {% highlight typescript tabtitle="TypeScript" %} -import { - PdfDocument, - PdfEncryptionType, - PdfSecurityOptions -} from '@syncfusion/ej2-pdf'; +import { PdfDocument, PdfEncryptionType, PdfSecurityOptions } from '@syncfusion/ej2-pdf'; -// Load an existing PDF document. -const response: Response = await fetch('Input.pdf'); -const inputData: Uint8Array = new Uint8Array(await response.arrayBuffer()); +// Load the existing PDF document const document: PdfDocument = new PdfDocument(inputData); // Protect the document using AES encryption. const options: PdfSecurityOptions = { @@ -255,8 +260,6 @@ document.destroy(); {% highlight javascript tabtitle="JavaScript" %} // Load an existing PDF document. -const response = await fetch('Input.pdf'); -const inputData = new Uint8Array(await response.arrayBuffer()); const document = new ej.pdf.PdfDocument(inputData); // Protect the document using AES encryption. document.setSecurity({ @@ -279,14 +282,9 @@ You can change the user password of an existing encrypted PDF document by loadin {% tabs %} {% highlight typescript tabtitle="TypeScript" %} -import { - PdfDocument, - PdfSecurityOptions -} from '@syncfusion/ej2-pdf'; +import { PdfDocument, PdfSecurityOptions } from '@syncfusion/ej2-pdf'; // Load the password-protected PDF document. -const response: Response = await fetch('Input.pdf'); -const inputData: Uint8Array = new Uint8Array(await response.arrayBuffer()); const document: PdfDocument = new PdfDocument(inputData, 'password'); // Change the user password. const options: PdfSecurityOptions = { @@ -302,8 +300,6 @@ document.destroy(); {% highlight javascript tabtitle="JavaScript" %} // Load the password-protected PDF document. -const response = await fetch('Input.pdf'); -const inputData = new Uint8Array(await response.arrayBuffer()); const document = new ej.pdf.PdfDocument(inputData, 'password'); // Change the user password. document.setSecurity({ @@ -317,54 +313,6 @@ document.destroy(); {% endhighlight %} {% endtabs %} -## Change the permissions of a PDF document - -You can change the permissions of an existing secured PDF document using the `permissions` property of `PdfSecurityOptions`. Load the document using a valid password before updating the permission flags. - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { - PdfDocument, - PdfPermissionFlag, - PdfSecurityOptions -} from '@syncfusion/ej2-pdf'; - -// Load the secured PDF document. -const response: Response = await fetch('Input.pdf'); -const inputData: Uint8Array = new Uint8Array(await response.arrayBuffer()); -const document: PdfDocument = new PdfDocument(inputData, 'syncfusion'); -// Allow content copying and document assembly. -const options: PdfSecurityOptions = { - permissions: PdfPermissionFlag.copyContent | - PdfPermissionFlag.assembleDocument -}; -document.setSecurity(options); -// Save the PDF document with the updated permissions. -const data: Uint8Array = document.save('Output.pdf'); -// Destroy the document and release its resources. -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -// Load the secured PDF document. -const response = await fetch('Input.pdf'); -const inputData = new Uint8Array(await response.arrayBuffer()); -const document = new PdfDocument(inputData, 'syncfusion'); -// Allow content copying and document assembly. -document.setSecurity({ - permissions: ej.pdf.PdfPermissionFlag.copyContent | - ej.pdf.PdfPermissionFlag.assembleDocument -}); -// Save the PDF document with the updated permissions. -document.save('Output.pdf'); -// Destroy the document and release its resources. -document.destroy(); - -{% endhighlight %} -{% endtabs %} - ## View document permission flags The `permissions` property of `PdfDocument` returns the permission flags available in the loaded PDF document. Since `PdfPermissionFlag` is a bitwise enumeration, use the bitwise AND operator to determine whether an individual permission is enabled. @@ -372,14 +320,9 @@ The `permissions` property of `PdfDocument` returns the permission flags availab {% tabs %} {% highlight typescript tabtitle="TypeScript" %} -import { - PdfDocument, - PdfPermissionFlag -} from '@syncfusion/ej2-pdf'; +import { PdfDocument, PdfPermissionFlag } from '@syncfusion/ej2-pdf'; // Load the secured PDF document. -const response: Response = await fetch('Input.pdf'); -const inputData: Uint8Array = new Uint8Array(await response.arrayBuffer()); const document: PdfDocument = new PdfDocument(inputData, 'password'); // Get the document permission flags. const permissions: PdfPermissionFlag = document.permissions; @@ -407,8 +350,6 @@ document.destroy(); {% highlight javascript tabtitle="JavaScript" %} // Load the secured PDF document. -const response = await fetch('Input.pdf'); -const inputData = new Uint8Array(await response.arrayBuffer()); const document = new ej.pdf.PdfDocument(inputData, 'password'); // Get the document permission flags. const permissions = document.permissions; @@ -445,28 +386,24 @@ The following flags can be combined when configuring document permissions: - `PdfPermissionFlag.assembleDocument` - `PdfPermissionFlag.fullQualityPrint` -## Remove the password from a user-password-protected PDF document +## Change the permissions of a PDF document -You can remove the user password from an encrypted PDF document by loading it with the current password, setting `userPassword` to an empty string, and saving the document. +You can change the permissions of an existing secured PDF document using the `permissions` property of `PdfSecurityOptions`. Load the document using a valid password before updating the permission flags. {% tabs %} {% highlight typescript tabtitle="TypeScript" %} -import { - PdfDocument, - PdfSecurityOptions -} from '@syncfusion/ej2-pdf'; +import { PdfDocument, PdfPermissionFlag, PdfSecurityOptions } from '@syncfusion/ej2-pdf'; -// Load the password-protected PDF document. -const response: Response = await fetch('Input.pdf'); -const inputData: Uint8Array = new Uint8Array(await response.arrayBuffer()); -const document: PdfDocument = new PdfDocument(inputData, 'password'); -// Remove the user password. +// Load the secured PDF document. +const document: PdfDocument = new PdfDocument(inputData, 'syncfusion'); +// Allow content copying and document assembly. const options: PdfSecurityOptions = { - userPassword: '' + permissions: PdfPermissionFlag.copyContent | + PdfPermissionFlag.assembleDocument }; document.setSecurity(options); -// Save the PDF document without the user password. +// Save the PDF document with the updated permissions. document.save('Output.pdf'); // Destroy the document and release its resources. document.destroy(); @@ -474,15 +411,14 @@ document.destroy(); {% endhighlight %} {% highlight javascript tabtitle="JavaScript" %} -// Load the password-protected PDF document. -const response = await fetch('Input.pdf'); -const inputData = new Uint8Array(await response.arrayBuffer()); -const document = new ej.pdf.PdfDocument(inputData, 'password'); -// Remove the user password. +// Load the secured PDF document. +const document = new ej.pdf.PdfDocument(inputData, 'syncfusion'); +// Allow content copying and document assembly. document.setSecurity({ - userPassword: '' + permissions: ej.pdf.PdfPermissionFlag.copyContent | + ej.pdf.PdfPermissionFlag.assembleDocument }); -// Save the PDF document without the user password. +// Save the PDF document with the updated permissions. document.save('Output.pdf'); // Destroy the document and release its resources. document.destroy(); @@ -490,8 +426,6 @@ document.destroy(); {% endhighlight %} {% endtabs %} -N> If the document also has an owner password or permission restrictions, clear the owner password and update the permissions when complete decryption is required. - ## How to determine whether a PDF document is password protected To determine whether a PDF document requires a password, try loading it without a password and handle the error raised for an encrypted document. Avoid depending on an exact error-message string because the message can change between versions. @@ -501,38 +435,26 @@ To determine whether a PDF document requires a password, try loading it without import { PdfDocument } from '@syncfusion/ej2-pdf'; -// Load the PDF document data. -const response: Response = await fetch('Input.pdf'); -const inputData: Uint8Array = new Uint8Array(await response.arrayBuffer()); +// Load the PDF document data let isPasswordProtected: boolean = false; -let document: PdfDocument | undefined; try { // Loading without a password fails when a valid password is required. - document = new PdfDocument(inputData); -} catch (error) { + let document = new PdfDocument(inputData); +} catch (error.message == 'Cannot open an encrypted document. The password is invalid.') { isPasswordProtected = true; } -if (document) { - document.destroy(); -} {% endhighlight %} {% highlight javascript tabtitle="JavaScript" %} // Load the PDF document data. -const response = await fetch('Input.pdf'); -const inputData = new Uint8Array(await response.arrayBuffer()); let isPasswordProtected = false; -let document; try { // Loading without a password fails when a valid password is required. - document = new ej.pdf.PdfDocument(inputData); -} catch (error) { + let document = new ej.pdf.PdfDocument(inputData); +} catch (error.message == 'Cannot open an encrypted document. The password is invalid.') { isPasswordProtected = true; } -if (document) { - document.destroy(); -} {% endhighlight %} {% endtabs %} From 92339dede1c8ec0adaaf61207871d4c6fe9dc544 Mon Sep 17 00:00:00 2001 From: "AzureAD\\DhakshinPrasathDhanr" Date: Tue, 1 Sep 2026 18:29:26 +0530 Subject: [PATCH 04/11] 1050196: Added UG files --- .../javascript/DigitalSignature.md | 420 +++++--- .../PDF/PDF-Library/javascript/PdfGrid.md | 928 ++++++++++++++++++ .../PDF-Library/javascript/Text-Extraction.md | 140 ++- 3 files changed, 1314 insertions(+), 174 deletions(-) create mode 100644 Document-Processing/PDF/PDF-Library/javascript/PdfGrid.md diff --git a/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md b/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md index 75512d0d4b..1fb277debd 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md +++ b/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md @@ -181,7 +181,7 @@ let externalSignatureCallback = ( return { signedData: new Uint8Array() }; // Placeholder return }; // Create a new signature using external signing -let signature: PdfSignature = PdfSignature.create(externalSignatureCallback, { +let signature: PdfSignature = signatureField.create (externalSignatureCallback, { cryptographicStandard: CryptographicStandard.cms, algorithm: DigestAlgorithm.sha256, }); @@ -422,6 +422,269 @@ var signedDocumentData = ej.pdf.PdfSignature.replaceEmptySignature( N> The two-step process is required when the signing operation cannot complete inside the `PdfSignature.create(...)` callback — for example, when the private key lives on a remote HSM with high latency. First, reserve the signature field with an empty signature dictionary; then, after the remote signer returns the signed bytes, call `replaceEmptySignature(...)` to embed them in the previously reserved field. +## Long-Term Validation (LTV) + +The JavaScript PDF Library supports Long-Term Validation for digital signatures through the [`enableLTV()`](https://ej2.syncfusion.com/documentation/api/pdf/pdfsignature#enableltv) method of the `PdfSignature` class. LTV helps preserve signature validity by embedding revocation information such as OCSP and CRL responses into the document. + +### Create Long Term Validation (LTV) when signing PDF documents externally + +You can create Long Term Validation (LTV) after externally signing a PDF document by using your public certificate chain. The following code example shows how to complete the external signing process and enable LTV using the [`enableLTV()`](https://ej2.syncfusion.com/documentation/api/pdf/pdfsignature#enableltv) method of the [`PdfSignature`](https://ej2.syncfusion.com/documentation/api/pdf/pdfsignature) class. + +The callback supplied to `enableLTV()` must retrieve the actual OCSP or CRL response requested by the library and return the response bytes as a `Uint8Array`. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} +import { + PdfDocument, + PdfForm, + PdfSignatureField, + PdfSignature, + DigestAlgorithm, + RevocationType +} from '@syncfusion/ej2-pdf'; + +// Load the externally signed PDF document +let document: PdfDocument = new PdfDocument(data); +// Access the PDF form +let form: PdfForm = document.form; +// Get the externally signed signature field +let field: PdfSignatureField = form.fieldAt(0) as PdfSignatureField; +// Get the existing signature +let signature: PdfSignature = field.getSignature(); +// Public certificate chain used for long-term validation +let publicCertificates: Uint8Array[] = [/* your certificates here */]; + +// Retrieve the OCSP or CRL response requested by the library +async function longTermValidationCallback( + url: string, + requestBytes?: Uint8Array +): Promise<{ response: Uint8Array }> { + // Send requestBytes to the supplied URL and return the actual response bytes + return { response: new Uint8Array() }; +} + +// Enable LTV and include the public certificates in the PDF document +let ltvEnabled: boolean = await signature.enableLTV( + publicCertificates, + RevocationType.crl, + true, + longTermValidationCallback +); +if (ltvEnabled) { + // Save the LTV-enabled PDF document + document.save('output.pdf'); +} +// Destroy the document +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load the externally signed PDF document +var document = new ej.pdf.PdfDocument(data); +// Access the PDF form +var form = document.form; +// Get the externally signed signature field +var field = form.fieldAt(0); +// Get the existing signature +var signature = field.getSignature(); +// Public certificate chain used for long-term validation +var publicCertificates = [/* your certificates here */]; + +// Retrieve the OCSP or CRL response requested by the library +var longTermValidationCallback = async function (url, requestBytes) { + // Send requestBytes to the supplied URL and return the actual response bytes + return { response: new Uint8Array() }; +}; + +// Enable LTV and include the public certificates in the PDF document +var ltvEnabled = await signature.enableLTV( + publicCertificates, + ej.pdf.RevocationType.crl, + true, + longTermValidationCallback +); +if (ltvEnabled) { + // Save the LTV-enabled PDF document + document.save('output.pdf'); +} +// Destroy the document +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +N> An empty `Uint8Array` is only a placeholder. The callback must return the actual OCSP or CRL response received from the supplied revocation service URL. + +### Enable Long Term Validation (LTV) PDF signature + +The JavaScript PDF Library supports creating long-term signature validation for a signed PDF document. LTV allows a signature to be validated long after the document was signed by embedding the required certificate and revocation information in the PDF document. + +N> The resulting PDF document can be larger because the certificate chain, Certificate Revocation List (CRL), Online Certificate Status Protocol (OCSP) responses, and related validation information can be embedded in the Document Security Store (DSS). + +The following code example explains how to enable LTV for an existing signature using the [`enableLTV()`](https://ej2.syncfusion.com/documentation/api/pdf/pdfsignature#enableltv) method of the [`PdfSignature`](https://ej2.syncfusion.com/documentation/api/pdf/pdfsignature) class. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} +import { + PdfDocument, + PdfForm, + PdfSignatureField, + PdfSignature +} from '@syncfusion/ej2-pdf'; + +// Load the existing signed PDF document +let document: PdfDocument = new PdfDocument(data); +// Access the PDF form +let form: PdfForm = document.form; +// Get the existing signature field +let field: PdfSignatureField = form.fieldAt(0) as PdfSignatureField; +// Get the existing signature +let signature: PdfSignature = field.getSignature(); + +// Retrieve the OCSP or CRL response requested by the library +async function longTermValidationCallback( + url: string, + requestBytes?: Uint8Array +): Promise<{ response: Uint8Array }> { + // Send requestBytes to the supplied URL and return the actual response bytes + return { response: new Uint8Array() }; +} + +// Enable LTV for the existing signature +let ltvEnabled: boolean = await signature.enableLTV(longTermValidationCallback); +if (ltvEnabled) { + // Save the LTV-enabled PDF document + document.save('output.pdf'); +} +// Destroy the document +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load the existing signed PDF document +var document = new ej.pdf.PdfDocument(data); +// Access the PDF form +var form = document.form; +// Get the existing signature field +var field = form.fieldAt(0); +// Get the existing signature +var signature = field.getSignature(); + +// Retrieve the OCSP or CRL response requested by the library +var longTermValidationCallback = async function (url, requestBytes) { + // Send requestBytes to the supplied URL and return the actual response bytes + return { response: new Uint8Array() }; +}; + +// Enable LTV for the existing signature +var ltvEnabled = await signature.enableLTV(longTermValidationCallback); +if (ltvEnabled) { + // Save the LTV-enabled PDF document + document.save('output.pdf'); +} +// Destroy the document +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +N> Enable LTV only after the target signature has been created or loaded from the PDF document. + +N> When a PDF document contains multiple signatures, call `enableLTV()` for each signature that requires long-term validation. + +### Enable Long Term Validation (LTV) with public certificates + +You can provide the public certificate chain, select the revocation mode, and specify whether the certificates must be included in the PDF document while enabling LTV. + +The following code example uses CRL-based revocation information and includes the supplied public certificates in the document. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} +import { + PdfDocument, + PdfForm, + PdfSignatureField, + PdfSignature, + RevocationType +} from '@syncfusion/ej2-pdf'; + +// Load the signed PDF document +let document: PdfDocument = new PdfDocument(data); +// Access the PDF form +let form: PdfForm = document.form; +// Get the signature field +let field: PdfSignatureField = form.fieldAt(0) as PdfSignatureField; +// Get the signature +let signature: PdfSignature = field.getSignature(); +// Public certificate chain used for validation +let publicCertificates: Uint8Array[] = [/* your certificates here */]; + +// Retrieve the revocation response requested by the library +async function longTermValidationCallback( + url: string, + requestBytes?: Uint8Array +): Promise<{ response: Uint8Array }> { + // Send requestBytes to the supplied URL and return the actual response bytes + return { response: new Uint8Array() }; +} + +// Enable LTV using CRL responses and include the public certificates +let ltvEnabled: boolean = await signature.enableLTV( + publicCertificates, + RevocationType.crl, + true, + longTermValidationCallback +); +if (ltvEnabled) { + // Save the LTV-enabled PDF document + document.save('output.pdf'); +} +// Destroy the document +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load the signed PDF document +var document = new ej.pdf.PdfDocument(data); +// Access the PDF form +var form = document.form; +// Get the signature field +var field = form.fieldAt(0); +// Get the signature +var signature = field.getSignature(); +// Public certificate chain used for validation +var publicCertificates = [/* your certificates here */]; + +// Retrieve the revocation response requested by the library +var longTermValidationCallback = async function (url, requestBytes) { + // Send requestBytes to the supplied URL and return the actual response bytes + return { response: new Uint8Array() }; +}; + +// Enable LTV using CRL responses and include the public certificates +var ltvEnabled = await signature.enableLTV( + publicCertificates, + ej.pdf.RevocationType.crl, + true, + longTermValidationCallback +); +if (ltvEnabled) { + // Save the LTV-enabled PDF document + document.save('output.pdf'); +} +// Destroy the document +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +N> Network communication, authentication, request headers, proxy configuration, and cross-origin access must be handled by the application that implements the callback. + +N> Invalid, empty, or unrelated response bytes may prevent the library from creating valid LTV information. + ## Signature options The following examples demonstrate the signature-creation options available in `PdfSignatureOptions`. @@ -803,161 +1066,6 @@ document.destroy(); {% endhighlight %} {% endtabs %} -## Digital signature validation - -The JavaScript PDF Library supports validating digital signatures in an existing PDF document. Digital signature validation verifies the following information to determine the validity of each signature: - -* Document modifications made after signing. -* The certificate chain against the provided trusted certificates. -* Timestamp information associated with the signature. -* Certificate revocation status using Online Certificate Status Protocol (OCSP) and Certificate Revocation List (CRL) information. -* Multiple digital signatures available in the PDF document. - -Use the `validateSignatures` method of `PdfForm` to validate the digital signatures in a PDF document. Configure the trusted certificates and their passwords using `PdfSignatureValidationOptions`. - -The `validateSignatures` method returns the overall validation status and the individual validation results. The `isValid` property indicates whether all the validated signatures are valid. The `results` property contains details such as the signature name, signature status, document modification status, and revocation result for each signature. - -The following code example shows how to validate the digital signatures in an existing PDF document. - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfDocument, PdfSignatureValidationOptions } from '@syncfusion/ej2-pdf'; - -// Load the signed PDF document. -const document: PdfDocument = new PdfDocument(documentData); -// Configure the signature validation options. -const options: PdfSignatureValidationOptions = { - trustedCertificates: [certificateData], - passwords: ['syncfusion'] -}; -// Validate the digital signatures in the PDF document. -const validationResult = document.form.validateSignatures(options); -// Check the validation result of each signature. -if (validationResult.results !== null && - validationResult.results !== undefined) { - validationResult.results.forEach((result) => { - console.log('Signature name: ' + result.signatureName); - console.log('Signature valid: ' + result.isSignatureValid); - console.log('Signature status: ' + result.signatureStatus); - console.log('Document modified: ' + result.isDocumentModified); - console.log('Revocation result: ', result.revocationResult); - }); -} -// Get the overall signature validation status. -console.log('All signatures valid: ' + validationResult.isValid); -// Destroy the document and release its resources. -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -// Load the signed PDF document. -const document = new ej.pdf.PdfDocument(documentData); -// Configure the signature validation options. -const options = { - trustedCertificates: [certificateData], - passwords: ['syncfusion'] -}; -// Validate the digital signatures in the PDF document. -const validationResult = document.form.validateSignatures(options); -// Check the validation result of each signature. -if (validationResult.results !== null && - validationResult.results !== undefined) { - validationResult.results.forEach((result) => { - console.log('Signature name: ' + result.signatureName); - console.log('Signature valid: ' + result.isSignatureValid); - console.log('Signature status: ' + result.signatureStatus); - console.log('Document modified: ' + result.isDocumentModified); - console.log('Revocation result: ', result.revocationResult); - }); -} -// Get the overall signature validation status. -console.log('All signatures valid: ' + validationResult.isValid); -// Destroy the document and release its resources. -document.destroy(); - -{% endhighlight %} - -{% endtabs %} - -## Validate all signatures in a PDF document - -You can validate all digital signatures in a PDF document by calling the `validateSignatures` method. The method validates every signature field in the document and returns the individual results through the `results` collection. - -The following code example shows how to validate all signatures and determine whether the complete PDF document has valid signatures. - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfDocument, PdfSignatureValidationOptions } from '@syncfusion/ej2-pdf'; - -// Load the PDF document that contains multiple signatures. -const document: PdfDocument = new PdfDocument(documentData); -// Configure the validation options. -const options: PdfSignatureValidationOptions = { - trustedCertificates: [certificateData], - passwords: ['syncfusion'] -}; -// Validate all signatures in the PDF document. -const validationResult = document.form.validateSignatures(options); -if (validationResult.results !== null && - validationResult.results !== undefined) { - console.log( - 'Number of validated signatures: ' + - validationResult.results.length - ); - validationResult.results.forEach((result) => { - console.log( - `${result.signatureName}: ${result.isSignatureValid}` - ); - }); -} -// Determine whether all signatures are valid. -if (validationResult.isValid) { - console.log('All signatures in the PDF document are valid.'); -} else { - console.log('One or more signatures in the PDF document are invalid.'); -} -// Destroy the document and release its resources. -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -// Load the PDF document that contains multiple signatures. -const document = new PdfDocument(documentData); -// Configure the validation options. -const options = { - trustedCertificates: [certificateData], - passwords: ['syncfusion'] -}; -// Validate all signatures in the PDF document. -const validationResult = document.form.validateSignatures(options); -if (validationResult.results !== null && - validationResult.results !== undefined) { - console.log( - 'Number of validated signatures: ' + - validationResult.results.length - ); - validationResult.results.forEach((result) => { - console.log( - `${result.signatureName}: ${result.isSignatureValid}` - ); - }); -} -// Determine whether all signatures are valid. -if (validationResult.isValid) { - console.log('All signatures in the PDF document are valid.'); -} else { - console.log('One or more signatures in the PDF document are invalid.'); -} -// Destroy the document and release its resources. -document.destroy(); - -{% endhighlight %} -{% endtabs %} - ## Inspecting signatures The following examples demonstrate how to read information from existing signatures in a PDF document. diff --git a/Document-Processing/PDF/PDF-Library/javascript/PdfGrid.md b/Document-Processing/PDF/PDF-Library/javascript/PdfGrid.md new file mode 100644 index 0000000000..1a9941b0e7 --- /dev/null +++ b/Document-Processing/PDF/PDF-Library/javascript/PdfGrid.md @@ -0,0 +1,928 @@ +--- +title: PdfGrid Tables in JavaScript PDF | Syncfusion +canonical_url: https://www.syncfusion.com/document-sdk/javascript-pdf-library +description: Create and customize PDF tables programmatically using PdfGrid in the Syncfusion JavaScript PDF Library. +platform: document-processing +control: PDF +documentation: UG +--- + +# PdfGrid Tables in JavaScript PDF + +The Syncfusion JavaScript PDF Library supports creating PDF tables from arrays of records or explicitly defined rows and columns. The `PdfGrid` class supports headers, custom column widths, row and column spanning, styles, images, hyperlinks, built-in styles, and pagination. + +N> The TypeScript samples use the `@syncfusion/ej2-pdf` package. The JavaScript samples use the corresponding `ej.pdf` global namespace. + +## Create a table from a data source + +Create a `PdfGrid` from an array of records and an ordered collection of `PdfColumnInformation` mappings. + + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfColumnInformation, PdfDocument, PdfGrid, PdfGridLayoutResult, PdfPage } from '@syncfusion/ej2-pdf'; + +// Create a new PDF document +let document: PdfDocument = new PdfDocument(); +// Add a page +let page: PdfPage = document.addPage(); +// Create the data source +let dataSource: object[] = [ + { id: 'E01', name: 'Clay' }, + { id: 'E02', name: 'Thomas' } +]; +// Define the column mappings +let columns: PdfColumnInformation[] = [ + { field: 'id', headerText: 'Employee ID', width: 90 }, + { field: 'name', headerText: 'Employee Name', width: 140 } +]; +// Create and draw the grid +let grid: PdfGrid = new PdfGrid(dataSource, columns); +let result: PdfGridLayoutResult = grid.draw(page, { x: 10, y: 10 }); +// Save and close the document +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Create a new PDF document +var document = new ej.pdf.PdfDocument(); +// Add a page +var page = document.addPage(); +// Create the data source +var dataSource = [ + { id: 'E01', name: 'Clay' }, + { id: 'E02', name: 'Thomas' } +]; +// Define the column mappings +var columns = [ + { field: 'id', headerText: 'Employee ID', width: 90 }, + { field: 'name', headerText: 'Employee Name', width: 140 } +]; +// Create and draw the grid +var grid = new ej.pdf.PdfGrid(dataSource, columns); +var result = grid.draw(page, { x: 10, y: 10 }); +// Save and close the document +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Create a table without a data source + +Define the rows, optional headers, and a zero-based column-width map directly. + + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfDocument, PdfGrid, PdfGridRow, PdfPage } from '@syncfusion/ej2-pdf'; + +let document: PdfDocument = new PdfDocument(); +let page: PdfPage = document.addPage(); +let widths: Map = new Map([[0, 90], [1, 140], [2, 100]]); +let headers: PdfGridRow[] = [{ + cells: [{ value: 'Employee ID' }, { value: 'Employee Name' }, { value: 'Salary' }] +}]; +let rows: PdfGridRow[] = [{ + cells: [{ value: 'E01' }, { value: 'Clay' }, { value: '$10,000' }] +}]; +let grid: PdfGrid = new PdfGrid(3, widths, rows, headers); +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +var document = new ej.pdf.PdfDocument(); +var page = document.addPage(); +var widths = new Map([[0, 90], [1, 140], [2, 100]]); +var headers = [{ + cells: [{ value: 'Employee ID' }, { value: 'Employee Name' }, { value: 'Salary' }] +}]; +var rows = [{ + cells: [{ value: 'E01' }, { value: 'Clay' }, { value: '$10,000' }] +}]; +var grid = new ej.pdf.PdfGrid(3, widths, rows, headers); +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Add rows and headers + +Use `addHeader` and `addRow` to append rows after constructing an explicit grid. + + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfDocument, PdfGrid, PdfPage } from '@syncfusion/ej2-pdf'; + +let document: PdfDocument = new PdfDocument(); +let page: PdfPage = document.addPage(); +let widths: Map = new Map([[0, 90], [1, 140]]); +let grid: PdfGrid = new PdfGrid(2, widths, []); +grid.addHeader({ cells: [{ value: 'ID' }, { value: 'Name' }] }); +grid.addRow({ cells: [{ value: 'E01' }, { value: 'Clay' }] }); +grid.addRow({ cells: [{ value: 'E02' }, { value: 'Thomas' }] }); +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +var document = new ej.pdf.PdfDocument(); +var page = document.addPage(); +var widths = new Map([[0, 90], [1, 140]]); +var grid = new ej.pdf.PdfGrid(2, widths, []); +grid.addHeader({ cells: [{ value: 'ID' }, { value: 'Name' }] }); +grid.addRow({ cells: [{ value: 'E01' }, { value: 'Clay' }] }); +grid.addRow({ cells: [{ value: 'E02' }, { value: 'Thomas' }] }); +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Create a table in an existing PDF document + +Load an existing document, access a page, and draw the grid on that page. + + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfColumnInformation, PdfDocument, PdfGrid, PdfPage } from '@syncfusion/ej2-pdf'; + +// Load an existing PDF document +let document: PdfDocument = new PdfDocument(data); +let page: PdfPage = document.getPage(0); +let source: object[] = [{ id: '1', name: 'Clay' }, { id: '2', name: 'Thomas' }]; +let columns: PdfColumnInformation[] = [ + { field: 'id', headerText: 'ID', width: 60 }, + { field: 'name', headerText: 'Name', width: 120 } +]; +let grid: PdfGrid = new PdfGrid(source, columns); +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load an existing PDF document +var document = new ej.pdf.PdfDocument(data); +var page = document.getPage(0); +var source = [{ id: '1', name: 'Clay' }, { id: '2', name: 'Thomas' }]; +var columns = [ + { field: 'id', headerText: 'ID', width: 60 }, + { field: 'name', headerText: 'Name', width: 120 } +]; +var grid = new ej.pdf.PdfGrid(source, columns); +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Customize table cells + +Apply a background, border, padding, and text color to an individual cell. + + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfBrush, PdfDocument, PdfGrid, PdfGridRow, PdfPage, PdfPen } from '@syncfusion/ej2-pdf'; + +let document: PdfDocument = new PdfDocument(); +let page: PdfPage = document.addPage(); +let widths: Map = new Map([[0, 100], [1, 140]]); +let rows: PdfGridRow[] = [{ + height: 40, + cells: [ + { + value: 'E01', + style: { + background: new PdfBrush({ r: 255, g: 255, b: 180 }), + border: new PdfPen({ r: 255, g: 0, b: 0 }, 1), + padding: { left: 8, right: 8, top: 6, bottom: 6 }, + textProperties: { color: new PdfBrush({ r: 0, g: 0, b: 180 }) } + } + }, + { value: 'Clay' } + ] +}]; +let grid: PdfGrid = new PdfGrid(2, widths, rows); +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +var document = new ej.pdf.PdfDocument(); +var page = document.addPage(); +var widths = new Map([[0, 100], [1, 140]]); +var rows = [{ + height: 40, + cells: [ + { + value: 'E01', + style: { + background: new ej.pdf.PdfBrush({ r: 255, g: 255, b: 180 }), + border: new ej.pdf.PdfPen({ r: 255, g: 0, b: 0 }, 1), + padding: { left: 8, right: 8, top: 6, bottom: 6 }, + textProperties: { color: new ej.pdf.PdfBrush({ r: 0, g: 0, b: 180 }) } + } + }, + { value: 'Clay' } + ] +}]; +var grid = new ej.pdf.PdfGrid(2, widths, rows); +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Customize rows and columns + +Set a row height and style, and configure column widths and text alignment. + + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfBrush, PdfColumnInformation, PdfDocument, PdfFontFamily, PdfGrid, PdfPage, PdfStandardFont, PdfTemplateHorizontalAlignment, PdfTemplateVerticalAlignment } from '@syncfusion/ej2-pdf'; + +let document: PdfDocument = new PdfDocument(); +let page: PdfPage = document.addPage(); +let source: object[] = [{ id: 'E01', name: 'John' }, { id: 'E02', name: 'Thomas' }]; +let columns: PdfColumnInformation[] = [ + { + field: 'id', headerText: 'Employee ID', width: 80, + style: { textProperties: { + horizontalAlignment: PdfTemplateHorizontalAlignment.center, + verticalAlignment: PdfTemplateVerticalAlignment.middle + } } + }, + { field: 'name', headerText: 'Employee Name', width: 150 } +]; +let grid: PdfGrid = new PdfGrid(source, columns); +grid.rows[0].height = 50; +grid.rows[0].style = { + background: new PdfBrush({ r: 255, g: 255, b: 200 }), + textProperties: { + font: new PdfStandardFont(PdfFontFamily.courier, 10), + color: new PdfBrush({ r: 0, g: 0, b: 255 }) + } +}; +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +var document = new ej.pdf.PdfDocument(); +var page = document.addPage(); +var source = [{ id: 'E01', name: 'John' }, { id: 'E02', name: 'Thomas' }]; +var columns = [ + { + field: 'id', headerText: 'Employee ID', width: 80, + style: { textProperties: { + horizontalAlignment: ej.pdf.PdfTemplateHorizontalAlignment.center, + verticalAlignment: ej.pdf.PdfTemplateVerticalAlignment.middle + } } + }, + { field: 'name', headerText: 'Employee Name', width: 150 } +]; +var grid = new ej.pdf.PdfGrid(source, columns); +grid.rows[0].height = 50; +grid.rows[0].style = { + background: new ej.pdf.PdfBrush({ r: 255, g: 255, b: 200 }), + textProperties: { + font: new ej.pdf.PdfStandardFont(ej.pdf.PdfFontFamily.courier, 10), + color: new ej.pdf.PdfBrush({ r: 0, g: 0, b: 255 }) + } +}; +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Customize the whole table + +Use the grid-level `style` property to set padding, spacing, border, and text formatting. + + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfDocument, PdfFontFamily, PdfGrid, PdfPage, PdfPen, PdfStandardFont } from '@syncfusion/ej2-pdf'; + +let document: PdfDocument = new PdfDocument(); +let page: PdfPage = document.addPage(); +let source: object[] = [{ id: 'E01', name: 'Clay' }, { id: 'E02', name: 'Thomas' }]; +let columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; +let grid: PdfGrid = new PdfGrid(source, columns); +grid.style = { + padding: { left: 4, right: 4, top: 3, bottom: 3 }, + space: { left: 1, right: 1, top: 1, bottom: 1 }, + border: new PdfPen({ r: 80, g: 80, b: 80 }, 0.5), + textProperties: { font: new PdfStandardFont(PdfFontFamily.helvetica, 9) } +}; +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +var document = new ej.pdf.PdfDocument(); +var page = document.addPage(); +var source = [{ id: 'E01', name: 'Clay' }, { id: 'E02', name: 'Thomas' }]; +var columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; +var grid = new ej.pdf.PdfGrid(source, columns); +grid.style = { + padding: { left: 4, right: 4, top: 3, bottom: 3 }, + space: { left: 1, right: 1, top: 1, bottom: 1 }, + border: new ej.pdf.PdfPen({ r: 80, g: 80, b: 80 }, 0.5), + textProperties: { font: new ej.pdf.PdfStandardFont(ej.pdf.PdfFontFamily.helvetica, 9) } +}; +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Apply a built-in table style + +Pass a `PdfGridBuiltinStyle` value to the constructor. + + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfDocument, PdfGrid, PdfGridBuiltinStyle, PdfPage } from '@syncfusion/ej2-pdf'; + +let document: PdfDocument = new PdfDocument(); +let page: PdfPage = document.addPage(); +let source: object[] = [{ id: 'E01', name: 'Clay' }, { id: 'E02', name: 'Thomas' }]; +let columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; +let grid: PdfGrid = new PdfGrid(source, columns, undefined, PdfGridBuiltinStyle.gridTable4Accent1); +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +var document = new ej.pdf.PdfDocument(); +var page = document.addPage(); +var source = [{ id: 'E01', name: 'Clay' }, { id: 'E02', name: 'Thomas' }]; +var columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; +var grid = new ej.pdf.PdfGrid(source, columns, undefined, ej.pdf.PdfGridBuiltinStyle.gridTable4Accent1); +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Paginate a table + +Use `PdfLayoutFormat` to flow table rows across pages and repeat the header on continuation pages. + + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfDocument, PdfGrid, PdfGridLayoutResult, PdfLayoutBreakType, PdfLayoutFormat, PdfLayoutType, PdfPage } from '@syncfusion/ej2-pdf'; + +let document: PdfDocument = new PdfDocument(); +let page: PdfPage = document.addPage(); +let source: object[] = []; +for (let i: number = 1; i <= 100; i++) { + source.push({ id: 'E' + i, name: 'Employee ' + i }); +} +let columns = [{ field: 'id', headerText: 'ID', width: 80 }, { field: 'name', headerText: 'Name', width: 160 }]; +let grid: PdfGrid = new PdfGrid(source, columns); +grid.repeatHeader = true; +let format: PdfLayoutFormat = new PdfLayoutFormat(); +format.layout = PdfLayoutType.paginate; +format.break = PdfLayoutBreakType.fitPage; +let result: PdfGridLayoutResult = grid.draw(page, { x: 10, y: 10, width: 300, height: 500 }, format); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +var document = new ej.pdf.PdfDocument(); +var page = document.addPage(); +var source = []; +for (var i = 1; i <= 100; i++) { + source.push({ id: 'E' + i, name: 'Employee ' + i }); +} +var columns = [{ field: 'id', headerText: 'ID', width: 80 }, { field: 'name', headerText: 'Name', width: 160 }]; +var grid = new ej.pdf.PdfGrid(source, columns); +grid.repeatHeader = true; +var format = new ej.pdf.PdfLayoutFormat(); +format.layout = ej.pdf.PdfLayoutType.paginate; +format.break = ej.pdf.PdfLayoutBreakType.fitPage; +var result = grid.draw(page, { x: 10, y: 10, width: 300, height: 500 }, format); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Prevent row breaks across pages + +Use `PdfLayoutBreakType.fitElement` to keep each row together. If a row does not fit in the remaining space, the complete row moves to the next page. + + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfDocument, PdfGrid, PdfLayoutBreakType, PdfLayoutFormat, PdfLayoutType, PdfPage } from '@syncfusion/ej2-pdf'; + +let document: PdfDocument = new PdfDocument(); +let page: PdfPage = document.addPage(); +let source: object[] = []; +for (let i: number = 1; i <= 80; i++) { + source.push({ id: 'E' + i, description: 'Complete row content for employee ' + i }); +} +let columns = [ + { field: 'id', headerText: 'ID', width: 60 }, + { field: 'description', headerText: 'Description', width: 240 } +]; +let grid: PdfGrid = new PdfGrid(source, columns); +let format: PdfLayoutFormat = new PdfLayoutFormat(); +format.layout = PdfLayoutType.paginate; +format.break = PdfLayoutBreakType.fitElement; +grid.draw(page, { x: 10, y: 10, width: 320, height: 500 }, format); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +var document = new ej.pdf.PdfDocument(); +var page = document.addPage(); +var source = []; +for (var i = 1; i <= 80; i++) { + source.push({ id: 'E' + i, description: 'Complete row content for employee ' + i }); +} +var columns = [ + { field: 'id', headerText: 'ID', width: 60 }, + { field: 'description', headerText: 'Description', width: 240 } +]; +var grid = new ej.pdf.PdfGrid(source, columns); +var format = new ej.pdf.PdfLayoutFormat(); +format.layout = ej.pdf.PdfLayoutType.paginate; +format.break = ej.pdf.PdfLayoutBreakType.fitElement; +grid.draw(page, { x: 10, y: 10, width: 320, height: 500 }, format); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +N> The .NET `PaginateBounds` API used to change continuation-page margins is not available in the current JavaScript `PdfGrid` implementation. Therefore, a JavaScript sample for changing margins from the second page onwards is not included. +## Add multiple tables + +Use the page and occupied bounds returned by the first grid to position the second grid without overlap. + + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfDocument, PdfGrid, PdfGridLayoutResult, PdfPage } from '@syncfusion/ej2-pdf'; + +let document: PdfDocument = new PdfDocument(); +let page: PdfPage = document.addPage(); +let columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; +let firstGrid: PdfGrid = new PdfGrid([{ id: 'E01', name: 'Clay' }], columns); +let firstResult: PdfGridLayoutResult = firstGrid.draw(page, { x: 10, y: 10 }); +let secondGrid: PdfGrid = new PdfGrid([{ id: 'E02', name: 'Thomas' }], columns); +let secondY: number = firstResult.bounds.y + firstResult.bounds.height + 20; +secondGrid.draw(firstResult.page, { x: 10, y: secondY }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +var document = new ej.pdf.PdfDocument(); +var page = document.addPage(); +var columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; +var firstGrid = new ej.pdf.PdfGrid([{ id: 'E01', name: 'Clay' }], columns); +var firstResult = firstGrid.draw(page, { x: 10, y: 10 }); +var secondGrid = new ej.pdf.PdfGrid([{ id: 'E02', name: 'Thomas' }], columns); +var secondY = firstResult.bounds.y + firstResult.bounds.height + 20; +secondGrid.draw(firstResult.page, { x: 10, y: secondY }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Apply text formatting + +Apply font, color, and alignment through `textProperties`. + + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfBrush, PdfDocument, PdfFontFamily, PdfGrid, PdfPage, PdfStandardFont, PdfTemplateHorizontalAlignment, PdfTemplateVerticalAlignment } from '@syncfusion/ej2-pdf'; + +let document: PdfDocument = new PdfDocument(); +let page: PdfPage = document.addPage(); +let source: object[] = [{ id: 'E01', name: 'Clay' }, { id: 'E02', name: 'Thomas' }]; +let columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; +let grid: PdfGrid = new PdfGrid(source, columns); +grid.style = { textProperties: { + font: new PdfStandardFont(PdfFontFamily.helvetica, 10), + color: new PdfBrush({ r: 0, g: 0, b: 120 }), + horizontalAlignment: PdfTemplateHorizontalAlignment.center, + verticalAlignment: PdfTemplateVerticalAlignment.middle +} }; +grid.draw(page, { x: 10, y: 10, width: 280, height: 200 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +var document = new ej.pdf.PdfDocument(); +var page = document.addPage(); +var source = [{ id: 'E01', name: 'Clay' }, { id: 'E02', name: 'Thomas' }]; +var columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; +var grid = new ej.pdf.PdfGrid(source, columns); +grid.style = { textProperties: { + font: new ej.pdf.PdfStandardFont(ej.pdf.PdfFontFamily.helvetica, 10), + color: new ej.pdf.PdfBrush({ r: 0, g: 0, b: 120 }), + horizontalAlignment: ej.pdf.PdfTemplateHorizontalAlignment.center, + verticalAlignment: ej.pdf.PdfTemplateVerticalAlignment.middle +} }; +grid.draw(page, { x: 10, y: 10, width: 280, height: 200 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Apply row and column spanning + +Set `rowSpan` and `columnSpan` in a cell style. Span regions cannot overlap or extend beyond the grid. + + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfDocument, PdfGrid, PdfGridRow, PdfPage, PdfTemplateHorizontalAlignment } from '@syncfusion/ej2-pdf'; + +let document: PdfDocument = new PdfDocument(); +let page: PdfPage = document.addPage(); +let widths: Map = new Map([[0, 100], [1, 140]]); +let rows: PdfGridRow[] = [ + { cells: [ + { value: 'Employee Details', style: { columnSpan: 2, textProperties: { horizontalAlignment: PdfTemplateHorizontalAlignment.center } } } + ] }, + { cells: [ + { value: 'E01', style: { rowSpan: 2 } }, { value: 'Clay' } + ] }, + { cells: [{ value: 'Thomas' }] } +]; +let grid: PdfGrid = new PdfGrid(2, widths, rows); +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +var document = new ej.pdf.PdfDocument(); +var page = document.addPage(); +var widths = new Map([[0, 100], [1, 140]]); +var rows = [ + { cells: [ + { value: 'Employee Details', style: { columnSpan: 2, textProperties: { horizontalAlignment: ej.pdf.PdfTemplateHorizontalAlignment.center } } } + ] }, + { cells: [ + { value: 'E01', style: { rowSpan: 2 } }, { value: 'Clay' } + ] }, + { cells: [{ value: 'Thomas' }] } +]; +var grid = new ej.pdf.PdfGrid(2, widths, rows); +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Insert an image in a table cell + +Assign a `PdfBitmap` as the cell value and configure its size, fit mode, and alignment. + + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfBitmap, PdfDocument, PdfGrid, PdfGridRow, PdfPage, PdfTemplateHorizontalAlignment, PdfTemplateVerticalAlignment } from '@syncfusion/ej2-pdf'; + +let document: PdfDocument = new PdfDocument(); +let page: PdfPage = document.addPage(); +let image: PdfBitmap = new PdfBitmap(imageData); +let widths: Map = new Map([[0, 60], [1, 120]]); +let rows: PdfGridRow[] = [{ + height: 80, + cells: [ + { value: '1' }, + { value: image, style: { imageProperties: { + width: 60, height: 60, fitType: 2, + horizontalAlignment: PdfTemplateHorizontalAlignment.center, + verticalAlignment: PdfTemplateVerticalAlignment.middle + } } } + ] +}]; +let grid: PdfGrid = new PdfGrid(2, widths, rows); +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +var document = new ej.pdf.PdfDocument(); +var page = document.addPage(); +var image = new ej.pdf.PdfBitmap(imageData); +var widths = new Map([[0, 60], [1, 120]]); +var rows = [{ + height: 80, + cells: [ + { value: '1' }, + { value: image, style: { imageProperties: { + width: 60, height: 60, fitType: 2, + horizontalAlignment: ej.pdf.PdfTemplateHorizontalAlignment.center, + verticalAlignment: ej.pdf.PdfTemplateVerticalAlignment.middle + } } } + ] +}]; +var grid = new ej.pdf.PdfGrid(2, widths, rows); +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Add a background image to a table cell + +Set `backgroundImage` in the cell style. A `fitType` value of `3` stretches the background image to fill the content area. + + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfBitmap, PdfDocument, PdfGrid, PdfGridRow, PdfPage, PdfTemplateHorizontalAlignment, PdfTemplateVerticalAlignment } from '@syncfusion/ej2-pdf'; + +let document: PdfDocument = new PdfDocument(); +let page: PdfPage = document.addPage(); +let image: PdfBitmap = new PdfBitmap(imageData); +let widths: Map = new Map([[0, 140], [1, 100]]); +let rows: PdfGridRow[] = [{ + height: 70, + cells: [ + { value: 'Employee ID', style: { backgroundImage: { + image: image, + imageProperties: { + fitType: 3, + horizontalAlignment: PdfTemplateHorizontalAlignment.center, + verticalAlignment: PdfTemplateVerticalAlignment.middle + } + } } }, + { value: 'E01' } + ] +}]; +let grid: PdfGrid = new PdfGrid(2, widths, rows); +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +var document = new ej.pdf.PdfDocument(); +var page = document.addPage(); +var image = new ej.pdf.PdfBitmap(imageData); +var widths = new Map([[0, 140], [1, 100]]); +var rows = [{ + height: 70, + cells: [ + { value: 'Employee ID', style: { backgroundImage: { + image: image, + imageProperties: { + fitType: 3, + horizontalAlignment: ej.pdf.PdfTemplateHorizontalAlignment.center, + verticalAlignment: ej.pdf.PdfTemplateVerticalAlignment.middle + } + } } }, + { value: 'E01' } + ] +}]; +var grid = new ej.pdf.PdfGrid(2, widths, rows); +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Add hyperlinks + +A string beginning with `http://` or `https://` creates a URI annotation during page-based drawing. An explicit `PdfLink` can also be assigned. + + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfDocument, PdfGrid, PdfGridRow, PdfLinkType, PdfPage } from '@syncfusion/ej2-pdf'; + +let document: PdfDocument = new PdfDocument(); +let page: PdfPage = document.addPage(); +let widths: Map = new Map([[0, 130], [1, 180]]); +let rows: PdfGridRow[] = [ + { cells: [{ value: 'Product page' }, { value: 'https://www.syncfusion.com' }] }, + { cells: [{ value: 'Report' }, { value: 'Open file', link: { type: PdfLinkType.file, uri: 'Report.pdf' } }] } +]; +let grid: PdfGrid = new PdfGrid(2, widths, rows); +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +var document = new ej.pdf.PdfDocument(); +var page = document.addPage(); +var widths = new Map([[0, 130], [1, 180]]); +var rows = [ + { cells: [{ value: 'Product page' }, { value: 'https://www.syncfusion.com' }] }, + { cells: [{ value: 'Report' }, { value: 'Open file', link: { type: ej.pdf.PdfLinkType.file, uri: 'Report.pdf' } }] } +]; +var grid = new ej.pdf.PdfGrid(2, widths, rows); +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Draw a borderless table + +Use a zero-width border at grid level. + + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfDocument, PdfGrid, PdfGridStyle, PdfPage, PdfPen } from '@syncfusion/ej2-pdf'; + +let document: PdfDocument = new PdfDocument(); +let page: PdfPage = document.addPage(); +let source: object[] = [{ id: 'E01', name: 'Clay' }, { id: 'E02', name: 'Thomas' }]; +let columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; +let style: PdfGridStyle = { border: new PdfPen({ r: 255, g: 255, b: 255 }, 0) }; +let grid: PdfGrid = new PdfGrid(source, columns, style); +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +var document = new ej.pdf.PdfDocument(); +var page = document.addPage(); +var source = [{ id: 'E01', name: 'Clay' }, { id: 'E02', name: 'Thomas' }]; +var columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; +var style = { border: new ej.pdf.PdfPen({ r: 255, g: 255, b: 255 }, 0) }; +var grid = new ej.pdf.PdfGrid(source, columns, style); +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Update the grid data source + +Reassign `dataSource` on a data-source grid. Generated rows are rebuilt, while manually added rows remain after them. + + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfDocument, PdfGrid, PdfPage } from '@syncfusion/ej2-pdf'; + +let document: PdfDocument = new PdfDocument(); +let page: PdfPage = document.addPage(); +let columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; +let grid: PdfGrid = new PdfGrid([{ id: 'E01', name: 'Clay' }], columns); +grid.addRow({ cells: [{ value: 'Manual' }, { value: 'Record' }] }); +grid.dataSource = [{ id: 'E10', name: 'Andrew' }, { id: 'E11', name: 'Michael' }]; +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +var document = new ej.pdf.PdfDocument(); +var page = document.addPage(); +var columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; +var grid = new ej.pdf.PdfGrid([{ id: 'E01', name: 'Clay' }], columns); +grid.addRow({ cells: [{ value: 'Manual' }, { value: 'Record' }] }); +grid.dataSource = [{ id: 'E10', name: 'Andrew' }, { id: 'E11', name: 'Michael' }]; +grid.draw(page, { x: 10, y: 10 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Draw by using a graphics context + +The graphics overload does not paginate. The complete grid must fit within the supplied bounds. + + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfDocument, PdfGrid, PdfPage } from '@syncfusion/ej2-pdf'; + +let document: PdfDocument = new PdfDocument(); +let page: PdfPage = document.addPage(); +let source: object[] = [{ id: 'E01', name: 'Clay' }, { id: 'E02', name: 'Thomas' }]; +let columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; +let grid: PdfGrid = new PdfGrid(source, columns); +grid.draw(page.graphics, { x: 10, y: 10, width: 300, height: 200 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +var document = new ej.pdf.PdfDocument(); +var page = document.addPage(); +var source = [{ id: 'E01', name: 'Clay' }, { id: 'E02', name: 'Thomas' }]; +var columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; +var grid = new ej.pdf.PdfGrid(source, columns); +grid.draw(page.graphics, { x: 10, y: 10, width: 300, height: 200 }); +document.save('Output.pdf'); +document.destroy(); + +{% endhighlight %} +{% endtabs %} + + +## JavaScript and .NET feature differences + +The following .NET PdfGrid APIs are not present in the supplied JavaScript implementation: + +- Nested `PdfGrid` objects as cell values +- `BeginCellLayout` and `BeginPageLayout` events +- Event-based table rotation +- `PdfGridBuiltinStyleSettings` +- `AllowHorizontalOverflow` +- `PaginateBounds` +- Per-side border collections such as `Borders.All` +- Direct annotation objects as cell values +- `PdfWordWrapType` and character-spacing formatting + +## Additional Resources + +- [JavaScript PDF Library](https://www.syncfusion.com/document-sdk/javascript-pdf-library) +- [JavaScript PDF Library documentation](https://help.syncfusion.com/document-processing/pdf/pdf-library/javascript/overview) +- [JavaScript PDF Library API reference](https://ej2.syncfusion.com/documentation/api/pdf) +- [JavaScript PDF Library examples](https://document.syncfusion.com/demos/pdf/javascript/#/tailwind3/pdf/default.html) +- [JavaScript PDF examples on GitHub](https://github.com/SyncfusionExamples/javascript-pdf-examples) diff --git a/Document-Processing/PDF/PDF-Library/javascript/Text-Extraction.md b/Document-Processing/PDF/PDF-Library/javascript/Text-Extraction.md index 33ce8f3cc8..fc0526d072 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/Text-Extraction.md +++ b/Document-Processing/PDF/PDF-Library/javascript/Text-Extraction.md @@ -18,9 +18,9 @@ The JavaScript PDF library allows you to extract text from a particular page or N> The `@syncfusion/ej2-pdf-data-extract` add-on package also powers the redaction features available in the JavaScript PDF Library. -## Working with basic text extraction +## Working with basic text extraction synchronously -This example demonstrates how to extract plain text from a PDF document using the [PdfDataExtractor](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor) class. Basic text extraction retrieves text content from the entire PDF document. +This example demonstrates how to extract plain text from a PDF document synchronously using the [PdfDataExtractor](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor) class and the `extractTextSync` method. Basic text extraction retrieves text content from the entire PDF document immediately. {% tabs %} {% highlight typescript tabtitle="TypeScript" %} @@ -32,8 +32,8 @@ import { PdfDataExtractor } from '@syncfusion/ej2-pdf-data-extract'; let document: PdfDocument = new PdfDocument(data); // Initialize a new instance of the `PdfDataExtractor` class let extractor: PdfDataExtractor = new PdfDataExtractor(document); -// Extract text content from the PDF document. -let text: string = extractor.extractText(); +// Extract text content from the PDF document synchronously. +let text: string = extractor.extractTextSync(); // Save the document document.save('Output.pdf'); // Close the document @@ -46,8 +46,8 @@ document.destroy(); var document = new ej.pdf.PdfDocument(data); // Initialize a new instance of the PdfDataExtractor class var extractor = new ej.pdfdataextract.PdfDataExtractor(document); -// Extract text content from the PDF document -var text = extractor.extractText(); +// Extract text content from the PDF document synchronously +var text = extractor.extractTextSync(); // Save the document document.save('Output.pdf'); // Close the document @@ -56,9 +56,113 @@ document.destroy(); {% endhighlight %} {% endtabs %} -## Extract text from specific page range in a PDF document +## Working with basic text extraction asynchronously -This example demonstrates how to extract text from a PDF document by specifying a start and end page index. This approach allows you to retrieve text content from a defined range of pages for processing or analysis. +This example demonstrates how to extract plain text from a PDF document asynchronously using the [PdfDataExtractor](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor) class and the `extractText` method. Basic text extraction retrieves text content from the entire PDF document. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfDocument } from '@syncfusion/ej2-pdf'; +import { PdfDataExtractor } from '@syncfusion/ej2-pdf-data-extract'; + +// Load an existing PDF document +let document: PdfDocument = new PdfDocument(data); +// Initialize a new instance of the `PdfDataExtractor` class +let extractor: PdfDataExtractor = new PdfDataExtractor(document); +// Extract text content from the PDF document asynchronously. +let text: string = await extractor.extractText(); +// Save the document +document.save('Output.pdf'); +// Close the document +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load an existing PDF document +var document = new ej.pdf.PdfDocument(data); +// Initialize a new instance of the PdfDataExtractor class +var extractor = new ej.pdfdataextract.PdfDataExtractor(document); +// Extract text content from the PDF document asynchronously +var text = await extractor.extractText(); +// Save the document +document.save('Output.pdf'); +// Close the document +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Extract text from a specific page range in a PDF document synchronously + +This example demonstrates how to synchronously extract text from a PDF document by specifying a start and end page index. This approach allows you to retrieve text content from a defined range of pages for processing or analysis. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} +import { PdfDocument } from '@syncfusion/ej2-pdf'; +import { PdfDataExtractor } from '@syncfusion/ej2-pdf-data-extract'; + +// Load an existing PDF document +let document: PdfDocument = new PdfDocument(data); +// Initialize a new instance of the `PdfDataExtractor` class +let extractor: PdfDataExtractor = new PdfDataExtractor(document); +// Extract text content from the specified page range synchronously +let text: string = extractor.extractTextSync({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); +// Release document resources +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load an existing PDF document +var document = new ej.pdf.PdfDocument(data); +// Initialize a new instance of the `PdfDataExtractor` class +var extractor = new ej.pdfdataextract.PdfDataExtractor(document); +// Extract text content from the specified page range synchronously +var text = extractor.extractTextSync({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); +// Release document resources +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Extract text from a specific page range in a PDF document asynchronously + +This example demonstrates how to asynchronously extract text from a PDF document by specifying a start and end page index. This approach allows you to retrieve text content from a defined range of pages for processing or analysis. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} +import { PdfDocument } from '@syncfusion/ej2-pdf'; +import { PdfDataExtractor } from '@syncfusion/ej2-pdf-data-extract'; + +// Load an existing PDF document +let document: PdfDocument = new PdfDocument(data); +// Initialize a new instance of the `PdfDataExtractor` class +let extractor: PdfDataExtractor = new PdfDataExtractor(document); +// Extract text content from the specified page range asynchronously +let text: string = await extractor.extractText({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); +// Release document resources +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load an existing PDF document +var document = new ej.pdf.PdfDocument(data); +// Initialize a new instance of the `PdfDataExtractor` class +var extractor = new ej.pdfdataextract.PdfDataExtractor(document); +// Extract text content from the specified page range asynchronously +var text = await extractor.extractText({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); +// Release document resources +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +## Working with layout-based text extraction synchronously + +This example demonstrates how to extract text from a PDF document synchronously using the [PdfDataExtractor](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor) class with layout-based options. Layout-based extraction preserves the visual structure of the source document, including line breaks and spacing. {% tabs %} {% highlight typescript tabtitle="TypeScript" %} @@ -69,8 +173,8 @@ import { PdfDataExtractor } from '@syncfusion/ej2-pdf-data-extract'; let document: PdfDocument = new PdfDocument(data); // Initialize a new instance of the `PdfDataExtractor` class let extractor: PdfDataExtractor = new PdfDataExtractor(document); -// Extract text content from the specified page range -let text: string = extractor.extractText({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); +// Extract text from the PDF page based on its layout synchronously +let text: string = extractor.extractTextSync({ isLayout: true }); // Release document resources document.destroy(); @@ -81,17 +185,17 @@ document.destroy(); var document = new ej.pdf.PdfDocument(data); // Initialize a new instance of the `PdfDataExtractor` class var extractor = new ej.pdfdataextract.PdfDataExtractor(document); -// Extract text content from the specified page range -var text = extractor.extractText({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); +// Extract text from the PDF page based on its layout synchronously +var text = extractor.extractTextSync({ isLayout: true }); // Release document resources document.destroy(); {% endhighlight %} {% endtabs %} -## Working with layout-based text extraction +## Working with layout-based text extraction asynchronously -This example demonstrates how to extract text from a PDF document using the [PdfDataExtractor](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor) class with layout-based options. Layout-based extraction preserves the visual structure of the source document, including line breaks and spacing. +This example demonstrates how to extract text from a PDF document asynchronously using the [PdfDataExtractor](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor) class with layout-based options. Layout-based extraction preserves the visual structure of the source document, including line breaks and spacing. {% tabs %} {% highlight typescript tabtitle="TypeScript" %} @@ -102,8 +206,8 @@ import { PdfDataExtractor } from '@syncfusion/ej2-pdf-data-extract'; let document: PdfDocument = new PdfDocument(data); // Initialize a new instance of the `PdfDataExtractor` class let extractor: PdfDataExtractor = new PdfDataExtractor(document); -// Extract text from the PDF page based on its layout -let text: string = extractor.extractText({ isLayout: true }); +// Extract text from the PDF page based on its layout asynchronously +let text: string = await extractor.extractText({ isLayout: true }); // Release document resources document.destroy(); @@ -114,8 +218,8 @@ document.destroy(); var document = new ej.pdf.PdfDocument(data); // Initialize a new instance of the `PdfDataExtractor` class var extractor = new ej.pdfdataextract.PdfDataExtractor(document); -// Extract text from the PDF page based on its layout -var text = extractor.extractText({ isLayout: true }); +// Extract text from the PDF page based on its layout asynchronously +var text = await extractor.extractText({ isLayout: true }); // Release document resources document.destroy(); From 3e0b91fe1c3cabdc2238cdcee103928bf846d004 Mon Sep 17 00:00:00 2001 From: santhiya Date: Tue, 1 Sep 2026 19:10:49 +0530 Subject: [PATCH 05/11] 1050196: Added content for digital signature --- .../javascript/DigitalSignature.md | 315 ++++++++++++++---- 1 file changed, 243 insertions(+), 72 deletions(-) diff --git a/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md b/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md index 1fb277debd..d82e34b6bf 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md +++ b/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md @@ -181,7 +181,7 @@ let externalSignatureCallback = ( return { signedData: new Uint8Array() }; // Placeholder return }; // Create a new signature using external signing -let signature: PdfSignature = signatureField.create (externalSignatureCallback, { +let signature: PdfSignature = PdfSignature.create(externalSignatureCallback, { cryptographicStandard: CryptographicStandard.cms, algorithm: DigestAlgorithm.sha256, }); @@ -431,43 +431,91 @@ The JavaScript PDF Library supports Long-Term Validation for digital signatures You can create Long Term Validation (LTV) after externally signing a PDF document by using your public certificate chain. The following code example shows how to complete the external signing process and enable LTV using the [`enableLTV()`](https://ej2.syncfusion.com/documentation/api/pdf/pdfsignature#enableltv) method of the [`PdfSignature`](https://ej2.syncfusion.com/documentation/api/pdf/pdfsignature) class. The callback supplied to `enableLTV()` must retrieve the actual OCSP or CRL response requested by the library and return the response bytes as a `Uint8Array`. - {% tabs %} {% highlight typescript tabtitle="TypeScript" %} import { PdfDocument, - PdfForm, + PdfPage, PdfSignatureField, PdfSignature, + PdfSignatureOptions, DigestAlgorithm, + CryptographicStandard, RevocationType } from '@syncfusion/ej2-pdf'; -// Load the externally signed PDF document -let document: PdfDocument = new PdfDocument(data); -// Access the PDF form -let form: PdfForm = document.form; -// Get the externally signed signature field -let field: PdfSignatureField = form.fieldAt(0) as PdfSignatureField; -// Get the existing signature -let signature: PdfSignature = field.getSignature(); -// Public certificate chain used for long-term validation -let publicCertificates: Uint8Array[] = [/* your certificates here */]; +// Define a callback function for external signing +function externalSignatureCallback( + data: Uint8Array, + options: { + algorithm: DigestAlgorithm, + cryptographicStandard: CryptographicStandard + } +): { signedData: Uint8Array; timestampData?: Uint8Array } { + // Sign the supplied document data using an external signing service + return { signedData: externalSignedData }; +} -// Retrieve the OCSP or CRL response requested by the library +// Define a callback function to retrieve OCSP or CRL responses async function longTermValidationCallback( url: string, requestBytes?: Uint8Array ): Promise<{ response: Uint8Array }> { - // Send requestBytes to the supplied URL and return the actual response bytes - return { response: new Uint8Array() }; + // Send requestBytes to the supplied URL and return the actual OCSP or CRL response + return { response: revocationResponse }; } -// Enable LTV and include the public certificates in the PDF document +// Create a new PDF document +let document: PdfDocument = new PdfDocument(); +// Add a page to the document +let page: PdfPage = document.addPage(); +// Create a signature field +let field: PdfSignatureField = new PdfSignatureField( + page, + 'field', + { x: 50, y: 50, width: 100, height: 100 } +); + +// Create a signature using the external-signing callback +let signature: PdfSignature = PdfSignature.create( + externalSignatureCallback, + { + cryptographicStandard: CryptographicStandard.cms, + digestAlgorithm: DigestAlgorithm.sha256, + contactInfo: 'johndoe@owned.us', + locationInfo: 'Honolulu, Hawaii', + reason: 'I am author of this document.', + signedName: 'Signature' + } +); +// Add the signature field to the PDF form +document.form.add(field); +// Set the signature to the field +field.setSignature(signature); +// Save the externally signed PDF document +let data: Uint8Array = document.save(); +// Destroy the document +document.destroy(); + +// Load the externally signed PDF document +document = new PdfDocument(data); +// Get the existing signature field +field = document.form.fieldAt(0) as PdfSignatureField; +// Get the existing signature +signature = field.getSignature(); +// Get the signature options +let options: PdfSignatureOptions = signature.getSignatureOptions(); + +// Public certificate chain used for long-term validation +let publicCertificates: Uint8Array[] = [ + publicCertificate1, + publicCertificate2 +]; + +// Enable LTV using the available OCSP or CRL response let ltvEnabled: boolean = await signature.enableLTV( publicCertificates, - RevocationType.crl, - true, + RevocationType.ocspOrCrl, longTermValidationCallback ); if (ltvEnabled) { @@ -480,28 +528,69 @@ document.destroy(); {% endhighlight %} {% highlight javascript tabtitle="JavaScript" %} +// Define a callback function for external signing +function externalSignatureCallback(data, options) { + // Sign the supplied document data using an external signing service + return { signedData: externalSignedData }; +} + +// Define a callback function to retrieve OCSP or CRL responses +async function longTermValidationCallback(url, requestBytes) { + // Send requestBytes to the supplied URL and return the actual OCSP or CRL response + return { response: revocationResponse }; +} + +// Create a new PDF document +var document = new ej.pdf.PdfDocument(); +// Add a page to the document +var page = document.addPage(); +// Create a signature field +var field = new ej.pdf.PdfSignatureField( + page, + 'field', + { x: 50, y: 50, width: 100, height: 100 } +); + +// Create a signature using the external-signing callback +var signature = ej.pdf.PdfSignature.create( + externalSignatureCallback, + { + cryptographicStandard: ej.pdf.CryptographicStandard.cms, + digestAlgorithm: ej.pdf.DigestAlgorithm.sha256, + contactInfo: 'johndoe@owned.us', + locationInfo: 'Honolulu, Hawaii', + reason: 'I am author of this document.', + signedName: 'Signature' + } +); +// Add the signature field to the PDF form +document.form.add(field); +// Set the signature to the field +field.setSignature(signature); +// Save the externally signed PDF document +var data = document.save(); +// Destroy the document +document.destroy(); + // Load the externally signed PDF document -var document = new ej.pdf.PdfDocument(data); -// Access the PDF form -var form = document.form; -// Get the externally signed signature field -var field = form.fieldAt(0); +document = new ej.pdf.PdfDocument(data); +// Get the existing signature field +field = document.form.fieldAt(0); // Get the existing signature -var signature = field.getSignature(); -// Public certificate chain used for long-term validation -var publicCertificates = [/* your certificates here */]; +signature = field.getSignature(); +// Get the signature options +var options = signature.getSignatureOptions(); -// Retrieve the OCSP or CRL response requested by the library -var longTermValidationCallback = async function (url, requestBytes) { - // Send requestBytes to the supplied URL and return the actual response bytes - return { response: new Uint8Array() }; -}; +// Public certificate chain used for long-term validation +var publicCertificates = [ + publicCertificate1, + publicCertificate2 +]; -// Enable LTV and include the public certificates in the PDF document +// Enable LTV using the available OCSP or CRL response var ltvEnabled = await signature.enableLTV( publicCertificates, - ej.pdf.RevocationType.crl, - true, + ej.pdf.RevocationType.ocspOrCrl, longTermValidationCallback ); if (ltvEnabled) { @@ -599,42 +688,86 @@ N> When a PDF document contains multiple signatures, call `enableLTV()` for each You can provide the public certificate chain, select the revocation mode, and specify whether the certificates must be included in the PDF document while enabling LTV. The following code example uses CRL-based revocation information and includes the supplied public certificates in the document. - {% tabs %} {% highlight typescript tabtitle="TypeScript" %} import { PdfDocument, - PdfForm, + PdfPage, PdfSignatureField, PdfSignature, - RevocationType + DigestAlgorithm, + CryptographicStandard } from '@syncfusion/ej2-pdf'; -// Load the signed PDF document -let document: PdfDocument = new PdfDocument(data); -// Access the PDF form -let form: PdfForm = document.form; -// Get the signature field -let field: PdfSignatureField = form.fieldAt(0) as PdfSignatureField; -// Get the signature -let signature: PdfSignature = field.getSignature(); -// Public certificate chain used for validation -let publicCertificates: Uint8Array[] = [/* your certificates here */]; +// Define a callback function for external signing +function externalSignatureCallback( + data: Uint8Array, + options: { + algorithm: DigestAlgorithm, + cryptographicStandard: CryptographicStandard + } +): { signedData: Uint8Array; timestampData?: Uint8Array } { + // Sign the supplied document data using an external signing service + return { signedData: externalSignedData }; +} -// Retrieve the revocation response requested by the library +// Define a callback function to retrieve OCSP and CRL responses async function longTermValidationCallback( url: string, requestBytes?: Uint8Array ): Promise<{ response: Uint8Array }> { - // Send requestBytes to the supplied URL and return the actual response bytes - return { response: new Uint8Array() }; + // Send requestBytes to the supplied URL and return the actual OCSP or CRL response + return { response: revocationResponse }; } -// Enable LTV using CRL responses and include the public certificates +// Create a new PDF document +let document: PdfDocument = new PdfDocument(); +// Add a page to the document +let page: PdfPage = document.addPage(); +// Create a signature field +let field: PdfSignatureField = new PdfSignatureField( + page, + 'field', + { x: 50, y: 50, width: 100, height: 100 } +); + +// Create a signature using the external-signing callback +let signature: PdfSignature = PdfSignature.create( + externalSignatureCallback, + { + cryptographicStandard: CryptographicStandard.cms, + digestAlgorithm: DigestAlgorithm.sha1, + contactInfo: 'johndoe@owned.us', + locationInfo: 'Honolulu, Hawaii', + reason: 'I am author of this document.', + signedName: 'Signature' + } +); +// Add the signature field to the PDF form +document.form.add(field); +// Set the signature to the field +field.setSignature(signature); +// Save the externally signed PDF document +let data: Uint8Array = document.save(); +// Destroy the document +document.destroy(); + +// Load the externally signed PDF document +document = new PdfDocument(data); +// Get the existing signature field +field = document.form.fieldAt(0) as PdfSignatureField; +// Get the existing signature +signature = field.getSignature(); + +// Public certificate chain used for long-term validation +let publicCertificates: Uint8Array[] = [ + publicCertificate1, + publicCertificate2 +]; + +// Enable LTV using the public certificate chain let ltvEnabled: boolean = await signature.enableLTV( publicCertificates, - RevocationType.crl, - true, longTermValidationCallback ); if (ltvEnabled) { @@ -647,28 +780,66 @@ document.destroy(); {% endhighlight %} {% highlight javascript tabtitle="JavaScript" %} -// Load the signed PDF document -var document = new ej.pdf.PdfDocument(data); -// Access the PDF form -var form = document.form; -// Get the signature field -var field = form.fieldAt(0); -// Get the signature -var signature = field.getSignature(); -// Public certificate chain used for validation -var publicCertificates = [/* your certificates here */]; +// Define a callback function for external signing +function externalSignatureCallback(data, options) { + // Sign the supplied document data using an external signing service + return { signedData: externalSignedData }; +} -// Retrieve the revocation response requested by the library -var longTermValidationCallback = async function (url, requestBytes) { - // Send requestBytes to the supplied URL and return the actual response bytes - return { response: new Uint8Array() }; -}; +// Define a callback function to retrieve OCSP and CRL responses +async function longTermValidationCallback(url, requestBytes) { + // Send requestBytes to the supplied URL and return the actual OCSP or CRL response + return { response: revocationResponse }; +} + +// Create a new PDF document +var document = new ej.pdf.PdfDocument(); +// Add a page to the document +var page = document.addPage(); +// Create a signature field +var field = new ej.pdf.PdfSignatureField( + page, + 'field', + { x: 50, y: 50, width: 100, height: 100 } +); + +// Create a signature using the external-signing callback +var signature = ej.pdf.PdfSignature.create( + externalSignatureCallback, + { + cryptographicStandard: ej.pdf.CryptographicStandard.cms, + digestAlgorithm: ej.pdf.DigestAlgorithm.sha1, + contactInfo: 'johndoe@owned.us', + locationInfo: 'Honolulu, Hawaii', + reason: 'I am author of this document.', + signedName: 'Signature' + } +); +// Add the signature field to the PDF form +document.form.add(field); +// Set the signature to the field +field.setSignature(signature); +// Save the externally signed PDF document +var data = document.save(); +// Destroy the document +document.destroy(); + +// Load the externally signed PDF document +document = new ej.pdf.PdfDocument(data); +// Get the existing signature field +field = document.form.fieldAt(0); +// Get the existing signature +signature = field.getSignature(); + +// Public certificate chain used for long-term validation +var publicCertificates = [ + publicCertificate1, + publicCertificate2 +]; -// Enable LTV using CRL responses and include the public certificates +// Enable LTV using the public certificate chain var ltvEnabled = await signature.enableLTV( publicCertificates, - ej.pdf.RevocationType.crl, - true, longTermValidationCallback ); if (ltvEnabled) { From a576ab0576f325c4a8e61f39c379af707155fe04 Mon Sep 17 00:00:00 2001 From: "AzureAD\\DhakshinPrasathDhanr" Date: Wed, 2 Sep 2026 10:39:08 +0530 Subject: [PATCH 06/11] 1050196: Updated Text extraction file --- .../PDF-Library/javascript/Text-Extraction.md | 239 ++++++++++++++++-- 1 file changed, 222 insertions(+), 17 deletions(-) diff --git a/Document-Processing/PDF/PDF-Library/javascript/Text-Extraction.md b/Document-Processing/PDF/PDF-Library/javascript/Text-Extraction.md index fc0526d072..5eb3114ce3 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/Text-Extraction.md +++ b/Document-Processing/PDF/PDF-Library/javascript/Text-Extraction.md @@ -230,11 +230,11 @@ N> Layout-based text extraction may take additional processing time when compare ## Text extraction with bounds -The following sections describe how to extract text along with positional and typographic information using the [extractTextLines](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlines) method. The method returns a hierarchical collection of [TextLine](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textline), [TextWord](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textword), and [TextGlyph](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textglyph) objects. +The following sections describe how to extract text along with positional and typographic information using the [extractTextLinesSync](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlinessync) and [extractTextLines](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlines) methods. The method returns a hierarchical collection of [TextLine](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textline), [TextWord](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textword), and [TextGlyph](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textglyph) objects. -### Working with lines +### Working with lines synchronously -This example demonstrates how to extract text from a PDF page based on individual lines. The [extractTextLines](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlines) method returns a collection of [TextLine](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textline) objects, allowing precise access to text content line by line. +This example demonstrates how to extract text from a PDF page based on individual lines. The [extractTextLinesSync](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlinessync) method returns a collection of [TextLine](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textline) objects, allowing precise access to text content line by line. {% tabs %} {% highlight typescript tabtitle="TypeScript" %} @@ -245,8 +245,8 @@ import { PdfDataExtractor, TextLine, TextWord, TextGlyph, PdfFontStyle, Rectangl let document: PdfDocument = new PdfDocument(data); // Initialize a new instance of the `PdfDataExtractor` class let extractor: PdfDataExtractor = new PdfDataExtractor(document); -// Extract `TextLine` objects from the PDF document -let textLines: Array = extractor.extractTextLines({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); +// Extract `TextLine` objects from the PDF document synchronously +let textLines: Array = extractor.extractTextLinesSync({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); // Iterate through each text line in the collection textLines.forEach((textLine: TextLine) => { // Gets the bounds of the text line @@ -274,8 +274,8 @@ document.destroy(); var document = new ej.pdf.PdfDocument(data); // Initialize a new instance of the `PdfDataExtractor` class var extractor = new ej.pdfdataextract.PdfDataExtractor(document); -// Extract `TextLine` objects from the PDF document -var textLines = extractor.extractTextLines({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); +// Extract `TextLine` objects from the PDF document synchronously +var textLines = extractor.extractTextLinesSync({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); // Iterate through each text line in the collection textLines.forEach((textLine) => { // Gets the bounds of the text line @@ -299,7 +299,139 @@ document.destroy(); {% endhighlight %} {% endtabs %} -### Working with words +### Working with lines asynchronously + +This example demonstrates how to extract text from a PDF page based on individual lines asynchronously. The [extractTextLines](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlines) method returns a collection of [TextLine](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textline) objects, allowing precise access to text content line by line. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} +import { PdfDocument } from '@syncfusion/ej2-pdf'; +import { PdfDataExtractor, TextLine, TextWord, TextGlyph, PdfFontStyle, Rectangle } from '@syncfusion/ej2-pdf-data-extract'; + +// Load an existing PDF document +let document: PdfDocument = new PdfDocument(data); +// Initialize a new instance of the `PdfDataExtractor` class +let extractor: PdfDataExtractor = new PdfDataExtractor(document); +// Extract `TextLine` objects from the PDF document asynchronously +let textLines: Array = await extractor.extractTextLines({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); +// Iterate through each text line in the collection +textLines.forEach((textLine: TextLine) => { + // Gets the bounds of the text line + let lineBounds: Rectangle = textLine.bounds; + // Gets the single line of extracted text from the PDF page + let line: string = textLine.text; + // Gets the page index of the text line extracted + let pageIndex: number = textLine.pageIndex; + // Gets the collection of text words extracted from a specified page in a PDF document + let words: TextWord[] = textLine.words; + // Gets the name of the font used for a particular line of text + let fontName: string = textLine.fontName; + // Gets the font style used for a particular line of text + let fontStyle: PdfFontStyle = textLine.fontStyle; + // Gets the font size used for a particular line of text + let fontSize: number = textLine.fontSize; +}); +// Release document resources +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load an existing PDF document +var document = new ej.pdf.PdfDocument(data); +// Initialize a new instance of the `PdfDataExtractor` class +var extractor = new ej.pdfdataextract.PdfDataExtractor(document); +// Extract `TextLine` objects from the PDF document asynchronously +var textLines = await extractor.extractTextLines({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); +// Iterate through each text line in the collection +textLines.forEach((textLine) => { + // Gets the bounds of the text line + var lineBounds = textLine.bounds; + // Gets the single line of extracted text from the PDF page + var line = textLine.text; + // Gets the page index of the text line extracted + var pageIndex = textLine.pageIndex; + // Gets the collection of text words extracted from a specified page in a PDF document + var words = textLine.words; + // Gets the name of the font used for a particular line of text + var fontName = textLine.fontName; + // Gets the font style used for a particular line of text + var fontStyle = textLine.fontStyle; + // Gets the font size used for a particular line of text + var fontSize = textLine.fontSize; +}); +// Release document resources +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +### Working with words synchronously + +This example demonstrates how to extract words from a PDF document using the [extractTextLinesSync](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlinessync) method. Each line contains a collection of [TextWord](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textword) objects. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} +import { PdfDocument } from '@syncfusion/ej2-pdf'; +import { PdfDataExtractor, TextLine, TextWord, TextGlyph, PdfFontStyle, Rectangle } from '@syncfusion/ej2-pdf-data-extract'; + +// Load an existing PDF document +let document: PdfDocument = new PdfDocument(data); +// Initialize a new instance of the `PdfDataExtractor` class +let extractor: PdfDataExtractor = new PdfDataExtractor(document); +// Extract `TextLine` objects from the PDF document synchronously +let textLines: Array = extractor.extractTextLinesSync({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); +textLines.forEach((textLine: TextLine) => { + textLine.words.forEach((textWord: TextWord) => { + // Gets the bounds of the text word + let wordBounds: Rectangle = textWord.bounds; + // Gets the single word of extracted text from the PDF page + let word: string = textWord.text; + // Gets the collection of text glyphs extracted from a specified page in a PDF document + let glyphs: TextGlyph[] = textWord.glyphs; + // Gets the name of the font used for a particular word + let wordFontName: string = textWord.fontName; + // Gets the style of the font used for a particular word + let wordFontStyle: PdfFontStyle = textWord.fontStyle; + // Gets the size of the font used for a particular word + let wordFontSize: number = textWord.fontSize; + }); +}); +// Release document resources +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load an existing PDF document +var document = new ej.pdf.PdfDocument(data); +// Initialize a new instance of the `PdfDataExtractor` class +var extractor = new ej.pdfdataextract.PdfDataExtractor(document); +// Extract `TextLine` objects from the PDF document synchronously +var textLines = extractor.extractTextLinesSync({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); +textLines.forEach((textLine) => { + textLine.words.forEach((textWord) => { + // Gets the bounds of the text word + var wordBounds = textWord.bounds; + // Gets the single word of extracted text from the PDF page + var word = textWord.text; + // Gets the collection of text glyphs extracted from a specified page in a PDF document + var glyphs = textWord.glyphs; + // Gets the name of the font used for a particular word + var wordFontName = textWord.fontName; + // Gets the style of the font used for a particular word + var wordFontStyle = textWord.fontStyle; + // Gets the size of the font used for a particular word + var wordFontSize = textWord.fontSize; + }); +}); +// Release document resources +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +### Working with words asynchronously This example demonstrates how to extract words from a PDF document using the [extractTextLines](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlines) method. Each line contains a collection of [TextWord](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textword) objects. @@ -312,8 +444,8 @@ import { PdfDataExtractor, TextLine, TextWord, TextGlyph, PdfFontStyle, Rectangl let document: PdfDocument = new PdfDocument(data); // Initialize a new instance of the `PdfDataExtractor` class let extractor: PdfDataExtractor = new PdfDataExtractor(document); -// Extract `TextLine` objects from the PDF document -let textLines: Array = extractor.extractTextLines({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); +// Extract `TextLine` objects from the PDF document asynchronously +let textLines: Array = await extractor.extractTextLines({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); textLines.forEach((textLine: TextLine) => { textLine.words.forEach((textWord: TextWord) => { // Gets the bounds of the text word @@ -340,8 +472,8 @@ document.destroy(); var document = new ej.pdf.PdfDocument(data); // Initialize a new instance of the `PdfDataExtractor` class var extractor = new ej.pdfdataextract.PdfDataExtractor(document); -// Extract `TextLine` objects from the PDF document -var textLines = extractor.extractTextLines({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); +// Extract `TextLine` objects from the PDF document asynchronously +var textLines = await extractor.extractTextLines({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); textLines.forEach((textLine) => { textLine.words.forEach((textWord) => { // Gets the bounds of the text word @@ -364,7 +496,80 @@ document.destroy(); {% endhighlight %} {% endtabs %} -### Working with characters +### Working with characters synchronously + +You can retrieve a single character and its properties, including bounds, font name, font size, and text color, using the [extractTextLinesSync](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlinessync) method. Refer to the code sample below. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} +import { PdfDocument, PdfColor, Rectangle } from '@syncfusion/ej2-pdf'; +import { PdfDataExtractor, TextLine, TextWord, TextGlyph, PdfFontStyle } from '@syncfusion/ej2-pdf-data-extract'; + +// Load an existing PDF document +let document: PdfDocument = new PdfDocument(data); +// Initialize a new instance of the `PdfDataExtractor` class +let extractor: PdfDataExtractor = new PdfDataExtractor(document); +// Extract `TextLine` objects from the PDF document synchronously +let textLines: Array = extractor.extractTextLinesSync({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); +textLines.forEach((textLine: TextLine) => { + textLine.words.forEach((textWord: TextWord) => { + textWord.glyphs.forEach((textGlyph: TextGlyph) => { + // Gets the bounds of the text glyph + let glyphBounds: Rectangle = textGlyph.bounds; + // Gets the single character of extracted text from the PDF page + let character: string = textGlyph.text; + // Gets the font size used for a particular character of the text + let fontSize: number = textGlyph.fontSize; + // Gets the name of the font used for a particular character of the text + let fontName: string = textGlyph.fontName; + // Gets the font style used for a particular character of the text + let fontStyle: PdfFontStyle = textGlyph.fontStyle; + // Gets the text color of the text glyph + let color: PdfColor = textGlyph.color; + // Gets the value indicating whether the glyph is rotated or not + let isRotated: boolean = textGlyph.isRotated; + }); + }); +}); +// Release document resources +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load an existing PDF document +var document = new ej.pdf.PdfDocument(data); +// Initialize a new instance of the `PdfDataExtractor` class +var extractor = new ej.pdfdataextract.PdfDataExtractor(document); +// Extract `TextLine` objects from the PDF document synchronously +var textLines = extractor.extractTextLinesSync({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); +textLines.forEach((textLine) => { + textLine.words.forEach((textWord) => { + textWord.glyphs.forEach((textGlyph) => { + // Gets the bounds of the text glyph + var glyphBounds = textGlyph.bounds; + // Gets the single character of extracted text from the PDF page + var character = textGlyph.text; + // Gets the font size used for a particular character of the text + var fontSize = textGlyph.fontSize; + // Gets the name of the font used for a particular character of the text + var fontName = textGlyph.fontName; + // Gets the font style used for a particular character of the text + var fontStyle = textGlyph.fontStyle; + // Gets the text color of the text glyph + var color = textGlyph.color; + // Gets the value indicating whether the glyph is rotated or not + var isRotated = textGlyph.isRotated; + }); + }); +}); +// Release document resources +document.destroy(); + +{% endhighlight %} +{% endtabs %} + +### Working with characters asynchronously You can retrieve a single character and its properties, including bounds, font name, font size, and text color, using the [extractTextLines](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlines) method. Refer to the code sample below. @@ -377,8 +582,8 @@ import { PdfDataExtractor, TextLine, TextWord, TextGlyph, PdfFontStyle } from '@ let document: PdfDocument = new PdfDocument(data); // Initialize a new instance of the `PdfDataExtractor` class let extractor: PdfDataExtractor = new PdfDataExtractor(document); -// Extract `TextLine` objects from the PDF document -let textLines: Array = extractor.extractTextLines({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); +// Extract `TextLine` objects from the PDF document asynchronously +let textLines: Array = await extractor.extractTextLines({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); textLines.forEach((textLine: TextLine) => { textLine.words.forEach((textWord: TextWord) => { textWord.glyphs.forEach((textGlyph: TextGlyph) => { @@ -409,8 +614,8 @@ document.destroy(); var document = new ej.pdf.PdfDocument(data); // Initialize a new instance of the `PdfDataExtractor` class var extractor = new ej.pdfdataextract.PdfDataExtractor(document); -// Extract `TextLine` objects from the PDF document -var textLines = extractor.extractTextLines({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); +// Extract `TextLine` objects from the PDF document asynchronously +var textLines = await extractor.extractTextLines({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); textLines.forEach((textLine) => { textLine.words.forEach((textWord) => { textWord.glyphs.forEach((textGlyph) => { From a1bcad3e485f55e78d218f9d35176a530ecf1480 Mon Sep 17 00:00:00 2001 From: "AzureAD\\DhakshinPrasathDhanr" Date: Thu, 3 Sep 2026 10:26:54 +0530 Subject: [PATCH 07/11] 1050196: Resolved CI failures --- Document-Processing-toc.html | 1 + .../PDF/PDF-Library/javascript/{PdfGrid.md => PDF-Grid.md} | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) rename Document-Processing/PDF/PDF-Library/javascript/{PdfGrid.md => PDF-Grid.md} (99%) diff --git a/Document-Processing-toc.html b/Document-Processing-toc.html index 09853e47c4..e533d988cc 100644 --- a/Document-Processing-toc.html +++ b/Document-Processing-toc.html @@ -3445,6 +3445,7 @@
  • Text
  • Lists
  • Images
  • +
  • Grids
  • Templates
  • Headers and Footers
  • Shapes
  • diff --git a/Document-Processing/PDF/PDF-Library/javascript/PdfGrid.md b/Document-Processing/PDF/PDF-Library/javascript/PDF-Grid.md similarity index 99% rename from Document-Processing/PDF/PDF-Library/javascript/PdfGrid.md rename to Document-Processing/PDF/PDF-Library/javascript/PDF-Grid.md index 1a9941b0e7..23289711af 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/PdfGrid.md +++ b/Document-Processing/PDF/PDF-Library/javascript/PDF-Grid.md @@ -798,7 +798,7 @@ document.destroy(); {% endhighlight %} {% endtabs %} -## Draw a borderless table +## Draw a border less table Use a zero-width border at grid level. From ad25eb2056bf744dac6ed8e6c6ee56112a045108 Mon Sep 17 00:00:00 2001 From: "AzureAD\\DhakshinPrasathDhanr" Date: Thu, 3 Sep 2026 14:11:18 +0530 Subject: [PATCH 08/11] 1050196: Added youtube link --- .../javascript/Create-PDF-document-angular.md | 6 + .../javascript/DigitalSignature.md | 155 ++++++++++++++++++ 2 files changed, 161 insertions(+) diff --git a/Document-Processing/PDF/PDF-Library/javascript/Create-PDF-document-angular.md b/Document-Processing/PDF/PDF-Library/javascript/Create-PDF-document-angular.md index 156584bbc1..1526e8258b 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/Create-PDF-document-angular.md +++ b/Document-Processing/PDF/PDF-Library/javascript/Create-PDF-document-angular.md @@ -15,6 +15,12 @@ The [JavaScript PDF Library](https://www.syncfusion.com/document-sdk/javascript- This guide explains how to integrate the [JavaScript PDF Library](https://www.syncfusion.com/document-sdk/javascript-pdf-library) into an Angular application that runs in the browser. The generated PDF is downloaded directly from the browser; no server-side PDF rendering is involved. +## Video Tutorial + +Watch the following video to learn how to create a PDF file in an Angular application using the JavaScript PDF Library. + +{% youtube "https://www.youtube.com/watch?v=cJHZz4k6fZM" %} + ## Prerequisites Before you begin, make sure you have the following installed: diff --git a/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md b/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md index d82e34b6bf..febe5d016d 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md +++ b/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md @@ -1237,6 +1237,161 @@ document.destroy(); {% endhighlight %} {% endtabs %} +## Digital signature validation + +The JavaScript PDF Library supports validating digital signatures in an existing PDF document. Digital signature validation verifies the following information to determine the validity of each signature: + +* Document modifications made after signing. +* The certificate chain against the provided trusted certificates. +* Timestamp information associated with the signature. +* Certificate revocation status using Online Certificate Status Protocol (OCSP) and Certificate Revocation List (CRL) information. +* Multiple digital signatures available in the PDF document. + +Use the `validateSignatures` method of `PdfForm` to validate the digital signatures in a PDF document. Configure the trusted certificates and their passwords using `PdfSignatureValidationOptions`. + +The `validateSignatures` method returns the overall validation status and the individual validation results. The `isValid` property indicates whether all the validated signatures are valid. The `results` property contains details such as the signature name, signature status, document modification status, and revocation result for each signature. + +The following code example shows how to validate the digital signatures in an existing PDF document. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfDocument, PdfSignatureValidationOptions } from '@syncfusion/ej2-pdf'; + +// Load the signed PDF document. +const document: PdfDocument = new PdfDocument(documentData); +// Configure the signature validation options. +const options: PdfSignatureValidationOptions = { + trustedCertificates: [certificateData], + passwords: ['syncfusion'] +}; +// Validate the digital signatures in the PDF document. +const validationResult = document.form.validateSignatures(options); +// Check the validation result of each signature. +if (validationResult.results !== null && + validationResult.results !== undefined) { + validationResult.results.forEach((result) => { + console.log('Signature name: ' + result.signatureName); + console.log('Signature valid: ' + result.isSignatureValid); + console.log('Signature status: ' + result.signatureStatus); + console.log('Document modified: ' + result.isDocumentModified); + console.log('Revocation result: ', result.revocationResult); + }); +} +// Get the overall signature validation status. +console.log('All signatures valid: ' + validationResult.isValid); +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load the signed PDF document. +const document = new ej.pdf.PdfDocument(documentData); +// Configure the signature validation options. +const options = { + trustedCertificates: [certificateData], + passwords: ['syncfusion'] +}; +// Validate the digital signatures in the PDF document. +const validationResult = document.form.validateSignatures(options); +// Check the validation result of each signature. +if (validationResult.results !== null && + validationResult.results !== undefined) { + validationResult.results.forEach((result) => { + console.log('Signature name: ' + result.signatureName); + console.log('Signature valid: ' + result.isSignatureValid); + console.log('Signature status: ' + result.signatureStatus); + console.log('Document modified: ' + result.isDocumentModified); + console.log('Revocation result: ', result.revocationResult); + }); +} +// Get the overall signature validation status. +console.log('All signatures valid: ' + validationResult.isValid); +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} + +{% endtabs %} + +## Validate all signatures in a PDF document + +You can validate all digital signatures in a PDF document by calling the `validateSignatures` method. The method validates every signature field in the document and returns the individual results through the `results` collection. + +The following code example shows how to validate all signatures and determine whether the complete PDF document has valid signatures. + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} + +import { PdfDocument, PdfSignatureValidationOptions } from '@syncfusion/ej2-pdf'; + +// Load the PDF document that contains multiple signatures. +const document: PdfDocument = new PdfDocument(documentData); +// Configure the validation options. +const options: PdfSignatureValidationOptions = { + trustedCertificates: [certificateData], + passwords: ['syncfusion'] +}; +// Validate all signatures in the PDF document. +const validationResult = document.form.validateSignatures(options); +if (validationResult.results !== null && + validationResult.results !== undefined) { + console.log( + 'Number of validated signatures: ' + + validationResult.results.length + ); + validationResult.results.forEach((result) => { + console.log( + `${result.signatureName}: ${result.isSignatureValid}` + ); + }); +} +// Determine whether all signatures are valid. +if (validationResult.isValid) { + console.log('All signatures in the PDF document are valid.'); +} else { + console.log('One or more signatures in the PDF document are invalid.'); +} +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Load the PDF document that contains multiple signatures. +const document = new PdfDocument(documentData); +// Configure the validation options. +const options = { + trustedCertificates: [certificateData], + passwords: ['syncfusion'] +}; +// Validate all signatures in the PDF document. +const validationResult = document.form.validateSignatures(options); +if (validationResult.results !== null && + validationResult.results !== undefined) { + console.log( + 'Number of validated signatures: ' + + validationResult.results.length + ); + validationResult.results.forEach((result) => { + console.log( + `${result.signatureName}: ${result.isSignatureValid}` + ); + }); +} +// Determine whether all signatures are valid. +if (validationResult.isValid) { + console.log('All signatures in the PDF document are valid.'); +} else { + console.log('One or more signatures in the PDF document are invalid.'); +} +// Destroy the document and release its resources. +document.destroy(); + +{% endhighlight %} +{% endtabs %} + ## Inspecting signatures The following examples demonstrate how to read information from existing signatures in a PDF document. From 5684e175ca65f5350f5e5b450e081ddfbbeafd7e Mon Sep 17 00:00:00 2001 From: "AzureAD\\DhakshinPrasathDhanr" Date: Fri, 4 Sep 2026 10:56:49 +0530 Subject: [PATCH 09/11] 1050196: Resolved review changes --- .../PDF/PDF-Library/javascript/Annotations.md | 238 +--------- .../javascript/DigitalSignature.md | 408 ++++++------------ .../PDF/PDF-Library/javascript/Encryption.md | 20 +- .../PDF/PDF-Library/javascript/Lists.md | 42 +- .../PDF-Library/javascript/Text-Extraction.md | 392 ++++------------- 5 files changed, 208 insertions(+), 892 deletions(-) diff --git a/Document-Processing/PDF/PDF-Library/javascript/Annotations.md b/Document-Processing/PDF/PDF-Library/javascript/Annotations.md index ba73e1d681..e8fec69372 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/Annotations.md +++ b/Document-Processing/PDF/PDF-Library/javascript/Annotations.md @@ -1021,11 +1021,7 @@ document.destroy(); ## Cloud Border Style Annotation -A cloud border style can be applied to rectangle, polygon, circle, and ellipse annotations in an existing PDF document by using the [PdfBorderEffect](https://ej2.syncfusion.com/documentation/api/pdf/pdfbordereffect) class. Set the `intensity` property to control the intensity of the cloud effect and set the `style` property to `PdfBorderEffectStyle.cloudy`. - -### PdfRectangleAnnotation - -A cloud border style can be applied to an existing [PdfRectangleAnnotation](https://ej2.syncfusion.com/documentation/api/pdf/pdfrectangleannotation) by using the [PdfBorderEffect](https://ej2.syncfusion.com/documentation/api/pdf/pdfbordereffect) class. +A cloud border style can be applied to rectangle, polygon, circle,ellipse and freeText annotations in an existing PDF document by using the [PdfBorderEffect](https://ej2.syncfusion.com/documentation/api/pdf/pdfbordereffect) class. Set the `intensity` property to control the intensity of the cloud effect and set the `style` property to `PdfBorderEffectStyle.cloudy`. The following code example demonstrates how to apply a cloud border style to an existing rectangle annotation in a PDF document. @@ -1078,238 +1074,6 @@ document.destroy(); {% endhighlight %} {% endtabs %} -### PdfPolygonAnnotation - -A cloud border style can be applied to an existing [PdfPolygonAnnotation](https://ej2.syncfusion.com/documentation/api/pdf/pdfpolygonannotation) by using the [PdfBorderEffect](https://ej2.syncfusion.com/documentation/api/pdf/pdfbordereffect) class. - -The following code example demonstrates how to apply a cloud border style to an existing polygon annotation in a PDF document. - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import {PdfBorderEffect, PdfBorderEffectStyle, PdfDocument, PdfPage, PdfPolygonAnnotation} from '@syncfusion/ej2-pdf'; - -// Load an existing PDF document -let document: PdfDocument = new PdfDocument(data, password); -// Get the first page -let page: PdfPage = document.getPage(0) as PdfPage; -// Get the first polygon annotation of the page -let annotation: PdfPolygonAnnotation = page.annotations.at(0) as PdfPolygonAnnotation; -// Initialize a new instance of the `PdfBorderEffect` class -let borderEffect: PdfBorderEffect = new PdfBorderEffect(); -// Set the intensity of the annotation border -borderEffect.intensity = 2; -// Set the cloud style of the annotation border -borderEffect.style = PdfBorderEffectStyle.cloudy; -// Set the border effect to the annotation -annotation.borderEffect = borderEffect; -// Save the document -document.save('Output.pdf'); -// Destroy the document -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -// Load an existing PDF document -var document = new ej.pdf.PdfDocument(data, password); -// Get the first page -var page = document.getPage(0); -// Get the first polygon annotation of the page -var annotation = page.annotations.at(0); -// Initialize a new instance of the PdfBorderEffect class -var borderEffect = new ej.pdf.PdfBorderEffect(); -// Set the intensity of the annotation border -borderEffect.intensity = 2; -// Set the cloud style of the annotation border -borderEffect.style = ej.pdf.PdfBorderEffectStyle.cloudy; -// Set the border effect to the annotation -annotation.borderEffect = borderEffect; -// Save the document -document.save('Output.pdf'); -// Destroy the document -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -### PdfCircleAnnotation - -A cloud border style can be applied to an existing [PdfCircleAnnotation](https://ej2.syncfusion.com/documentation/api/pdf/pdfcircleannotation) by using the [PdfBorderEffect](https://ej2.syncfusion.com/documentation/api/pdf/pdfbordereffect) class. - -The following code example demonstrates how to apply a cloud border style to an existing circle annotation in a PDF document. - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import {PdfBorderEffect, PdfBorderEffectStyle, PdfCircleAnnotation, PdfDocument, PdfPage} from '@syncfusion/ej2-pdf'; - -// Load an existing PDF document -let document: PdfDocument = new PdfDocument(data, password); -// Get the first page -let page: PdfPage = document.getPage(0) as PdfPage; -// Get the first circle annotation of the page -let annotation: PdfCircleAnnotation = page.annotations.at(0) as PdfCircleAnnotation; -// Initialize a new instance of the `PdfBorderEffect` class -let borderEffect: PdfBorderEffect = new PdfBorderEffect(); -// Set the intensity of the annotation border -borderEffect.intensity = 2; -// Set the cloud style of the annotation border -borderEffect.style = PdfBorderEffectStyle.cloudy; -// Set the border effect to the annotation -annotation.borderEffect = borderEffect; -// Generate the annotation appearance -annotation.setAppearance(true); -// Save the document -document.save('Output.pdf'); -// Destroy the document -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -// Load an existing PDF document -var document = new ej.pdf.PdfDocument(data, password); -// Get the first page -var page = document.getPage(0); -// Get the first circle annotation of the page -var annotation = page.annotations.at(0); -// Initialize a new instance of the PdfBorderEffect class -var borderEffect = new ej.pdf.PdfBorderEffect(); -// Set the intensity of the annotation border -borderEffect.intensity = 2; -// Set the cloud style of the annotation border -borderEffect.style = ej.pdf.PdfBorderEffectStyle.cloudy; -// Set the border effect to the annotation -annotation.borderEffect = borderEffect; -// Generate the annotation appearance -annotation.setAppearance(true); -// Save the document -document.save('Output.pdf'); -// Destroy the document -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -### PdfEllipseAnnotation - -A cloud border style can be applied to an existing [PdfEllipseAnnotation](https://ej2.syncfusion.com/documentation/api/pdf/pdfellipseannotation) by using the [PdfBorderEffect](https://ej2.syncfusion.com/documentation/api/pdf/pdfbordereffect) class. - -The following code example demonstrates how to apply a cloud border style to an existing ellipse annotation in a PDF document. - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import {PdfBorderEffect, PdfBorderEffectStyle, PdfDocument, PdfEllipseAnnotation, PdfPage} from '@syncfusion/ej2-pdf'; - -// Load an existing PDF document -let document: PdfDocument = new PdfDocument(data, password); -// Get the first page -let page: PdfPage = document.getPage(0) as PdfPage; -// Get the first ellipse annotation of the page -let annotation: PdfEllipseAnnotation = page.annotations.at(0) as PdfEllipseAnnotation; -// Initialize a new instance of the `PdfBorderEffect` class -let borderEffect: PdfBorderEffect = new PdfBorderEffect(); -// Set the intensity of the annotation border -borderEffect.intensity = 2; -// Set the cloud style of the annotation border -borderEffect.style = PdfBorderEffectStyle.cloudy; -// Set the border effect to the annotation -annotation.borderEffect = borderEffect; -// Generate the annotation appearance -annotation.setAppearance(true); -// Save the document -document.save('Output.pdf'); -// Destroy the document -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -// Load an existing PDF document -var document = new ej.pdf.PdfDocument(data, password); -// Get the first page -var page = document.getPage(0); -// Get the first ellipse annotation of the page -var annotation = page.annotations.at(0); -// Initialize a new instance of the PdfBorderEffect class -var borderEffect = new ej.pdf.PdfBorderEffect(); -// Set the intensity of the annotation border -borderEffect.intensity = 2; -// Set the cloud style of the annotation border -borderEffect.style = ej.pdf.PdfBorderEffectStyle.cloudy; -// Set the border effect to the annotation -annotation.borderEffect = borderEffect; -// Generate the annotation appearance -annotation.setAppearance(true); -// Save the document -document.save('Output.pdf'); -// Destroy the document -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -### PdfFreeTextAnnotation - -A cloud border style can be applied to an existing [PdfFreeTextAnnotation](https://ej2.syncfusion.com/documentation/api/pdf/pdffreetextannotation) by using the [PdfBorderEffect](https://ej2.syncfusion.com/documentation/api/pdf/pdfbordereffect) class. - -The following code example demonstrates how to apply a cloud border style to an existing free text annotation in a PDF document. - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfBorderEffect, PdfBorderEffectStyle, PdfDocument, PdfFreeTextAnnotation, PdfPage } from '@syncfusion/ej2-pdf'; - -// Load an existing PDF document -let document: PdfDocument = new PdfDocument(data, password); -// Get the first page -let page: PdfPage = document.getPage(0) as PdfPage; -// Get the first free text annotation of the page -let annotation: PdfFreeTextAnnotation = page.annotations.at(0) as PdfFreeTextAnnotation; -// Initialize a new instance of the `PdfBorderEffect` class -let borderEffect: PdfBorderEffect = new PdfBorderEffect(); -// Set the intensity of the annotation border -borderEffect.intensity = 2; -// Set the cloud style of the annotation border -borderEffect.style = PdfBorderEffectStyle.cloudy; -// Set the border effect to the annotation -annotation.borderEffect = borderEffect; -// Generate the annotation appearance -annotation.setAppearance(true); -// Save the document -document.save('Output.pdf'); -// Destroy the document -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -// Load an existing PDF document -var document = new ej.pdf.PdfDocument(data, password); -// Get the first page -var page = document.getPage(0); -// Get the first free text annotation of the page -var annotation = page.annotations.at(0); -// Initialize a new instance of the PdfBorderEffect class -var borderEffect = new ej.pdf.PdfBorderEffect(); -// Set the intensity of the annotation border -borderEffect.intensity = 2; -// Set the cloud style of the annotation border -borderEffect.style = ej.pdf.PdfBorderEffectStyle.cloudy; -// Set the border effect to the annotation -annotation.borderEffect = borderEffect; -// Generate the annotation appearance -annotation.setAppearance(true); -// Save the document -document.save('Output.pdf'); -// Destroy the document -document.destroy(); - -{% endhighlight %} -{% endtabs %} - ## Custom appearance in stamp annotation This example demonstrates how to embed a custom image as the appearance of a rubber stamp annotation. diff --git a/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md b/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md index febe5d016d..2e221e6166 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md +++ b/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md @@ -424,70 +424,106 @@ N> The two-step process is required when the signing operation cannot complete i ## Long-Term Validation (LTV) -The JavaScript PDF Library supports Long-Term Validation for digital signatures through the [`enableLTV()`](https://ej2.syncfusion.com/documentation/api/pdf/pdfsignature#enableltv) method of the `PdfSignature` class. LTV helps preserve signature validity by embedding revocation information such as OCSP and CRL responses into the document. +The JavaScript PDF Library supports Long-Term Validation for digital signatures through the [enableLTV()](https://ej2.syncfusion.com/documentation/api/pdf/pdfsignature#enableltv) method of the `PdfSignature` class. LTV helps preserve signature validity by embedding revocation information such as OCSP and CRL responses into the document. + +### Enable Long Term Validation (LTV) PDF signature + +The JavaScript PDF Library supports creating long-term signature validation while digitally signing a PDF document. LTV allows the signature to be validated long after the document was signed by embedding the required certificate and revocation information in the PDF document. + +The following code example explains how to create a digital signature and enable LTV using the [enableLTV()](https://ej2.syncfusion.com/documentation/api/pdf/pdfsignature#enableltv) method of the [PdfSignature](https://ej2.syncfusion.com/documentation/api/pdf/pdfsignature) class. + + +{% tabs %} +{% highlight typescript tabtitle="TypeScript" %} +import { PdfDocument, PdfPage, PdfForm, PdfSignatureField, PdfSignature, DigestAlgorithm, CryptographicStandard } from '@syncfusion/ej2-pdf'; + +// Create a new PDF document +let document: PdfDocument = new PdfDocument(); +// Add a new page to the document +let page: PdfPage = document.addPage(); +// Access the PDF form +let form: PdfForm = document.form; +// Create a new signature field +let field: PdfSignatureField = new PdfSignatureField(page, 'Signature', { x: 10, y: 10, width: 100, height: 50 }); +// Create a digital signature using PFX data and a private key +let signature: PdfSignature = PdfSignature.create(certData, password, { cryptographicStandard: CryptographicStandard.cms, digestAlgorithm: DigestAlgorithm.sha256 }); +// Set the signature to the field +field.setSignature(signature); +// Add the signature field to the PDF form +form.add(field); +// Retrieve the OCSP or CRL response requested by the library +async function longTermValidationCallback(url: string, requestBytes?: Uint8Array): Promise<{ response: Uint8Array }> { + // Send requestBytes to the supplied URL and return the actual response bytes + return { response: new Uint8Array() }; +} +// Enable LTV for the created signature +let ltvEnabled: boolean = await signature.enableLTV(longTermValidationCallback); +// Save the document +document.save('output.pdf'); +// Destroy the document +document.destroy(); + +{% endhighlight %} +{% highlight javascript tabtitle="JavaScript" %} + +// Create a new PDF document +var document = new ej.pdf.PdfDocument(); +// Add a new page to the document +var page = document.addPage(); +// Access the PDF form +var form = document.form; +// Create a new signature field +var field = new ej.pdf.PdfSignatureField(page, 'Signature', { x: 10, y: 10, width: 100, height: 50 }); +// Create a digital signature using PFX data and a private key +var signature = ej.pdf.PdfSignature.create(certData, password, { cryptographicStandard: ej.pdf.CryptographicStandard.cms, digestAlgorithm: ej.pdf.DigestAlgorithm.sha256 }); +// Set the signature to the field +field.setSignature(signature); +// Add the signature field to the PDF form +form.add(field); +// Retrieve the OCSP or CRL response requested by the library +var longTermValidationCallback = async function (url, requestBytes) { + // Send requestBytes to the supplied URL and return the actual response bytes + return { response: new Uint8Array() }; +}; +// Enable LTV for the created signature +var ltvEnabled = await signature.enableLTV(longTermValidationCallback); +// Save the document +document.save('output.pdf'); +// Destroy the document +document.destroy(); + +{% endhighlight %} +{% endtabs %} + ### Create Long Term Validation (LTV) when signing PDF documents externally -You can create Long Term Validation (LTV) after externally signing a PDF document by using your public certificate chain. The following code example shows how to complete the external signing process and enable LTV using the [`enableLTV()`](https://ej2.syncfusion.com/documentation/api/pdf/pdfsignature#enableltv) method of the [`PdfSignature`](https://ej2.syncfusion.com/documentation/api/pdf/pdfsignature) class. +You can create Long Term Validation (LTV) after externally signing a PDF document by using the public certificate chain. The PDF document must first be signed and saved. Then, reload the signed document, retrieve the created signature, and call the [enableLTV()](https://ej2.syncfusion.com/documentation/api/pdf/pdfsignature#enableltv) method of the [`PdfSignature`](https://ej2.syncfusion.com/documentation/api/pdf/pdfsignature) class to embed the required revocation information. The callback supplied to `enableLTV()` must retrieve the actual OCSP or CRL response requested by the library and return the response bytes as a `Uint8Array`. + {% tabs %} {% highlight typescript tabtitle="TypeScript" %} -import { - PdfDocument, - PdfPage, - PdfSignatureField, - PdfSignature, - PdfSignatureOptions, - DigestAlgorithm, - CryptographicStandard, - RevocationType -} from '@syncfusion/ej2-pdf'; +import { PdfDocument, PdfPage, PdfSignatureField, PdfSignature, DigestAlgorithm, CryptographicStandard, RevocationType } from '@syncfusion/ej2-pdf'; // Define a callback function for external signing -function externalSignatureCallback( - data: Uint8Array, - options: { - algorithm: DigestAlgorithm, - cryptographicStandard: CryptographicStandard - } -): { signedData: Uint8Array; timestampData?: Uint8Array } { +function externalSignatureCallback(data: Uint8Array, options: { algorithm: DigestAlgorithm, cryptographicStandard: CryptographicStandard }): { signedData: Uint8Array; timestampData?: Uint8Array } { // Sign the supplied document data using an external signing service return { signedData: externalSignedData }; } - // Define a callback function to retrieve OCSP or CRL responses -async function longTermValidationCallback( - url: string, - requestBytes?: Uint8Array -): Promise<{ response: Uint8Array }> { +async function longTermValidationCallback(url: string, requestBytes?: Uint8Array): Promise<{ response: Uint8Array }> { // Send requestBytes to the supplied URL and return the actual OCSP or CRL response return { response: revocationResponse }; } - // Create a new PDF document let document: PdfDocument = new PdfDocument(); -// Add a page to the document +// Add a new page to the document let page: PdfPage = document.addPage(); // Create a signature field -let field: PdfSignatureField = new PdfSignatureField( - page, - 'field', - { x: 50, y: 50, width: 100, height: 100 } -); - +let field: PdfSignatureField = new PdfSignatureField(page, 'Signature', { x: 50, y: 50, width: 100, height: 100 }); // Create a signature using the external-signing callback -let signature: PdfSignature = PdfSignature.create( - externalSignatureCallback, - { - cryptographicStandard: CryptographicStandard.cms, - digestAlgorithm: DigestAlgorithm.sha256, - contactInfo: 'johndoe@owned.us', - locationInfo: 'Honolulu, Hawaii', - reason: 'I am author of this document.', - signedName: 'Signature' - } -); +let signature: PdfSignature = PdfSignature.create(externalSignatureCallback, { cryptographicStandard: CryptographicStandard.cms, digestAlgorithm: DigestAlgorithm.sha256, contactInfo: 'johndoe@owned.us', locationInfo: 'Honolulu, Hawaii', reason: 'I am author of this document.', signedName: 'Signature' }); // Add the signature field to the PDF form document.form.add(field); // Set the signature to the field @@ -499,29 +535,16 @@ document.destroy(); // Load the externally signed PDF document document = new PdfDocument(data); -// Get the existing signature field +// Get the created signature field field = document.form.fieldAt(0) as PdfSignatureField; -// Get the existing signature +// Get the created signature signature = field.getSignature(); -// Get the signature options -let options: PdfSignatureOptions = signature.getSignatureOptions(); - -// Public certificate chain used for long-term validation -let publicCertificates: Uint8Array[] = [ - publicCertificate1, - publicCertificate2 -]; - +// Define the public certificate chain used for long-term validation +let publicCertificates: Uint8Array[] = [publicCertificate1, publicCertificate2]; // Enable LTV using the available OCSP or CRL response -let ltvEnabled: boolean = await signature.enableLTV( - publicCertificates, - RevocationType.ocspOrCrl, - longTermValidationCallback -); -if (ltvEnabled) { - // Save the LTV-enabled PDF document - document.save('output.pdf'); -} +let ltvEnabled: boolean = await signature.enableLTV(publicCertificates, RevocationType.ocspOrCrl, longTermValidationCallback); +// Save the LTV-enabled PDF document +document.save('output.pdf'); // Destroy the document document.destroy(); @@ -533,36 +556,19 @@ function externalSignatureCallback(data, options) { // Sign the supplied document data using an external signing service return { signedData: externalSignedData }; } - // Define a callback function to retrieve OCSP or CRL responses async function longTermValidationCallback(url, requestBytes) { // Send requestBytes to the supplied URL and return the actual OCSP or CRL response return { response: revocationResponse }; } - // Create a new PDF document var document = new ej.pdf.PdfDocument(); -// Add a page to the document +// Add a new page to the document var page = document.addPage(); // Create a signature field -var field = new ej.pdf.PdfSignatureField( - page, - 'field', - { x: 50, y: 50, width: 100, height: 100 } -); - +var field = new ej.pdf.PdfSignatureField(page, 'Signature', { x: 50, y: 50, width: 100, height: 100 }); // Create a signature using the external-signing callback -var signature = ej.pdf.PdfSignature.create( - externalSignatureCallback, - { - cryptographicStandard: ej.pdf.CryptographicStandard.cms, - digestAlgorithm: ej.pdf.DigestAlgorithm.sha256, - contactInfo: 'johndoe@owned.us', - locationInfo: 'Honolulu, Hawaii', - reason: 'I am author of this document.', - signedName: 'Signature' - } -); +var signature = ej.pdf.PdfSignature.create(externalSignatureCallback, { cryptographicStandard: ej.pdf.CryptographicStandard.cms, digestAlgorithm: ej.pdf.DigestAlgorithm.sha256, contactInfo: 'johndoe@owned.us', locationInfo: 'Honolulu, Hawaii', reason: 'I am author of this document.', signedName: 'Signature' }); // Add the signature field to the PDF form document.form.add(field); // Set the signature to the field @@ -574,175 +580,52 @@ document.destroy(); // Load the externally signed PDF document document = new ej.pdf.PdfDocument(data); -// Get the existing signature field +// Get the created signature field field = document.form.fieldAt(0); -// Get the existing signature +// Get the created signature signature = field.getSignature(); -// Get the signature options -var options = signature.getSignatureOptions(); - -// Public certificate chain used for long-term validation -var publicCertificates = [ - publicCertificate1, - publicCertificate2 -]; - +// Define the public certificate chain used for long-term validation +var publicCertificates = [publicCertificate1, publicCertificate2]; // Enable LTV using the available OCSP or CRL response -var ltvEnabled = await signature.enableLTV( - publicCertificates, - ej.pdf.RevocationType.ocspOrCrl, - longTermValidationCallback -); -if (ltvEnabled) { - // Save the LTV-enabled PDF document - document.save('output.pdf'); -} -// Destroy the document -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -N> An empty `Uint8Array` is only a placeholder. The callback must return the actual OCSP or CRL response received from the supplied revocation service URL. - -### Enable Long Term Validation (LTV) PDF signature - -The JavaScript PDF Library supports creating long-term signature validation for a signed PDF document. LTV allows a signature to be validated long after the document was signed by embedding the required certificate and revocation information in the PDF document. - -N> The resulting PDF document can be larger because the certificate chain, Certificate Revocation List (CRL), Online Certificate Status Protocol (OCSP) responses, and related validation information can be embedded in the Document Security Store (DSS). - -The following code example explains how to enable LTV for an existing signature using the [`enableLTV()`](https://ej2.syncfusion.com/documentation/api/pdf/pdfsignature#enableltv) method of the [`PdfSignature`](https://ej2.syncfusion.com/documentation/api/pdf/pdfsignature) class. - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} -import { - PdfDocument, - PdfForm, - PdfSignatureField, - PdfSignature -} from '@syncfusion/ej2-pdf'; - -// Load the existing signed PDF document -let document: PdfDocument = new PdfDocument(data); -// Access the PDF form -let form: PdfForm = document.form; -// Get the existing signature field -let field: PdfSignatureField = form.fieldAt(0) as PdfSignatureField; -// Get the existing signature -let signature: PdfSignature = field.getSignature(); - -// Retrieve the OCSP or CRL response requested by the library -async function longTermValidationCallback( - url: string, - requestBytes?: Uint8Array -): Promise<{ response: Uint8Array }> { - // Send requestBytes to the supplied URL and return the actual response bytes - return { response: new Uint8Array() }; -} - -// Enable LTV for the existing signature -let ltvEnabled: boolean = await signature.enableLTV(longTermValidationCallback); -if (ltvEnabled) { - // Save the LTV-enabled PDF document - document.save('output.pdf'); -} -// Destroy the document -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -// Load the existing signed PDF document -var document = new ej.pdf.PdfDocument(data); -// Access the PDF form -var form = document.form; -// Get the existing signature field -var field = form.fieldAt(0); -// Get the existing signature -var signature = field.getSignature(); - -// Retrieve the OCSP or CRL response requested by the library -var longTermValidationCallback = async function (url, requestBytes) { - // Send requestBytes to the supplied URL and return the actual response bytes - return { response: new Uint8Array() }; -}; - -// Enable LTV for the existing signature -var ltvEnabled = await signature.enableLTV(longTermValidationCallback); -if (ltvEnabled) { - // Save the LTV-enabled PDF document - document.save('output.pdf'); -} +var ltvEnabled = await signature.enableLTV(publicCertificates, ej.pdf.RevocationType.ocspOrCrl, longTermValidationCallback); +// Save the LTV-enabled PDF document +document.save('output.pdf'); // Destroy the document document.destroy(); {% endhighlight %} {% endtabs %} -N> Enable LTV only after the target signature has been created or loaded from the PDF document. - -N> When a PDF document contains multiple signatures, call `enableLTV()` for each signature that requires long-term validation. +N> Enable LTV only after the externally signed PDF document has been saved and the created signature has been loaded from the document. When a PDF document contains multiple signatures, call `enableLTV()` for each signature that requires long-term validation. ### Enable Long Term Validation (LTV) with public certificates -You can provide the public certificate chain, select the revocation mode, and specify whether the certificates must be included in the PDF document while enabling LTV. +You can provide the public certificate chain while enabling LTV for an externally signed PDF document. The PDF document must first be signed and saved. Then, reload the signed document, retrieve the created signature, and call `enableLTV()` with the public certificates and the callback that returns the requested OCSP or CRL response. + +The following code example creates an external signature, reloads the signed PDF document, and enables LTV using the supplied public certificate chain. -The following code example uses CRL-based revocation information and includes the supplied public certificates in the document. {% tabs %} {% highlight typescript tabtitle="TypeScript" %} -import { - PdfDocument, - PdfPage, - PdfSignatureField, - PdfSignature, - DigestAlgorithm, - CryptographicStandard -} from '@syncfusion/ej2-pdf'; +import { PdfDocument, PdfPage, PdfSignatureField, PdfSignature, DigestAlgorithm, CryptographicStandard } from '@syncfusion/ej2-pdf'; // Define a callback function for external signing -function externalSignatureCallback( - data: Uint8Array, - options: { - algorithm: DigestAlgorithm, - cryptographicStandard: CryptographicStandard - } -): { signedData: Uint8Array; timestampData?: Uint8Array } { +function externalSignatureCallback(data: Uint8Array, options: { algorithm: DigestAlgorithm, cryptographicStandard: CryptographicStandard }): { signedData: Uint8Array; timestampData?: Uint8Array } { // Sign the supplied document data using an external signing service return { signedData: externalSignedData }; } - -// Define a callback function to retrieve OCSP and CRL responses -async function longTermValidationCallback( - url: string, - requestBytes?: Uint8Array -): Promise<{ response: Uint8Array }> { +// Define a callback function to retrieve OCSP or CRL responses +async function longTermValidationCallback(url: string, requestBytes?: Uint8Array): Promise<{ response: Uint8Array }> { // Send requestBytes to the supplied URL and return the actual OCSP or CRL response return { response: revocationResponse }; } - // Create a new PDF document let document: PdfDocument = new PdfDocument(); -// Add a page to the document +// Add a new page to the document let page: PdfPage = document.addPage(); // Create a signature field -let field: PdfSignatureField = new PdfSignatureField( - page, - 'field', - { x: 50, y: 50, width: 100, height: 100 } -); - +let field: PdfSignatureField = new PdfSignatureField(page, 'Signature', { x: 50, y: 50, width: 100, height: 100 }); // Create a signature using the external-signing callback -let signature: PdfSignature = PdfSignature.create( - externalSignatureCallback, - { - cryptographicStandard: CryptographicStandard.cms, - digestAlgorithm: DigestAlgorithm.sha1, - contactInfo: 'johndoe@owned.us', - locationInfo: 'Honolulu, Hawaii', - reason: 'I am author of this document.', - signedName: 'Signature' - } -); +let signature: PdfSignature = PdfSignature.create(externalSignatureCallback, { cryptographicStandard: CryptographicStandard.cms, digestAlgorithm: DigestAlgorithm.sha256, contactInfo: 'johndoe@owned.us', locationInfo: 'Honolulu, Hawaii', reason: 'I am author of this document.', signedName: 'Signature' }); // Add the signature field to the PDF form document.form.add(field); // Set the signature to the field @@ -754,26 +637,16 @@ document.destroy(); // Load the externally signed PDF document document = new PdfDocument(data); -// Get the existing signature field +// Get the created signature field field = document.form.fieldAt(0) as PdfSignatureField; -// Get the existing signature +// Get the created signature signature = field.getSignature(); - -// Public certificate chain used for long-term validation -let publicCertificates: Uint8Array[] = [ - publicCertificate1, - publicCertificate2 -]; - +// Define the public certificate chain used for long-term validation +let publicCertificates: Uint8Array[] = [publicCertificate1, publicCertificate2]; // Enable LTV using the public certificate chain -let ltvEnabled: boolean = await signature.enableLTV( - publicCertificates, - longTermValidationCallback -); -if (ltvEnabled) { - // Save the LTV-enabled PDF document - document.save('output.pdf'); -} +let ltvEnabled: boolean = await signature.enableLTV(publicCertificates, longTermValidationCallback); +// Save the LTV-enabled PDF document +document.save('output.pdf'); // Destroy the document document.destroy(); @@ -785,36 +658,19 @@ function externalSignatureCallback(data, options) { // Sign the supplied document data using an external signing service return { signedData: externalSignedData }; } - -// Define a callback function to retrieve OCSP and CRL responses +// Define a callback function to retrieve OCSP or CRL responses async function longTermValidationCallback(url, requestBytes) { // Send requestBytes to the supplied URL and return the actual OCSP or CRL response return { response: revocationResponse }; } - // Create a new PDF document var document = new ej.pdf.PdfDocument(); -// Add a page to the document +// Add a new page to the document var page = document.addPage(); // Create a signature field -var field = new ej.pdf.PdfSignatureField( - page, - 'field', - { x: 50, y: 50, width: 100, height: 100 } -); - +var field = new ej.pdf.PdfSignatureField(page, 'Signature', { x: 50, y: 50, width: 100, height: 100 }); // Create a signature using the external-signing callback -var signature = ej.pdf.PdfSignature.create( - externalSignatureCallback, - { - cryptographicStandard: ej.pdf.CryptographicStandard.cms, - digestAlgorithm: ej.pdf.DigestAlgorithm.sha1, - contactInfo: 'johndoe@owned.us', - locationInfo: 'Honolulu, Hawaii', - reason: 'I am author of this document.', - signedName: 'Signature' - } -); +var signature = ej.pdf.PdfSignature.create(externalSignatureCallback, { cryptographicStandard: ej.pdf.CryptographicStandard.cms, digestAlgorithm: ej.pdf.DigestAlgorithm.sha256, contactInfo: 'johndoe@owned.us', locationInfo: 'Honolulu, Hawaii', reason: 'I am author of this document.', signedName: 'Signature' }); // Add the signature field to the PDF form document.form.add(field); // Set the signature to the field @@ -826,35 +682,23 @@ document.destroy(); // Load the externally signed PDF document document = new ej.pdf.PdfDocument(data); -// Get the existing signature field +// Get the created signature field field = document.form.fieldAt(0); -// Get the existing signature +// Get the created signature signature = field.getSignature(); - -// Public certificate chain used for long-term validation -var publicCertificates = [ - publicCertificate1, - publicCertificate2 -]; - +// Define the public certificate chain used for long-term validation +var publicCertificates = [publicCertificate1, publicCertificate2]; // Enable LTV using the public certificate chain -var ltvEnabled = await signature.enableLTV( - publicCertificates, - longTermValidationCallback -); -if (ltvEnabled) { - // Save the LTV-enabled PDF document - document.save('output.pdf'); -} +var ltvEnabled = await signature.enableLTV(publicCertificates, longTermValidationCallback); +// Save the LTV-enabled PDF document +document.save('output.pdf'); // Destroy the document document.destroy(); {% endhighlight %} {% endtabs %} -N> Network communication, authentication, request headers, proxy configuration, and cross-origin access must be handled by the application that implements the callback. - -N> Invalid, empty, or unrelated response bytes may prevent the library from creating valid LTV information. +N> The callback must return the actual OCSP or CRL response received from the supplied revocation service URL. Placeholder or empty response bytes do not provide long-term validation. ## Signature options diff --git a/Document-Processing/PDF/PDF-Library/javascript/Encryption.md b/Document-Processing/PDF/PDF-Library/javascript/Encryption.md index 337ba90949..7b6b15a623 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/Encryption.md +++ b/Document-Processing/PDF/PDF-Library/javascript/Encryption.md @@ -192,15 +192,7 @@ const document: PdfDocument = new PdfDocument(inputData, 'password'); const options: PdfSecurityOptions = { userPassword: '', ownerPassword: '', - permissions: PdfPermissionFlag.print | - PdfPermissionFlag.copyContent | - PdfPermissionFlag.editContent | - PdfPermissionFlag.editAnnotations | - PdfPermissionFlag.fillFields | - PdfPermissionFlag.accessibilityCopyContent | - PdfPermissionFlag.assembleDocument | - PdfPermissionFlag.fullQualityPrint -}; + permissions: PdfPermissionFlag.default}; document.setSecurity(options); // Save the decrypted PDF document. document.save('Output.pdf'); @@ -216,15 +208,7 @@ const document = new ej.pdf.PdfDocument(inputData, 'password'); document.setSecurity({ userPassword: '', ownerPassword: '', - permissions: ej.pdf.PdfPermissionFlag.print | - ej.pdf.PdfPermissionFlag.copyContent | - ej.pdf.PdfPermissionFlag.editContent | - ej.pdf.PdfPermissionFlag.editAnnotations | - ej.pdf.PdfPermissionFlag.fillFields | - ej.pdf.PdfPermissionFlag.accessibilityCopyContent | - ej.pdf.PdfPermissionFlag.assembleDocument | - ej.pdf.PdfPermissionFlag.fullQualityPrint -}); + permissions: ej.pdf.PdfPermissionFlag.default}); // Save the decrypted PDF document. document.save('Output.pdf'); // Destroy the document and release its resources. diff --git a/Document-Processing/PDF/PDF-Library/javascript/Lists.md b/Document-Processing/PDF/PDF-Library/javascript/Lists.md index 73274e2ead..a8a9353721 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/Lists.md +++ b/Document-Processing/PDF/PDF-Library/javascript/Lists.md @@ -156,39 +156,22 @@ The following code example shows how to create a PDF document, add an unordered {% tabs %} {% highlight typescript tabtitle="TypeScript" %} -import { - PdfBitmap, - PdfDocument, - PdfImageMarker, - PdfListItemCollection, - PdfUnorderedList -} from '@syncfusion/ej2-pdf'; +import { PdfBitmap, PdfDocument, PdfImageMarker, PdfListItemCollection, PdfUnorderedList } from '@syncfusion/ej2-pdf'; // Create a new PDF document. const document: PdfDocument = new PdfDocument(); // Add a new page to the document. const page = document.addPage(); // Create the items for the unordered list. -const items: PdfListItemCollection = new PdfListItemCollection([ - 'Essential PDF', - 'Essential DocIO', - 'Essential XlsIO' -]); +const items: PdfListItemCollection = new PdfListItemCollection([ 'Essential PDF', 'Essential DocIO', 'Essential XlsIO']); // Create an unordered list. const unorderedList: PdfUnorderedList = new PdfUnorderedList(items); // Create an image marker using the loaded image. -const imageMarker: PdfImageMarker = { - image: new PdfBitmap(imageData) -}; +const imageMarker: PdfImageMarker = {image: new PdfBitmap(imageData)}; // Set the image as the marker for the unordered list. unorderedList.setMarker(imageMarker); // Draw the unordered list on the PDF page. -unorderedList.draw(page, { - x: 10, - y: 20, - width: page.graphics.clientSize.width - 20, - height: page.graphics.clientSize.height - 40 -}); +unorderedList.draw(page, { x: 10,y: 20, width: page.graphics.clientSize.width - 20, height: page.graphics.clientSize.height - 40}); // Save the PDF document. document.save('SetImageMarker.pdf'); // Destroy the document and release its resources. @@ -202,26 +185,15 @@ const document = new ej.pdf.PdfDocument(); // Add a new page to the document. const page = document.addPage(); // Create the items for the unordered list. -const items = new ej.pdf.PdfListItemCollection([ - 'Essential PDF', - 'Essential DocIO', - 'Essential XlsIO' -]); +const items = new ej.pdf.PdfListItemCollection([ 'Essential PDF', 'Essential DocIO', 'Essential XlsIO']); // Create an unordered list. const unorderedList = new ej.pdf.PdfUnorderedList(items); // Create an image marker using the loaded image. -const imageMarker = { - image: new ej.pdf.PdfBitmap(imageData) -}; +const imageMarker = { image: new ej.pdf.PdfBitmap(imageData)}; // Set the image as the marker for the unordered list. unorderedList.setMarker(imageMarker); // Draw the unordered list on the PDF page. -unorderedList.draw(page, { - x: 10, - y: 20, - width: page.graphics.clientSize.width - 20, - height: page.graphics.clientSize.height - 40 -}); +unorderedList.draw(page, {x: 10, y: 20, width: page.graphics.clientSize.width - 20, height: page.graphics.clientSize.height - 40 }); // Save the PDF document. document.save('SetImageMarker.pdf'); // Destroy the document and release its resources. diff --git a/Document-Processing/PDF/PDF-Library/javascript/Text-Extraction.md b/Document-Processing/PDF/PDF-Library/javascript/Text-Extraction.md index 5eb3114ce3..b1680ec73b 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/Text-Extraction.md +++ b/Document-Processing/PDF/PDF-Library/javascript/Text-Extraction.md @@ -56,43 +56,12 @@ document.destroy(); {% endhighlight %} {% endtabs %} -## Working with basic text extraction asynchronously +### Basic text extraction -This example demonstrates how to extract plain text from a PDF document asynchronously using the [PdfDataExtractor](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor) class and the `extractText` method. Basic text extraction retrieves text content from the entire PDF document. - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfDocument } from '@syncfusion/ej2-pdf'; -import { PdfDataExtractor } from '@syncfusion/ej2-pdf-data-extract'; - -// Load an existing PDF document -let document: PdfDocument = new PdfDocument(data); -// Initialize a new instance of the `PdfDataExtractor` class -let extractor: PdfDataExtractor = new PdfDataExtractor(document); -// Extract text content from the PDF document asynchronously. -let text: string = await extractor.extractText(); -// Save the document -document.save('Output.pdf'); -// Close the document -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -// Load an existing PDF document -var document = new ej.pdf.PdfDocument(data); -// Initialize a new instance of the PdfDataExtractor class -var extractor = new ej.pdfdataextract.PdfDataExtractor(document); -// Extract text content from the PDF document asynchronously -var text = await extractor.extractText(); -// Save the document -document.save('Output.pdf'); -// Close the document -document.destroy(); - -{% endhighlight %} -{% endtabs %} +| Method | Return Type | Description | +|---|---|---| +| [`extractTextSync()`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextsync) | `string` | Extracts plain text synchronously from all pages of the PDF document. | +| [`extractText()`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttext) | `Promise` | Extracts plain text asynchronously from all pages of the PDF document. | ## Extract text from a specific page range in a PDF document synchronously @@ -127,38 +96,12 @@ document.destroy(); {% endhighlight %} {% endtabs %} -## Extract text from a specific page range in a PDF document asynchronously - -This example demonstrates how to asynchronously extract text from a PDF document by specifying a start and end page index. This approach allows you to retrieve text content from a defined range of pages for processing or analysis. - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} -import { PdfDocument } from '@syncfusion/ej2-pdf'; -import { PdfDataExtractor } from '@syncfusion/ej2-pdf-data-extract'; - -// Load an existing PDF document -let document: PdfDocument = new PdfDocument(data); -// Initialize a new instance of the `PdfDataExtractor` class -let extractor: PdfDataExtractor = new PdfDataExtractor(document); -// Extract text content from the specified page range asynchronously -let text: string = await extractor.extractText({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); -// Release document resources -document.destroy(); +### Text extraction from a specific page range -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -// Load an existing PDF document -var document = new ej.pdf.PdfDocument(data); -// Initialize a new instance of the `PdfDataExtractor` class -var extractor = new ej.pdfdataextract.PdfDataExtractor(document); -// Extract text content from the specified page range asynchronously -var text = await extractor.extractText({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); -// Release document resources -document.destroy(); - -{% endhighlight %} -{% endtabs %} +| Method | Return Type | Description | +|---|---|---| +| [`extractTextSync(options)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextsync) | `string` | Extracts plain text synchronously from the page range specified using `startPageIndex` and `endPageIndex`. | +| [`extractText(options)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttext) | `Promise` | Extracts plain text asynchronously from the page range specified using `startPageIndex` and `endPageIndex`. | ## Working with layout-based text extraction synchronously @@ -193,40 +136,12 @@ document.destroy(); {% endhighlight %} {% endtabs %} -## Working with layout-based text extraction asynchronously - -This example demonstrates how to extract text from a PDF document asynchronously using the [PdfDataExtractor](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor) class with layout-based options. Layout-based extraction preserves the visual structure of the source document, including line breaks and spacing. - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} -import { PdfDocument } from '@syncfusion/ej2-pdf'; -import { PdfDataExtractor } from '@syncfusion/ej2-pdf-data-extract'; - -// Load an existing PDF document -let document: PdfDocument = new PdfDocument(data); -// Initialize a new instance of the `PdfDataExtractor` class -let extractor: PdfDataExtractor = new PdfDataExtractor(document); -// Extract text from the PDF page based on its layout asynchronously -let text: string = await extractor.extractText({ isLayout: true }); -// Release document resources -document.destroy(); +### Layout-based text extraction -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -// Load an existing PDF document -var document = new ej.pdf.PdfDocument(data); -// Initialize a new instance of the `PdfDataExtractor` class -var extractor = new ej.pdfdataextract.PdfDataExtractor(document); -// Extract text from the PDF page based on its layout asynchronously -var text = await extractor.extractText({ isLayout: true }); -// Release document resources -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -N> Layout-based text extraction may take additional processing time when compared to the basic extraction mode. +| Method | Return Type | Description | +|---|---|---| +| [`extractTextSync(options)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextsync) | `string` | Extracts text synchronously while preserving the visual layout when `isLayout` is set to `true`. | +| [`extractText(options)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttext) | `Promise` | Extracts text asynchronously while preserving the visual layout when `isLayout` is set to `true`. | ## Text extraction with bounds @@ -299,72 +214,14 @@ document.destroy(); {% endhighlight %} {% endtabs %} -### Working with lines asynchronously - -This example demonstrates how to extract text from a PDF page based on individual lines asynchronously. The [extractTextLines](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlines) method returns a collection of [TextLine](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textline) objects, allowing precise access to text content line by line. - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} -import { PdfDocument } from '@syncfusion/ej2-pdf'; -import { PdfDataExtractor, TextLine, TextWord, TextGlyph, PdfFontStyle, Rectangle } from '@syncfusion/ej2-pdf-data-extract'; +### Working with lines -// Load an existing PDF document -let document: PdfDocument = new PdfDocument(data); -// Initialize a new instance of the `PdfDataExtractor` class -let extractor: PdfDataExtractor = new PdfDataExtractor(document); -// Extract `TextLine` objects from the PDF document asynchronously -let textLines: Array = await extractor.extractTextLines({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); -// Iterate through each text line in the collection -textLines.forEach((textLine: TextLine) => { - // Gets the bounds of the text line - let lineBounds: Rectangle = textLine.bounds; - // Gets the single line of extracted text from the PDF page - let line: string = textLine.text; - // Gets the page index of the text line extracted - let pageIndex: number = textLine.pageIndex; - // Gets the collection of text words extracted from a specified page in a PDF document - let words: TextWord[] = textLine.words; - // Gets the name of the font used for a particular line of text - let fontName: string = textLine.fontName; - // Gets the font style used for a particular line of text - let fontStyle: PdfFontStyle = textLine.fontStyle; - // Gets the font size used for a particular line of text - let fontSize: number = textLine.fontSize; -}); -// Release document resources -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -// Load an existing PDF document -var document = new ej.pdf.PdfDocument(data); -// Initialize a new instance of the `PdfDataExtractor` class -var extractor = new ej.pdfdataextract.PdfDataExtractor(document); -// Extract `TextLine` objects from the PDF document asynchronously -var textLines = await extractor.extractTextLines({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); -// Iterate through each text line in the collection -textLines.forEach((textLine) => { - // Gets the bounds of the text line - var lineBounds = textLine.bounds; - // Gets the single line of extracted text from the PDF page - var line = textLine.text; - // Gets the page index of the text line extracted - var pageIndex = textLine.pageIndex; - // Gets the collection of text words extracted from a specified page in a PDF document - var words = textLine.words; - // Gets the name of the font used for a particular line of text - var fontName = textLine.fontName; - // Gets the font style used for a particular line of text - var fontStyle = textLine.fontStyle; - // Gets the font size used for a particular line of text - var fontSize = textLine.fontSize; -}); -// Release document resources -document.destroy(); - -{% endhighlight %} -{% endtabs %} +| Method | Return Type | Description | +|---|---|---| +| [`extractTextLinesSync()`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlinessync) | `TextLine[]` | Extracts text lines synchronously from all pages of the PDF document. | +| [`extractTextLinesSync(options)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlinessync) | `TextLine[]` | Extracts text lines synchronously from the page range specified in the extraction options. | +| [`extractTextLines()`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlines) | `Promise` | Extracts text lines asynchronously from all pages of the PDF document. | +| [`extractTextLines(options)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlines) | `Promise` | Extracts text lines asynchronously from the page range specified in the extraction options. | ### Working with words synchronously @@ -431,70 +288,14 @@ document.destroy(); {% endhighlight %} {% endtabs %} -### Working with words asynchronously - -This example demonstrates how to extract words from a PDF document using the [extractTextLines](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlines) method. Each line contains a collection of [TextWord](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textword) objects. - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} -import { PdfDocument } from '@syncfusion/ej2-pdf'; -import { PdfDataExtractor, TextLine, TextWord, TextGlyph, PdfFontStyle, Rectangle } from '@syncfusion/ej2-pdf-data-extract'; - -// Load an existing PDF document -let document: PdfDocument = new PdfDocument(data); -// Initialize a new instance of the `PdfDataExtractor` class -let extractor: PdfDataExtractor = new PdfDataExtractor(document); -// Extract `TextLine` objects from the PDF document asynchronously -let textLines: Array = await extractor.extractTextLines({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); -textLines.forEach((textLine: TextLine) => { - textLine.words.forEach((textWord: TextWord) => { - // Gets the bounds of the text word - let wordBounds: Rectangle = textWord.bounds; - // Gets the single word of extracted text from the PDF page - let word: string = textWord.text; - // Gets the collection of text glyphs extracted from a specified page in a PDF document - let glyphs: TextGlyph[] = textWord.glyphs; - // Gets the name of the font used for a particular word - let wordFontName: string = textWord.fontName; - // Gets the style of the font used for a particular word - let wordFontStyle: PdfFontStyle = textWord.fontStyle; - // Gets the size of the font used for a particular word - let wordFontSize: number = textWord.fontSize; - }); -}); -// Release document resources -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -// Load an existing PDF document -var document = new ej.pdf.PdfDocument(data); -// Initialize a new instance of the `PdfDataExtractor` class -var extractor = new ej.pdfdataextract.PdfDataExtractor(document); -// Extract `TextLine` objects from the PDF document asynchronously -var textLines = await extractor.extractTextLines({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); -textLines.forEach((textLine) => { - textLine.words.forEach((textWord) => { - // Gets the bounds of the text word - var wordBounds = textWord.bounds; - // Gets the single word of extracted text from the PDF page - var word = textWord.text; - // Gets the collection of text glyphs extracted from a specified page in a PDF document - var glyphs = textWord.glyphs; - // Gets the name of the font used for a particular word - var wordFontName = textWord.fontName; - // Gets the style of the font used for a particular word - var wordFontStyle = textWord.fontStyle; - // Gets the size of the font used for a particular word - var wordFontSize = textWord.fontSize; - }); -}); -// Release document resources -document.destroy(); +### Working with words -{% endhighlight %} -{% endtabs %} +| Method | Return Type | Description | +|---|---|---| +| `extractTextWordsSync()` | `TextWord[]` | Extracts text words synchronously from all pages of the PDF document. | +| `extractTextWordsSync(options)` | `TextWord[]` | Extracts text words synchronously from the page range specified in the extraction options. | +| `extractTextWords()` | `Promise` | Extracts text words asynchronously from all pages of the PDF document. | +| `extractTextWords(options)` | `Promise` | Extracts text words asynchronously from the page range specified in the extraction options. | ### Working with characters synchronously @@ -569,84 +370,20 @@ document.destroy(); {% endhighlight %} {% endtabs %} -### Working with characters asynchronously - -You can retrieve a single character and its properties, including bounds, font name, font size, and text color, using the [extractTextLines](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlines) method. Refer to the code sample below. - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} -import { PdfDocument, PdfColor, Rectangle } from '@syncfusion/ej2-pdf'; -import { PdfDataExtractor, TextLine, TextWord, TextGlyph, PdfFontStyle } from '@syncfusion/ej2-pdf-data-extract'; +### Working with characters -// Load an existing PDF document -let document: PdfDocument = new PdfDocument(data); -// Initialize a new instance of the `PdfDataExtractor` class -let extractor: PdfDataExtractor = new PdfDataExtractor(document); -// Extract `TextLine` objects from the PDF document asynchronously -let textLines: Array = await extractor.extractTextLines({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); -textLines.forEach((textLine: TextLine) => { - textLine.words.forEach((textWord: TextWord) => { - textWord.glyphs.forEach((textGlyph: TextGlyph) => { - // Gets the bounds of the text glyph - let glyphBounds: Rectangle = textGlyph.bounds; - // Gets the single character of extracted text from the PDF page - let character: string = textGlyph.text; - // Gets the font size used for a particular character of the text - let fontSize: number = textGlyph.fontSize; - // Gets the name of the font used for a particular character of the text - let fontName: string = textGlyph.fontName; - // Gets the font style used for a particular character of the text - let fontStyle: PdfFontStyle = textGlyph.fontStyle; - // Gets the text color of the text glyph - let color: PdfColor = textGlyph.color; - // Gets the value indicating whether the glyph is rotated or not - let isRotated: boolean = textGlyph.isRotated; - }); - }); -}); -// Release document resources -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -// Load an existing PDF document -var document = new ej.pdf.PdfDocument(data); -// Initialize a new instance of the `PdfDataExtractor` class -var extractor = new ej.pdfdataextract.PdfDataExtractor(document); -// Extract `TextLine` objects from the PDF document asynchronously -var textLines = await extractor.extractTextLines({ startPageIndex: 0, endPageIndex: document.pageCount - 1 }); -textLines.forEach((textLine) => { - textLine.words.forEach((textWord) => { - textWord.glyphs.forEach((textGlyph) => { - // Gets the bounds of the text glyph - var glyphBounds = textGlyph.bounds; - // Gets the single character of extracted text from the PDF page - var character = textGlyph.text; - // Gets the font size used for a particular character of the text - var fontSize = textGlyph.fontSize; - // Gets the name of the font used for a particular character of the text - var fontName = textGlyph.fontName; - // Gets the font style used for a particular character of the text - var fontStyle = textGlyph.fontStyle; - // Gets the text color of the text glyph - var color = textGlyph.color; - // Gets the value indicating whether the glyph is rotated or not - var isRotated = textGlyph.isRotated; - }); - }); -}); -// Release document resources -document.destroy(); - -{% endhighlight %} -{% endtabs %} +| Method | Return Type | Description | +|---|---|---| +| `extractTextCharactersSync()` | `TextGlyph[]` | Extracts text characters synchronously from all pages of the PDF document. | +| `extractTextCharactersSync(options)` | `TextGlyph[]` | Extracts text characters synchronously from the page range specified in the extraction options. | +| `extractTextCharacters()` | `Promise` | Extracts text characters asynchronously from all pages of the PDF document. | +| `extractTextCharacters(options)` | `Promise` | Extracts text characters asynchronously from the page range specified in the extraction options. | -## Find Text +### Find text synchronously -The [findText](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtext) method of the [PdfDataExtractor](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor) class locates specific text in a PDF document. The method returns the page index and rectangular bounds of each matching text occurrence. These details are useful for highlighting text, applying redaction, adding annotations, navigating between search results, and building custom search features. +The [findTextSync](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtext) method of the [PdfDataExtractor](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor) class locates specific text in a PDF document. The method returns the page index and rectangular bounds of each matching text occurrence synchronously.. These details are useful for highlighting text, applying redaction, adding annotations, navigating between search results, and building custom search features. -The following code example demonstrates how to search for text in a PDF document using the `findText` method. +The following code example demonstrates how to search for text synchronously in a PDF document. {% tabs %} @@ -659,8 +396,8 @@ import { PdfDataExtractor } from '@syncfusion/ej2-pdf-data-extract'; let document: PdfDocument = new PdfDocument(data); // Initialize a new instance of the `PdfDataExtractor` class let extractor: PdfDataExtractor = new PdfDataExtractor(document); -// Search for the specified text and retrieve the matching occurrences -let searchResults = await extractor.findText('document'); +// Search for the specified text and retrieve the matching occurrences synchronously +let searchResults = extractor.findTextSync('document'); // Release document resources document.destroy(); @@ -672,8 +409,8 @@ document.destroy(); var document = new ej.pdf.PdfDocument(data); // Initialize a new instance of the PdfDataExtractor class var extractor = new ej.pdfdataextract.PdfDataExtractor(document); -// Search for the specified text and retrieve the matching occurrences -var searchResults = await extractor.findText('document'); +// Search for the specified text and retrieve the matching occurrences synchronously +var searchResults = extractor.findTextSync('document'); // Release document resources document.destroy(); @@ -681,31 +418,33 @@ document.destroy(); {% endtabs %} -N> The page index returned in a text search result is zero-based. - -N> The `findText` method searches the text content available in the PDF document. It does not perform optical character recognition on scanned or image-only PDF pages. +N> Use `findTextSync` when the search result is required immediately. For large PDF documents, use the asynchronous `findText` method to avoid blocking execution. -N> Searching a large PDF document may require additional processing time depending on the number of pages and matching text occurrences. +## Search and get the bounds of text in a PDF document -### Find text synchronously +You can search for specific text in a PDF document and retrieve the location of every occurrence using the [findTextSync](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtextsync) and [findText](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtext) methods of the [PdfDataExtractor](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor) class. -The [findTextSync](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtextsync) method searches for text and returns the matching occurrences synchronously. +The `findTextSync` method searches the PDF document synchronously, while the `findText` method performs the search asynchronously. Both methods accept optional text-search settings and return the searched text together with the bounding rectangles of all matching occurrences grouped by page number. The returned bounds can be used for highlighting, redaction, annotation, and document navigation. -The following code example demonstrates how to search for text synchronously in a PDF document. +The following code example demonstrates how to search for text synchronously using optional search parameters and retrieve the bounds of all matching occurrences in a PDF document. {% tabs %} {% highlight typescript tabtitle="TypeScript" %} import { PdfDocument } from '@syncfusion/ej2-pdf'; -import { PdfDataExtractor } from '@syncfusion/ej2-pdf-data-extract'; +import { PdfDataExtractor, TextSearchResult, Rectangle } from '@syncfusion/ej2-pdf-data-extract'; // Load an existing PDF document let document: PdfDocument = new PdfDocument(data); -// Initialize a new instance of the `PdfDataExtractor` class +// Initialize a new instance of the PdfDataExtractor class let extractor: PdfDataExtractor = new PdfDataExtractor(document); -// Search for the specified text and retrieve the matching occurrences synchronously -let searchResults = extractor.findTextSync('document'); +// Search for the specified text synchronously using optional search parameters +let textSearch: TextSearchResult = extractor.findTextSync('hello', { caseSensitive: false, wholeWord: true, startPageIndex: 0, endPageIndex: document.pageCount - 1 }); +// Get the searched text +let searchText: string = textSearch.searchText; +// Get the matching bounds grouped by page number +let searchResults: Map<number, Rectangle[]> = textSearch.searchResults; // Release document resources document.destroy(); @@ -717,8 +456,12 @@ document.destroy(); var document = new ej.pdf.PdfDocument(data); // Initialize a new instance of the PdfDataExtractor class var extractor = new ej.pdfdataextract.PdfDataExtractor(document); -// Search for the specified text and retrieve the matching occurrences synchronously -var searchResults = extractor.findTextSync('document'); +// Search for the specified text synchronously using optional search parameters +var textSearch = extractor.findTextSync('hello', { caseSensitive: false, wholeWord: true, startPageIndex: 0, endPageIndex: document.pageCount - 1 }); +// Get the searched text +var searchText = textSearch.searchText; +// Get the matching bounds grouped by page number +var searchResults = textSearch.searchResults; // Release document resources document.destroy(); @@ -726,7 +469,7 @@ document.destroy(); {% endtabs %} -N> Use `findTextSync` when the search result is required immediately. For large PDF documents, use the asynchronous `findText` method to avoid blocking execution. +N> The `findTextSync()` and `findText()` methods also accept a collection of text values as a `string[]`. When multiple text values are provided, `findTextSync()` returns a `TextSearchResult[]`, while `findText()` returns a `Promise`. Each item in the returned collection corresponds to one input text value and contains the searched text in `searchText` and the matching bounding rectangles grouped by page number in `searchResults`. ## FindText Module API Reference @@ -738,6 +481,15 @@ Use the following table to select the text-search method that matches your requi | [`findText(text: string, options)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtext) | Promise | Searches for the specified text asynchronously using the supplied text-search options and returns the matching occurrences. | | [`findTextSync(text: string)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtextsync) | Text search result collection | Searches for the specified text synchronously throughout the PDF document and returns all matching occurrences with their page indexes and bounds. | | [`findTextSync(text: string, options)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtextsync) | Text search result collection | Searches for the specified text synchronously using the supplied text-search options and returns the matching occurrences. | +Use the following table for text search options in the find text method. + +| Optional parameter | Type | Default value | Description | +| ------------------ | --------- | --------------- | ----------------------------------------------------------------------------------- | +| `caseSensitive` | `boolean` | `false` | Specifies whether the search must match uppercase and lowercase characters exactly. | +| `wholeWord` | `boolean` | `false` | Specifies whether the search must match only complete words. | +| `startPageIndex` | `number` | `0` | Specifies the zero-based index of the first page to search. | +| `endPageIndex` | `number` | Last page index | Specifies the zero-based index of the last page to search. | + ## Additional Resources - [JavaScript PDF Library](https://www.syncfusion.com/document-sdk/javascript-pdf-library) From c392b788085974a145a372912319785d784145ab Mon Sep 17 00:00:00 2001 From: "AzureAD\\DhakshinPrasathDhanr" Date: Fri, 4 Sep 2026 14:17:19 +0530 Subject: [PATCH 10/11] 1050196: Removed grid file --- Document-Processing-toc.html | 1 - .../PDF/PDF-Library/javascript/PDF-Grid.md | 928 ------------------ 2 files changed, 929 deletions(-) delete mode 100644 Document-Processing/PDF/PDF-Library/javascript/PDF-Grid.md diff --git a/Document-Processing-toc.html b/Document-Processing-toc.html index ff4d2983cf..52d531824c 100644 --- a/Document-Processing-toc.html +++ b/Document-Processing-toc.html @@ -3454,7 +3454,6 @@
  • Text
  • Lists
  • Images
  • -
  • Grids
  • Templates
  • Headers and Footers
  • Shapes
  • diff --git a/Document-Processing/PDF/PDF-Library/javascript/PDF-Grid.md b/Document-Processing/PDF/PDF-Library/javascript/PDF-Grid.md deleted file mode 100644 index 23289711af..0000000000 --- a/Document-Processing/PDF/PDF-Library/javascript/PDF-Grid.md +++ /dev/null @@ -1,928 +0,0 @@ ---- -title: PdfGrid Tables in JavaScript PDF | Syncfusion -canonical_url: https://www.syncfusion.com/document-sdk/javascript-pdf-library -description: Create and customize PDF tables programmatically using PdfGrid in the Syncfusion JavaScript PDF Library. -platform: document-processing -control: PDF -documentation: UG ---- - -# PdfGrid Tables in JavaScript PDF - -The Syncfusion JavaScript PDF Library supports creating PDF tables from arrays of records or explicitly defined rows and columns. The `PdfGrid` class supports headers, custom column widths, row and column spanning, styles, images, hyperlinks, built-in styles, and pagination. - -N> The TypeScript samples use the `@syncfusion/ej2-pdf` package. The JavaScript samples use the corresponding `ej.pdf` global namespace. - -## Create a table from a data source - -Create a `PdfGrid` from an array of records and an ordered collection of `PdfColumnInformation` mappings. - - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfColumnInformation, PdfDocument, PdfGrid, PdfGridLayoutResult, PdfPage } from '@syncfusion/ej2-pdf'; - -// Create a new PDF document -let document: PdfDocument = new PdfDocument(); -// Add a page -let page: PdfPage = document.addPage(); -// Create the data source -let dataSource: object[] = [ - { id: 'E01', name: 'Clay' }, - { id: 'E02', name: 'Thomas' } -]; -// Define the column mappings -let columns: PdfColumnInformation[] = [ - { field: 'id', headerText: 'Employee ID', width: 90 }, - { field: 'name', headerText: 'Employee Name', width: 140 } -]; -// Create and draw the grid -let grid: PdfGrid = new PdfGrid(dataSource, columns); -let result: PdfGridLayoutResult = grid.draw(page, { x: 10, y: 10 }); -// Save and close the document -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -// Create a new PDF document -var document = new ej.pdf.PdfDocument(); -// Add a page -var page = document.addPage(); -// Create the data source -var dataSource = [ - { id: 'E01', name: 'Clay' }, - { id: 'E02', name: 'Thomas' } -]; -// Define the column mappings -var columns = [ - { field: 'id', headerText: 'Employee ID', width: 90 }, - { field: 'name', headerText: 'Employee Name', width: 140 } -]; -// Create and draw the grid -var grid = new ej.pdf.PdfGrid(dataSource, columns); -var result = grid.draw(page, { x: 10, y: 10 }); -// Save and close the document -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -## Create a table without a data source - -Define the rows, optional headers, and a zero-based column-width map directly. - - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfDocument, PdfGrid, PdfGridRow, PdfPage } from '@syncfusion/ej2-pdf'; - -let document: PdfDocument = new PdfDocument(); -let page: PdfPage = document.addPage(); -let widths: Map = new Map([[0, 90], [1, 140], [2, 100]]); -let headers: PdfGridRow[] = [{ - cells: [{ value: 'Employee ID' }, { value: 'Employee Name' }, { value: 'Salary' }] -}]; -let rows: PdfGridRow[] = [{ - cells: [{ value: 'E01' }, { value: 'Clay' }, { value: '$10,000' }] -}]; -let grid: PdfGrid = new PdfGrid(3, widths, rows, headers); -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -var document = new ej.pdf.PdfDocument(); -var page = document.addPage(); -var widths = new Map([[0, 90], [1, 140], [2, 100]]); -var headers = [{ - cells: [{ value: 'Employee ID' }, { value: 'Employee Name' }, { value: 'Salary' }] -}]; -var rows = [{ - cells: [{ value: 'E01' }, { value: 'Clay' }, { value: '$10,000' }] -}]; -var grid = new ej.pdf.PdfGrid(3, widths, rows, headers); -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -## Add rows and headers - -Use `addHeader` and `addRow` to append rows after constructing an explicit grid. - - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfDocument, PdfGrid, PdfPage } from '@syncfusion/ej2-pdf'; - -let document: PdfDocument = new PdfDocument(); -let page: PdfPage = document.addPage(); -let widths: Map = new Map([[0, 90], [1, 140]]); -let grid: PdfGrid = new PdfGrid(2, widths, []); -grid.addHeader({ cells: [{ value: 'ID' }, { value: 'Name' }] }); -grid.addRow({ cells: [{ value: 'E01' }, { value: 'Clay' }] }); -grid.addRow({ cells: [{ value: 'E02' }, { value: 'Thomas' }] }); -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -var document = new ej.pdf.PdfDocument(); -var page = document.addPage(); -var widths = new Map([[0, 90], [1, 140]]); -var grid = new ej.pdf.PdfGrid(2, widths, []); -grid.addHeader({ cells: [{ value: 'ID' }, { value: 'Name' }] }); -grid.addRow({ cells: [{ value: 'E01' }, { value: 'Clay' }] }); -grid.addRow({ cells: [{ value: 'E02' }, { value: 'Thomas' }] }); -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -## Create a table in an existing PDF document - -Load an existing document, access a page, and draw the grid on that page. - - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfColumnInformation, PdfDocument, PdfGrid, PdfPage } from '@syncfusion/ej2-pdf'; - -// Load an existing PDF document -let document: PdfDocument = new PdfDocument(data); -let page: PdfPage = document.getPage(0); -let source: object[] = [{ id: '1', name: 'Clay' }, { id: '2', name: 'Thomas' }]; -let columns: PdfColumnInformation[] = [ - { field: 'id', headerText: 'ID', width: 60 }, - { field: 'name', headerText: 'Name', width: 120 } -]; -let grid: PdfGrid = new PdfGrid(source, columns); -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -// Load an existing PDF document -var document = new ej.pdf.PdfDocument(data); -var page = document.getPage(0); -var source = [{ id: '1', name: 'Clay' }, { id: '2', name: 'Thomas' }]; -var columns = [ - { field: 'id', headerText: 'ID', width: 60 }, - { field: 'name', headerText: 'Name', width: 120 } -]; -var grid = new ej.pdf.PdfGrid(source, columns); -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -## Customize table cells - -Apply a background, border, padding, and text color to an individual cell. - - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfBrush, PdfDocument, PdfGrid, PdfGridRow, PdfPage, PdfPen } from '@syncfusion/ej2-pdf'; - -let document: PdfDocument = new PdfDocument(); -let page: PdfPage = document.addPage(); -let widths: Map = new Map([[0, 100], [1, 140]]); -let rows: PdfGridRow[] = [{ - height: 40, - cells: [ - { - value: 'E01', - style: { - background: new PdfBrush({ r: 255, g: 255, b: 180 }), - border: new PdfPen({ r: 255, g: 0, b: 0 }, 1), - padding: { left: 8, right: 8, top: 6, bottom: 6 }, - textProperties: { color: new PdfBrush({ r: 0, g: 0, b: 180 }) } - } - }, - { value: 'Clay' } - ] -}]; -let grid: PdfGrid = new PdfGrid(2, widths, rows); -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -var document = new ej.pdf.PdfDocument(); -var page = document.addPage(); -var widths = new Map([[0, 100], [1, 140]]); -var rows = [{ - height: 40, - cells: [ - { - value: 'E01', - style: { - background: new ej.pdf.PdfBrush({ r: 255, g: 255, b: 180 }), - border: new ej.pdf.PdfPen({ r: 255, g: 0, b: 0 }, 1), - padding: { left: 8, right: 8, top: 6, bottom: 6 }, - textProperties: { color: new ej.pdf.PdfBrush({ r: 0, g: 0, b: 180 }) } - } - }, - { value: 'Clay' } - ] -}]; -var grid = new ej.pdf.PdfGrid(2, widths, rows); -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -## Customize rows and columns - -Set a row height and style, and configure column widths and text alignment. - - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfBrush, PdfColumnInformation, PdfDocument, PdfFontFamily, PdfGrid, PdfPage, PdfStandardFont, PdfTemplateHorizontalAlignment, PdfTemplateVerticalAlignment } from '@syncfusion/ej2-pdf'; - -let document: PdfDocument = new PdfDocument(); -let page: PdfPage = document.addPage(); -let source: object[] = [{ id: 'E01', name: 'John' }, { id: 'E02', name: 'Thomas' }]; -let columns: PdfColumnInformation[] = [ - { - field: 'id', headerText: 'Employee ID', width: 80, - style: { textProperties: { - horizontalAlignment: PdfTemplateHorizontalAlignment.center, - verticalAlignment: PdfTemplateVerticalAlignment.middle - } } - }, - { field: 'name', headerText: 'Employee Name', width: 150 } -]; -let grid: PdfGrid = new PdfGrid(source, columns); -grid.rows[0].height = 50; -grid.rows[0].style = { - background: new PdfBrush({ r: 255, g: 255, b: 200 }), - textProperties: { - font: new PdfStandardFont(PdfFontFamily.courier, 10), - color: new PdfBrush({ r: 0, g: 0, b: 255 }) - } -}; -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -var document = new ej.pdf.PdfDocument(); -var page = document.addPage(); -var source = [{ id: 'E01', name: 'John' }, { id: 'E02', name: 'Thomas' }]; -var columns = [ - { - field: 'id', headerText: 'Employee ID', width: 80, - style: { textProperties: { - horizontalAlignment: ej.pdf.PdfTemplateHorizontalAlignment.center, - verticalAlignment: ej.pdf.PdfTemplateVerticalAlignment.middle - } } - }, - { field: 'name', headerText: 'Employee Name', width: 150 } -]; -var grid = new ej.pdf.PdfGrid(source, columns); -grid.rows[0].height = 50; -grid.rows[0].style = { - background: new ej.pdf.PdfBrush({ r: 255, g: 255, b: 200 }), - textProperties: { - font: new ej.pdf.PdfStandardFont(ej.pdf.PdfFontFamily.courier, 10), - color: new ej.pdf.PdfBrush({ r: 0, g: 0, b: 255 }) - } -}; -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -## Customize the whole table - -Use the grid-level `style` property to set padding, spacing, border, and text formatting. - - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfDocument, PdfFontFamily, PdfGrid, PdfPage, PdfPen, PdfStandardFont } from '@syncfusion/ej2-pdf'; - -let document: PdfDocument = new PdfDocument(); -let page: PdfPage = document.addPage(); -let source: object[] = [{ id: 'E01', name: 'Clay' }, { id: 'E02', name: 'Thomas' }]; -let columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; -let grid: PdfGrid = new PdfGrid(source, columns); -grid.style = { - padding: { left: 4, right: 4, top: 3, bottom: 3 }, - space: { left: 1, right: 1, top: 1, bottom: 1 }, - border: new PdfPen({ r: 80, g: 80, b: 80 }, 0.5), - textProperties: { font: new PdfStandardFont(PdfFontFamily.helvetica, 9) } -}; -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -var document = new ej.pdf.PdfDocument(); -var page = document.addPage(); -var source = [{ id: 'E01', name: 'Clay' }, { id: 'E02', name: 'Thomas' }]; -var columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; -var grid = new ej.pdf.PdfGrid(source, columns); -grid.style = { - padding: { left: 4, right: 4, top: 3, bottom: 3 }, - space: { left: 1, right: 1, top: 1, bottom: 1 }, - border: new ej.pdf.PdfPen({ r: 80, g: 80, b: 80 }, 0.5), - textProperties: { font: new ej.pdf.PdfStandardFont(ej.pdf.PdfFontFamily.helvetica, 9) } -}; -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -## Apply a built-in table style - -Pass a `PdfGridBuiltinStyle` value to the constructor. - - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfDocument, PdfGrid, PdfGridBuiltinStyle, PdfPage } from '@syncfusion/ej2-pdf'; - -let document: PdfDocument = new PdfDocument(); -let page: PdfPage = document.addPage(); -let source: object[] = [{ id: 'E01', name: 'Clay' }, { id: 'E02', name: 'Thomas' }]; -let columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; -let grid: PdfGrid = new PdfGrid(source, columns, undefined, PdfGridBuiltinStyle.gridTable4Accent1); -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -var document = new ej.pdf.PdfDocument(); -var page = document.addPage(); -var source = [{ id: 'E01', name: 'Clay' }, { id: 'E02', name: 'Thomas' }]; -var columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; -var grid = new ej.pdf.PdfGrid(source, columns, undefined, ej.pdf.PdfGridBuiltinStyle.gridTable4Accent1); -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -## Paginate a table - -Use `PdfLayoutFormat` to flow table rows across pages and repeat the header on continuation pages. - - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfDocument, PdfGrid, PdfGridLayoutResult, PdfLayoutBreakType, PdfLayoutFormat, PdfLayoutType, PdfPage } from '@syncfusion/ej2-pdf'; - -let document: PdfDocument = new PdfDocument(); -let page: PdfPage = document.addPage(); -let source: object[] = []; -for (let i: number = 1; i <= 100; i++) { - source.push({ id: 'E' + i, name: 'Employee ' + i }); -} -let columns = [{ field: 'id', headerText: 'ID', width: 80 }, { field: 'name', headerText: 'Name', width: 160 }]; -let grid: PdfGrid = new PdfGrid(source, columns); -grid.repeatHeader = true; -let format: PdfLayoutFormat = new PdfLayoutFormat(); -format.layout = PdfLayoutType.paginate; -format.break = PdfLayoutBreakType.fitPage; -let result: PdfGridLayoutResult = grid.draw(page, { x: 10, y: 10, width: 300, height: 500 }, format); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -var document = new ej.pdf.PdfDocument(); -var page = document.addPage(); -var source = []; -for (var i = 1; i <= 100; i++) { - source.push({ id: 'E' + i, name: 'Employee ' + i }); -} -var columns = [{ field: 'id', headerText: 'ID', width: 80 }, { field: 'name', headerText: 'Name', width: 160 }]; -var grid = new ej.pdf.PdfGrid(source, columns); -grid.repeatHeader = true; -var format = new ej.pdf.PdfLayoutFormat(); -format.layout = ej.pdf.PdfLayoutType.paginate; -format.break = ej.pdf.PdfLayoutBreakType.fitPage; -var result = grid.draw(page, { x: 10, y: 10, width: 300, height: 500 }, format); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -## Prevent row breaks across pages - -Use `PdfLayoutBreakType.fitElement` to keep each row together. If a row does not fit in the remaining space, the complete row moves to the next page. - - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfDocument, PdfGrid, PdfLayoutBreakType, PdfLayoutFormat, PdfLayoutType, PdfPage } from '@syncfusion/ej2-pdf'; - -let document: PdfDocument = new PdfDocument(); -let page: PdfPage = document.addPage(); -let source: object[] = []; -for (let i: number = 1; i <= 80; i++) { - source.push({ id: 'E' + i, description: 'Complete row content for employee ' + i }); -} -let columns = [ - { field: 'id', headerText: 'ID', width: 60 }, - { field: 'description', headerText: 'Description', width: 240 } -]; -let grid: PdfGrid = new PdfGrid(source, columns); -let format: PdfLayoutFormat = new PdfLayoutFormat(); -format.layout = PdfLayoutType.paginate; -format.break = PdfLayoutBreakType.fitElement; -grid.draw(page, { x: 10, y: 10, width: 320, height: 500 }, format); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -var document = new ej.pdf.PdfDocument(); -var page = document.addPage(); -var source = []; -for (var i = 1; i <= 80; i++) { - source.push({ id: 'E' + i, description: 'Complete row content for employee ' + i }); -} -var columns = [ - { field: 'id', headerText: 'ID', width: 60 }, - { field: 'description', headerText: 'Description', width: 240 } -]; -var grid = new ej.pdf.PdfGrid(source, columns); -var format = new ej.pdf.PdfLayoutFormat(); -format.layout = ej.pdf.PdfLayoutType.paginate; -format.break = ej.pdf.PdfLayoutBreakType.fitElement; -grid.draw(page, { x: 10, y: 10, width: 320, height: 500 }, format); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -N> The .NET `PaginateBounds` API used to change continuation-page margins is not available in the current JavaScript `PdfGrid` implementation. Therefore, a JavaScript sample for changing margins from the second page onwards is not included. -## Add multiple tables - -Use the page and occupied bounds returned by the first grid to position the second grid without overlap. - - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfDocument, PdfGrid, PdfGridLayoutResult, PdfPage } from '@syncfusion/ej2-pdf'; - -let document: PdfDocument = new PdfDocument(); -let page: PdfPage = document.addPage(); -let columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; -let firstGrid: PdfGrid = new PdfGrid([{ id: 'E01', name: 'Clay' }], columns); -let firstResult: PdfGridLayoutResult = firstGrid.draw(page, { x: 10, y: 10 }); -let secondGrid: PdfGrid = new PdfGrid([{ id: 'E02', name: 'Thomas' }], columns); -let secondY: number = firstResult.bounds.y + firstResult.bounds.height + 20; -secondGrid.draw(firstResult.page, { x: 10, y: secondY }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -var document = new ej.pdf.PdfDocument(); -var page = document.addPage(); -var columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; -var firstGrid = new ej.pdf.PdfGrid([{ id: 'E01', name: 'Clay' }], columns); -var firstResult = firstGrid.draw(page, { x: 10, y: 10 }); -var secondGrid = new ej.pdf.PdfGrid([{ id: 'E02', name: 'Thomas' }], columns); -var secondY = firstResult.bounds.y + firstResult.bounds.height + 20; -secondGrid.draw(firstResult.page, { x: 10, y: secondY }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -## Apply text formatting - -Apply font, color, and alignment through `textProperties`. - - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfBrush, PdfDocument, PdfFontFamily, PdfGrid, PdfPage, PdfStandardFont, PdfTemplateHorizontalAlignment, PdfTemplateVerticalAlignment } from '@syncfusion/ej2-pdf'; - -let document: PdfDocument = new PdfDocument(); -let page: PdfPage = document.addPage(); -let source: object[] = [{ id: 'E01', name: 'Clay' }, { id: 'E02', name: 'Thomas' }]; -let columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; -let grid: PdfGrid = new PdfGrid(source, columns); -grid.style = { textProperties: { - font: new PdfStandardFont(PdfFontFamily.helvetica, 10), - color: new PdfBrush({ r: 0, g: 0, b: 120 }), - horizontalAlignment: PdfTemplateHorizontalAlignment.center, - verticalAlignment: PdfTemplateVerticalAlignment.middle -} }; -grid.draw(page, { x: 10, y: 10, width: 280, height: 200 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -var document = new ej.pdf.PdfDocument(); -var page = document.addPage(); -var source = [{ id: 'E01', name: 'Clay' }, { id: 'E02', name: 'Thomas' }]; -var columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; -var grid = new ej.pdf.PdfGrid(source, columns); -grid.style = { textProperties: { - font: new ej.pdf.PdfStandardFont(ej.pdf.PdfFontFamily.helvetica, 10), - color: new ej.pdf.PdfBrush({ r: 0, g: 0, b: 120 }), - horizontalAlignment: ej.pdf.PdfTemplateHorizontalAlignment.center, - verticalAlignment: ej.pdf.PdfTemplateVerticalAlignment.middle -} }; -grid.draw(page, { x: 10, y: 10, width: 280, height: 200 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -## Apply row and column spanning - -Set `rowSpan` and `columnSpan` in a cell style. Span regions cannot overlap or extend beyond the grid. - - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfDocument, PdfGrid, PdfGridRow, PdfPage, PdfTemplateHorizontalAlignment } from '@syncfusion/ej2-pdf'; - -let document: PdfDocument = new PdfDocument(); -let page: PdfPage = document.addPage(); -let widths: Map = new Map([[0, 100], [1, 140]]); -let rows: PdfGridRow[] = [ - { cells: [ - { value: 'Employee Details', style: { columnSpan: 2, textProperties: { horizontalAlignment: PdfTemplateHorizontalAlignment.center } } } - ] }, - { cells: [ - { value: 'E01', style: { rowSpan: 2 } }, { value: 'Clay' } - ] }, - { cells: [{ value: 'Thomas' }] } -]; -let grid: PdfGrid = new PdfGrid(2, widths, rows); -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -var document = new ej.pdf.PdfDocument(); -var page = document.addPage(); -var widths = new Map([[0, 100], [1, 140]]); -var rows = [ - { cells: [ - { value: 'Employee Details', style: { columnSpan: 2, textProperties: { horizontalAlignment: ej.pdf.PdfTemplateHorizontalAlignment.center } } } - ] }, - { cells: [ - { value: 'E01', style: { rowSpan: 2 } }, { value: 'Clay' } - ] }, - { cells: [{ value: 'Thomas' }] } -]; -var grid = new ej.pdf.PdfGrid(2, widths, rows); -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -## Insert an image in a table cell - -Assign a `PdfBitmap` as the cell value and configure its size, fit mode, and alignment. - - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfBitmap, PdfDocument, PdfGrid, PdfGridRow, PdfPage, PdfTemplateHorizontalAlignment, PdfTemplateVerticalAlignment } from '@syncfusion/ej2-pdf'; - -let document: PdfDocument = new PdfDocument(); -let page: PdfPage = document.addPage(); -let image: PdfBitmap = new PdfBitmap(imageData); -let widths: Map = new Map([[0, 60], [1, 120]]); -let rows: PdfGridRow[] = [{ - height: 80, - cells: [ - { value: '1' }, - { value: image, style: { imageProperties: { - width: 60, height: 60, fitType: 2, - horizontalAlignment: PdfTemplateHorizontalAlignment.center, - verticalAlignment: PdfTemplateVerticalAlignment.middle - } } } - ] -}]; -let grid: PdfGrid = new PdfGrid(2, widths, rows); -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -var document = new ej.pdf.PdfDocument(); -var page = document.addPage(); -var image = new ej.pdf.PdfBitmap(imageData); -var widths = new Map([[0, 60], [1, 120]]); -var rows = [{ - height: 80, - cells: [ - { value: '1' }, - { value: image, style: { imageProperties: { - width: 60, height: 60, fitType: 2, - horizontalAlignment: ej.pdf.PdfTemplateHorizontalAlignment.center, - verticalAlignment: ej.pdf.PdfTemplateVerticalAlignment.middle - } } } - ] -}]; -var grid = new ej.pdf.PdfGrid(2, widths, rows); -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -## Add a background image to a table cell - -Set `backgroundImage` in the cell style. A `fitType` value of `3` stretches the background image to fill the content area. - - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfBitmap, PdfDocument, PdfGrid, PdfGridRow, PdfPage, PdfTemplateHorizontalAlignment, PdfTemplateVerticalAlignment } from '@syncfusion/ej2-pdf'; - -let document: PdfDocument = new PdfDocument(); -let page: PdfPage = document.addPage(); -let image: PdfBitmap = new PdfBitmap(imageData); -let widths: Map = new Map([[0, 140], [1, 100]]); -let rows: PdfGridRow[] = [{ - height: 70, - cells: [ - { value: 'Employee ID', style: { backgroundImage: { - image: image, - imageProperties: { - fitType: 3, - horizontalAlignment: PdfTemplateHorizontalAlignment.center, - verticalAlignment: PdfTemplateVerticalAlignment.middle - } - } } }, - { value: 'E01' } - ] -}]; -let grid: PdfGrid = new PdfGrid(2, widths, rows); -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -var document = new ej.pdf.PdfDocument(); -var page = document.addPage(); -var image = new ej.pdf.PdfBitmap(imageData); -var widths = new Map([[0, 140], [1, 100]]); -var rows = [{ - height: 70, - cells: [ - { value: 'Employee ID', style: { backgroundImage: { - image: image, - imageProperties: { - fitType: 3, - horizontalAlignment: ej.pdf.PdfTemplateHorizontalAlignment.center, - verticalAlignment: ej.pdf.PdfTemplateVerticalAlignment.middle - } - } } }, - { value: 'E01' } - ] -}]; -var grid = new ej.pdf.PdfGrid(2, widths, rows); -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -## Add hyperlinks - -A string beginning with `http://` or `https://` creates a URI annotation during page-based drawing. An explicit `PdfLink` can also be assigned. - - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfDocument, PdfGrid, PdfGridRow, PdfLinkType, PdfPage } from '@syncfusion/ej2-pdf'; - -let document: PdfDocument = new PdfDocument(); -let page: PdfPage = document.addPage(); -let widths: Map = new Map([[0, 130], [1, 180]]); -let rows: PdfGridRow[] = [ - { cells: [{ value: 'Product page' }, { value: 'https://www.syncfusion.com' }] }, - { cells: [{ value: 'Report' }, { value: 'Open file', link: { type: PdfLinkType.file, uri: 'Report.pdf' } }] } -]; -let grid: PdfGrid = new PdfGrid(2, widths, rows); -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -var document = new ej.pdf.PdfDocument(); -var page = document.addPage(); -var widths = new Map([[0, 130], [1, 180]]); -var rows = [ - { cells: [{ value: 'Product page' }, { value: 'https://www.syncfusion.com' }] }, - { cells: [{ value: 'Report' }, { value: 'Open file', link: { type: ej.pdf.PdfLinkType.file, uri: 'Report.pdf' } }] } -]; -var grid = new ej.pdf.PdfGrid(2, widths, rows); -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -## Draw a border less table - -Use a zero-width border at grid level. - - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfDocument, PdfGrid, PdfGridStyle, PdfPage, PdfPen } from '@syncfusion/ej2-pdf'; - -let document: PdfDocument = new PdfDocument(); -let page: PdfPage = document.addPage(); -let source: object[] = [{ id: 'E01', name: 'Clay' }, { id: 'E02', name: 'Thomas' }]; -let columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; -let style: PdfGridStyle = { border: new PdfPen({ r: 255, g: 255, b: 255 }, 0) }; -let grid: PdfGrid = new PdfGrid(source, columns, style); -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -var document = new ej.pdf.PdfDocument(); -var page = document.addPage(); -var source = [{ id: 'E01', name: 'Clay' }, { id: 'E02', name: 'Thomas' }]; -var columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; -var style = { border: new ej.pdf.PdfPen({ r: 255, g: 255, b: 255 }, 0) }; -var grid = new ej.pdf.PdfGrid(source, columns, style); -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -## Update the grid data source - -Reassign `dataSource` on a data-source grid. Generated rows are rebuilt, while manually added rows remain after them. - - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfDocument, PdfGrid, PdfPage } from '@syncfusion/ej2-pdf'; - -let document: PdfDocument = new PdfDocument(); -let page: PdfPage = document.addPage(); -let columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; -let grid: PdfGrid = new PdfGrid([{ id: 'E01', name: 'Clay' }], columns); -grid.addRow({ cells: [{ value: 'Manual' }, { value: 'Record' }] }); -grid.dataSource = [{ id: 'E10', name: 'Andrew' }, { id: 'E11', name: 'Michael' }]; -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -var document = new ej.pdf.PdfDocument(); -var page = document.addPage(); -var columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; -var grid = new ej.pdf.PdfGrid([{ id: 'E01', name: 'Clay' }], columns); -grid.addRow({ cells: [{ value: 'Manual' }, { value: 'Record' }] }); -grid.dataSource = [{ id: 'E10', name: 'Andrew' }, { id: 'E11', name: 'Michael' }]; -grid.draw(page, { x: 10, y: 10 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% endtabs %} - -## Draw by using a graphics context - -The graphics overload does not paginate. The complete grid must fit within the supplied bounds. - - -{% tabs %} -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfDocument, PdfGrid, PdfPage } from '@syncfusion/ej2-pdf'; - -let document: PdfDocument = new PdfDocument(); -let page: PdfPage = document.addPage(); -let source: object[] = [{ id: 'E01', name: 'Clay' }, { id: 'E02', name: 'Thomas' }]; -let columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; -let grid: PdfGrid = new PdfGrid(source, columns); -grid.draw(page.graphics, { x: 10, y: 10, width: 300, height: 200 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% highlight javascript tabtitle="JavaScript" %} - -var document = new ej.pdf.PdfDocument(); -var page = document.addPage(); -var source = [{ id: 'E01', name: 'Clay' }, { id: 'E02', name: 'Thomas' }]; -var columns = [{ field: 'id', headerText: 'ID' }, { field: 'name', headerText: 'Name' }]; -var grid = new ej.pdf.PdfGrid(source, columns); -grid.draw(page.graphics, { x: 10, y: 10, width: 300, height: 200 }); -document.save('Output.pdf'); -document.destroy(); - -{% endhighlight %} -{% endtabs %} - - -## JavaScript and .NET feature differences - -The following .NET PdfGrid APIs are not present in the supplied JavaScript implementation: - -- Nested `PdfGrid` objects as cell values -- `BeginCellLayout` and `BeginPageLayout` events -- Event-based table rotation -- `PdfGridBuiltinStyleSettings` -- `AllowHorizontalOverflow` -- `PaginateBounds` -- Per-side border collections such as `Borders.All` -- Direct annotation objects as cell values -- `PdfWordWrapType` and character-spacing formatting - -## Additional Resources - -- [JavaScript PDF Library](https://www.syncfusion.com/document-sdk/javascript-pdf-library) -- [JavaScript PDF Library documentation](https://help.syncfusion.com/document-processing/pdf/pdf-library/javascript/overview) -- [JavaScript PDF Library API reference](https://ej2.syncfusion.com/documentation/api/pdf) -- [JavaScript PDF Library examples](https://document.syncfusion.com/demos/pdf/javascript/#/tailwind3/pdf/default.html) -- [JavaScript PDF examples on GitHub](https://github.com/SyncfusionExamples/javascript-pdf-examples) From 12dbd6dd79c0bab4b644d59cd5f92e3e801f9706 Mon Sep 17 00:00:00 2001 From: "AzureAD\\DhakshinPrasathDhanr" Date: Fri, 4 Sep 2026 18:03:59 +0530 Subject: [PATCH 11/11] 1050196: Resolved the feedback items --- .../PDF/PDF-Library/javascript/Annotations.md | 2 +- .../javascript/DigitalSignature.md | 62 ++- .../PDF/PDF-Library/javascript/Encryption.md | 370 +++++++++++------- .../PDF-Library/javascript/Text-Extraction.md | 193 +++++---- .../PDF/PDF-Library/javascript/Text.md | 41 -- 5 files changed, 376 insertions(+), 292 deletions(-) diff --git a/Document-Processing/PDF/PDF-Library/javascript/Annotations.md b/Document-Processing/PDF/PDF-Library/javascript/Annotations.md index e8fec69372..4b9eb62c29 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/Annotations.md +++ b/Document-Processing/PDF/PDF-Library/javascript/Annotations.md @@ -1021,7 +1021,7 @@ document.destroy(); ## Cloud Border Style Annotation -A cloud border style can be applied to rectangle, polygon, circle,ellipse and freeText annotations in an existing PDF document by using the [PdfBorderEffect](https://ej2.syncfusion.com/documentation/api/pdf/pdfbordereffect) class. Set the `intensity` property to control the intensity of the cloud effect and set the `style` property to `PdfBorderEffectStyle.cloudy`. +A cloud border style can be applied to rectangle, polygon, circle, ellipse and freeText annotations in an existing PDF document by using the [PdfBorderEffect](https://ej2.syncfusion.com/documentation/api/pdf/pdfbordereffect) class. Set the `intensity` property to control the intensity of the cloud effect and set the `style` property to `PdfBorderEffectStyle.cloudy`. The following code example demonstrates how to apply a cloud border style to an existing rectangle annotation in a PDF document. diff --git a/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md b/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md index 2e221e6166..cc00ba37f3 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md +++ b/Document-Processing/PDF/PDF-Library/javascript/DigitalSignature.md @@ -1091,39 +1091,36 @@ The JavaScript PDF Library supports validating digital signatures in an existing * Certificate revocation status using Online Certificate Status Protocol (OCSP) and Certificate Revocation List (CRL) information. * Multiple digital signatures available in the PDF document. -Use the `validateSignatures` method of `PdfForm` to validate the digital signatures in a PDF document. Configure the trusted certificates and their passwords using `PdfSignatureValidationOptions`. +## Validate a signature from a signature field -The `validateSignatures` method returns the overall validation status and the individual validation results. The `isValid` property indicates whether all the validated signatures are valid. The `results` property contains details such as the signature name, signature status, document modification status, and revocation result for each signature. +You can validate an individual digital signature by accessing a specific signature field and validating its associated signature. This approach is useful when you need to check the validity of a particular signature in a document. -The following code example shows how to validate the digital signatures in an existing PDF document. +The following code example demonstrates how to retrieve a signature field, extract its signature, and validate it using trusted certificates. {% tabs %} {% highlight typescript tabtitle="TypeScript" %} -import { PdfDocument, PdfSignatureValidationOptions } from '@syncfusion/ej2-pdf'; +import { PdfDocument, PdfSignatureField, PdfSignature, PdfSignatureValidationOptions } from '@syncfusion/ej2-pdf'; // Load the signed PDF document. const document: PdfDocument = new PdfDocument(documentData); +// Get the first signature field from the form. +const field: PdfSignatureField = document.form.fieldAt(0) as PdfSignatureField; +// Get the signature from the field. +const signature: PdfSignature = field.getSignature(); // Configure the signature validation options. const options: PdfSignatureValidationOptions = { trustedCertificates: [certificateData], passwords: ['syncfusion'] }; -// Validate the digital signatures in the PDF document. -const validationResult = document.form.validateSignatures(options); -// Check the validation result of each signature. -if (validationResult.results !== null && - validationResult.results !== undefined) { - validationResult.results.forEach((result) => { - console.log('Signature name: ' + result.signatureName); - console.log('Signature valid: ' + result.isSignatureValid); - console.log('Signature status: ' + result.signatureStatus); - console.log('Document modified: ' + result.isDocumentModified); - console.log('Revocation result: ', result.revocationResult); - }); -} -// Get the overall signature validation status. -console.log('All signatures valid: ' + validationResult.isValid); +// Validate the signature. +const validationResult = signature.validate(options); +// Check the validation result. +console.log('Signature name: ' + validationResult.signatureName); +console.log('Signature valid: ' + validationResult.isSignatureValid); +console.log('Signature status: ' + validationResult.signatureStatus); +console.log('Document modified: ' + validationResult.isDocumentModified); +console.log('Revocation result: ', validationResult.revocationResult); // Destroy the document and release its resources. document.destroy(); @@ -1132,26 +1129,23 @@ document.destroy(); // Load the signed PDF document. const document = new ej.pdf.PdfDocument(documentData); +// Get the first signature field from the form. +const field = document.form.fieldAt(0); +// Get the signature from the field. +const signature = field.getSignature(); // Configure the signature validation options. const options = { trustedCertificates: [certificateData], passwords: ['syncfusion'] }; -// Validate the digital signatures in the PDF document. -const validationResult = document.form.validateSignatures(options); -// Check the validation result of each signature. -if (validationResult.results !== null && - validationResult.results !== undefined) { - validationResult.results.forEach((result) => { - console.log('Signature name: ' + result.signatureName); - console.log('Signature valid: ' + result.isSignatureValid); - console.log('Signature status: ' + result.signatureStatus); - console.log('Document modified: ' + result.isDocumentModified); - console.log('Revocation result: ', result.revocationResult); - }); -} -// Get the overall signature validation status. -console.log('All signatures valid: ' + validationResult.isValid); +// Validate the signature. +const validationResult = signature.validate(options); +// Check the validation result. +console.log('Signature name: ' + validationResult.signatureName); +console.log('Signature valid: ' + validationResult.isSignatureValid); +console.log('Signature status: ' + validationResult.signatureStatus); +console.log('Document modified: ' + validationResult.isDocumentModified); +console.log('Revocation result: ', validationResult.revocationResult); // Destroy the document and release its resources. document.destroy(); diff --git a/Document-Processing/PDF/PDF-Library/javascript/Encryption.md b/Document-Processing/PDF/PDF-Library/javascript/Encryption.md index 7b6b15a623..f3eba441e6 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/Encryption.md +++ b/Document-Processing/PDF/PDF-Library/javascript/Encryption.md @@ -14,11 +14,18 @@ A **user password** controls whether a user can open the PDF document. An **owne The supported encryption algorithms are: -- Rivest Cipher 4 (RC4) -- Advanced Encryption Standard (AES) +- Rivest Cipher 4 (RC4) - Legacy encryption standard, suitable for backward compatibility +- Advanced Encryption Standard (AES) - Modern encryption standard, recommended for new applications ## Working with RC4 encryption +RC4 encryption is a legacy encryption standard that provides 40-bit and 128-bit encryption strength. Use RC4 encryption when you need to maintain compatibility with older PDF readers or legacy systems that don't support AES encryption. For new applications, consider using AES encryption instead, as it offers stronger security. + +**Use cases for RC4 encryption:** +- Maintaining compatibility with PDF readers from before 2006 +- Legacy systems that explicitly require RC4 encryption +- Quick protection for non-critical documents that need basic encryption + You can encrypt a PDF document using 40-bit or 128-bit RC4 encryption by setting the `encryptionType` property of `PdfSecurityOptions` to `PdfEncryptionType.rc4Bit40` or `PdfEncryptionType.rc4Bit128`. The following example encrypts a new PDF document using RC4 128-bit encryption and a user password. @@ -28,54 +35,54 @@ The following example encrypts a new PDF document using RC4 128-bit encryption a import { PdfBrush, PdfDocument, PdfEncryptionType, PdfFontFamily, PdfFontStyle, PdfSecurityOptions, PdfStandardFont } from '@syncfusion/ej2-pdf'; -// Create a new PDF document. +// Create a new PDF document const document: PdfDocument = new PdfDocument(); -// Add a page to the document. +// Add a page to the document const page = document.addPage(); -// Embed the standard font used to draw text. +// Embed the standard font used to draw text const font: PdfStandardFont = document.embedFont(PdfFontFamily.helvetica, 12, PdfFontStyle.regular); -// Draw text on the page. +// Draw text on the page page.graphics.drawString( 'Encrypted with RC4 128-bit encryption', font, { x: 10, y: 20, width: 300, height: 50 }, new PdfBrush({ r: 0, g: 0, b: 0 }) ); -// Configure RC4 security using a user password. +// Configure RC4 security using a user password const options: PdfSecurityOptions = { encryptionType: PdfEncryptionType.rc4Bit128, userPassword: 'password' }; document.setSecurity(options); -// Save the encrypted PDF document. +// Save the encrypted PDF document document.save('Output.pdf'); -// Destroy the document and release its resources. +// Destroy the document and release its resources document.destroy(); {% endhighlight %} {% highlight javascript tabtitle="JavaScript" %} -// Create a new PDF document. +// Create a new PDF document const document = new ej.pdf.PdfDocument(); -// Add a page to the document. +// Add a page to the document const page = document.addPage(); -// Embed the standard font used to draw text. +// Embed the standard font used to draw text const font = document.embedFont(ej.pdf.PdfFontFamily.helvetica, 12, ej.pdf.PdfFontStyle.regular); -// Draw text on the page. +// Draw text on the page page.graphics.drawString( 'Encrypted with RC4 128-bit encryption', font, { x: 10, y: 20, width: 300, height: 50 }, new ej.pdf.PdfBrush({ r: 0, g: 0, b: 0 }) ); -// Configure RC4 security using a user password. +// Configure RC4 security using a user password document.setSecurity({ encryptionType: ej.pdf.PdfEncryptionType.rc4Bit128, userPassword: 'password' }); -// Save the encrypted PDF document. +// Save the encrypted PDF document document.save('Output.pdf'); -// Destroy the document and release its resources. +// Destroy the document and release its resources document.destroy(); {% endhighlight %} @@ -88,11 +95,12 @@ You can restrict document operations by specifying an owner password and permiss import { PdfDocument, PdfEncryptionType, PdfPermissionFlag, PdfSecurityOptions } from '@syncfusion/ej2-pdf'; -// Create a new PDF document. +// Create a new PDF document const document: PdfDocument = new PdfDocument(); -// Add a page to the document. +// Add a page to the document document.addPage(); -// Restrict the document operations using an owner password and permission flags. +// Restrict the document operations using an owner password and permission flags +// This allows only printing and accessibility-based content copying const options: PdfSecurityOptions = { encryptionType: PdfEncryptionType.rc4Bit128, ownerPassword: 'ownerPassword', @@ -101,19 +109,20 @@ const options: PdfSecurityOptions = { PdfPermissionFlag.accessibilityCopyContent }; document.setSecurity(options); -// Save the encrypted PDF document. +// Save the encrypted PDF document document.save('Output.pdf'); -// Destroy the document and release its resources. +// Destroy the document and release its resources document.destroy(); {% endhighlight %} {% highlight javascript tabtitle="JavaScript" %} -// Create a new PDF document. +// Create a new PDF document const document = new ej.pdf.PdfDocument(); -// Add a page to the document. +// Add a page to the document document.addPage(); -// Restrict the document operations using an owner password and permission flags. +// Restrict the document operations using an owner password and permission flags +// This allows only printing and accessibility-based content copying document.setSecurity({ encryptionType: ej.pdf.PdfEncryptionType.rc4Bit128, ownerPassword: 'ownerPassword', @@ -121,9 +130,9 @@ document.setSecurity({ permissions: ej.pdf.PdfPermissionFlag.print | ej.pdf.PdfPermissionFlag.accessibilityCopyContent }); -// Save the encrypted PDF document. +// Save the encrypted PDF document document.save('Output.pdf'); -// Destroy the document and release its resources. +// Destroy the document and release its resources document.destroy(); {% endhighlight %} @@ -133,6 +142,15 @@ N> When both user and owner passwords are specified, use different values for th ## Working with AES encryption +AES (Advanced Encryption Standard) encryption provides modern, strong encryption for your PDF documents. It offers multiple bit strengths (128-bit, 256-bit Revision 5, and 256-bit Revision 6) to balance security requirements with compatibility. AES is the recommended encryption method for new applications and sensitive documents. + +**Use cases for AES encryption:** +- Protecting confidential or sensitive documents +- Meeting compliance requirements (GDPR, HIPAA, etc.) +- Ensuring long-term document security +- Applications requiring strong, modern encryption standards +- Archival documents that need maximum security + You can encrypt a PDF document using AES encryption by setting the `encryptionType` property to a supported AES value such as `PdfEncryptionType.aesBit128`, `PdfEncryptionType.aesBit256Rev5`, or `PdfEncryptionType.aesBit256Rev6`. The following example encrypts a new PDF document using AES 256-bit Revision 5 encryption and an owner password. @@ -142,36 +160,40 @@ The following example encrypts a new PDF document using AES 256-bit Revision 5 e import { PdfDocument, PdfEncryptionType, PdfSecurityOptions } from '@syncfusion/ej2-pdf'; -// Create a new PDF document. +// Create a new PDF document const document: PdfDocument = new PdfDocument(); -// Add a page to the document. +// Add a page to the document document.addPage(); -// Configure AES security using an owner password. + +// Configure AES 256-bit encryption with owner password +// This provides strong, modern encryption recommended for sensitive documents const options: PdfSecurityOptions = { encryptionType: PdfEncryptionType.aesBit256Rev5, ownerPassword: 'ownerPassword' }; document.setSecurity(options); -// Save the encrypted PDF document. +// Save the encrypted PDF document document.save('Output.pdf'); -// Destroy the document and release its resources. +// Destroy the document and release its resources document.destroy(); {% endhighlight %} {% highlight javascript tabtitle="JavaScript" %} -// Create a new PDF document. +// Create a new PDF document const document = new ej.pdf.PdfDocument(); -// Add a page to the document. +// Add a page to the document document.addPage(); -// Configure AES security using an owner password. + +// Configure AES 256-bit encryption with owner password +// This provides strong, modern encryption recommended for sensitive documents document.setSecurity({ encryptionType: ej.pdf.PdfEncryptionType.aesBit256Rev5, ownerPassword: 'ownerPassword' }); -// Save the encrypted PDF document. +// Save the encrypted PDF document document.save('Output.pdf'); -// Destroy the document and release its resources. +// Destroy the document and release its resources document.destroy(); {% endhighlight %} @@ -179,39 +201,47 @@ document.destroy(); ## Decrypting an encrypted PDF document -The JavaScript PDF Library supports decrypting an encrypted PDF document by removing its owner or user password and restoring all supported permissions. This is particularly useful when you need to access or modify a secured PDF. +Decryption allows you to remove password protection from a PDF document by clearing both the user and owner passwords and restoring full permissions. This is useful when you need to access or modify a previously secured document, or when you need to change the security settings. + +**Use cases for decryption:** +- Removing security from documents you own +- Preparing documents for unrestricted distribution +- Converting from one encryption method to another +- Restoring full permissions to previously restricted documents {% tabs %} {% highlight typescript tabtitle="TypeScript" %} import { PdfDocument, PdfPermissionFlag, PdfSecurityOptions } from '@syncfusion/ej2-pdf'; -// Open the document using a valid password. +// Open the encrypted document using a valid password const document: PdfDocument = new PdfDocument(inputData, 'password'); -// Clear the passwords and restore all supported permissions. +// Clear the passwords and restore all supported permissions const options: PdfSecurityOptions = { userPassword: '', ownerPassword: '', - permissions: PdfPermissionFlag.default}; + permissions: PdfPermissionFlag.default +}; document.setSecurity(options); -// Save the decrypted PDF document. +// Save the decrypted PDF document document.save('Output.pdf'); -// Destroy the document and release its resources. +// Destroy the document and release its resources document.destroy(); {% endhighlight %} {% highlight javascript tabtitle="JavaScript" %} -// Load the encrypted PDF document data. +// Load the encrypted PDF document using the current password const document = new ej.pdf.PdfDocument(inputData, 'password'); -// Clear the passwords and restore all supported permissions. +// Clear the passwords and restore all supported permissions document.setSecurity({ userPassword: '', ownerPassword: '', - permissions: ej.pdf.PdfPermissionFlag.default}); -// Save the decrypted PDF document. + permissions: ej.pdf.PdfPermissionFlag.default +}); +// Save the decrypted PDF document document.save('Output.pdf'); -// Destroy the document and release its resources. +// Destroy the document and release its resources document.destroy(); {% endhighlight %} @@ -219,41 +249,52 @@ document.destroy(); ## Protect an existing PDF document -You can make the existing PDF document password protected by configuring the required encryption type and passwords, and saving the document. +This approach allows you to add encryption to documents that were previously unencrypted. It's useful when you already have PDF files and need to secure them retroactively. + +**Use cases for protecting existing documents:** +- Securing previously unencrypted documents +- Upgrading to stronger encryption on existing PDFs +- Adding access control to documents already in use +- Batch-protecting multiple documents with consistent security settings {% tabs %} {% highlight typescript tabtitle="TypeScript" %} import { PdfDocument, PdfEncryptionType, PdfSecurityOptions } from '@syncfusion/ej2-pdf'; -// Load the existing PDF document +// Load an existing PDF document that is currently unencrypted const document: PdfDocument = new PdfDocument(inputData); -// Protect the document using AES encryption. -const options: PdfSecurityOptions = { +// Configure encryption settings with both user and owner passwords +// User password: Required to open the document +// Owner password: Controls document permissions and modifications +const securityOptions: PdfSecurityOptions = { encryptionType: PdfEncryptionType.aesBit256Rev5, ownerPassword: 'ownerPassword256', userPassword: 'userPassword256' }; -document.setSecurity(options); -// Save the protected PDF document. -document.save('Output.pdf'); -// Destroy the document and release its resources. +// Apply encryption to the document +document.setSecurity(securityOptions); +// Save the now-encrypted document +document.save('ProtectedDocument.pdf'); +// Clean up resources document.destroy(); {% endhighlight %} {% highlight javascript tabtitle="JavaScript" %} -// Load an existing PDF document. +// Load an existing PDF document that is currently unencrypted const document = new ej.pdf.PdfDocument(inputData); -// Protect the document using AES encryption. +// Configure encryption settings with both user and owner passwords +// User password: Required to open the document +// Owner password: Controls document permissions and modifications document.setSecurity({ encryptionType: ej.pdf.PdfEncryptionType.aesBit256Rev5, ownerPassword: 'ownerPassword256', userPassword: 'userPassword256' }); -// Save the protected PDF document. -document.save('Output.pdf'); -// Destroy the document and release its resources. +// Save the now-encrypted document +document.save('ProtectedDocument.pdf'); +// Clean up resources document.destroy(); {% endhighlight %} @@ -261,37 +302,46 @@ document.destroy(); ## Changing the password of a PDF document -You can change the user password of an existing encrypted PDF document by loading it with the current password and applying the new password through `setSecurity`. +Update the security credentials of an existing encrypted document without modifying other security settings. This allows users or administrators to refresh authentication credentials periodically. + +**Use cases for password changes:** +- Periodic security credential rotation +- Responding to password compromise +- Updating passwords when personnel change +- Enforcing new password policies {% tabs %} {% highlight typescript tabtitle="TypeScript" %} import { PdfDocument, PdfSecurityOptions } from '@syncfusion/ej2-pdf'; -// Load the password-protected PDF document. +// Load the password-protected PDF document with the current password const document: PdfDocument = new PdfDocument(inputData, 'password'); -// Change the user password. -const options: PdfSecurityOptions = { +// Create new security options with the updated user password +// All other encryption settings remain unchanged +const securityOptions: PdfSecurityOptions = { userPassword: 'NewPassword' }; -document.setSecurity(options); -// Save the password-changed PDF document. -document.save('Output.pdf'); -// Destroy the document and release its resources. +// Apply the new password to the document +document.setSecurity(securityOptions); +// Save the document with the updated password +document.save('PasswordChanged.pdf'); +// Clean up resources document.destroy(); {% endhighlight %} {% highlight javascript tabtitle="JavaScript" %} -// Load the password-protected PDF document. +// Load the password-protected PDF document with the current password const document = new ej.pdf.PdfDocument(inputData, 'password'); -// Change the user password. +// Create new security options with the updated user password +// All other encryption settings remain unchanged document.setSecurity({ userPassword: 'NewPassword' }); -// Save the password-changed PDF document. -document.save('Output.pdf'); -// Destroy the document and release its resources. +// Save the document with the updated password +document.save('PasswordChanged.pdf'); +// Clean up resources document.destroy(); {% endhighlight %} @@ -299,6 +349,14 @@ document.destroy(); ## View document permission flags +Inspect the permissions currently set on a secured PDF document to understand which operations users can perform. This is essential for auditing document security and verifying that restrictions are correctly applied. + +**Use cases for viewing permissions:** +- Auditing document security settings +- Verifying permission restrictions before distribution +- Understanding which operations are permitted on received documents +- Programmatically checking document access levels + The `permissions` property of `PdfDocument` returns the permission flags available in the loaded PDF document. Since `PdfPermissionFlag` is a bitwise enumeration, use the bitwise AND operator to determine whether an individual permission is enabled. {% tabs %} @@ -306,54 +364,51 @@ The `permissions` property of `PdfDocument` returns the permission flags availab import { PdfDocument, PdfPermissionFlag } from '@syncfusion/ej2-pdf'; -// Load the secured PDF document. +// Load the secured PDF document with the required password const document: PdfDocument = new PdfDocument(inputData, 'password'); -// Get the document permission flags. +// Get the permission flags from the document +// PdfPermissionFlag is a bitwise enumeration, so use bitwise AND (&) to check each flag const permissions: PdfPermissionFlag = document.permissions; -// Check the required permission flags. -const canPrint: boolean = - (permissions & PdfPermissionFlag.print) !== 0; -const canCopyContent: boolean = - (permissions & PdfPermissionFlag.copyContent) !== 0; -const canEditContent: boolean = - (permissions & PdfPermissionFlag.editContent) !== 0; -const canEditAnnotations: boolean = - (permissions & PdfPermissionFlag.editAnnotations) !== 0; -const canFillFields: boolean = - (permissions & PdfPermissionFlag.fillFields) !== 0; -const canCopyForAccessibility: boolean = - (permissions & PdfPermissionFlag.accessibilityCopyContent) !== 0; -const canAssembleDocument: boolean = - (permissions & PdfPermissionFlag.assembleDocument) !== 0; -const canPrintInFullQuality: boolean = - (permissions & PdfPermissionFlag.fullQualityPrint) !== 0; -// Destroy the document and release its resources. +// Check individual permission flags +// Each permission is checked using bitwise AND operation to verify if enabled +const canPrint: boolean = (permissions & PdfPermissionFlag.print) !== 0; +const canCopyContent: boolean = (permissions & PdfPermissionFlag.copyContent) !== 0; +const canEditContent: boolean = (permissions & PdfPermissionFlag.editContent) !== 0; +const canEditAnnotations: boolean = (permissions & PdfPermissionFlag.editAnnotations) !== 0; +const canFillFields: boolean = (permissions & PdfPermissionFlag.fillFields) !== 0; +const canCopyForAccessibility: boolean = (permissions & PdfPermissionFlag.accessibilityCopyContent) !== 0; +const canAssembleDocument: boolean = (permissions & PdfPermissionFlag.assembleDocument) !== 0; +const canPrintInFullQuality: boolean = (permissions & PdfPermissionFlag.fullQualityPrint) !== 0; +// Use the permission flags for decision-making +console.log('Printing allowed: ' + canPrint); +console.log('Copying allowed: ' + canCopyContent); +console.log('Editing allowed: ' + canEditContent); +// Clean up resources document.destroy(); {% endhighlight %} {% highlight javascript tabtitle="JavaScript" %} -// Load the secured PDF document. +// Load the secured PDF document with the required password const document = new ej.pdf.PdfDocument(inputData, 'password'); -// Get the document permission flags. +// Get the permission flags from the document +// PdfPermissionFlag is a bitwise enumeration, so use bitwise AND (&) to check each flag const permissions = document.permissions; -// Check the required permission flags. +// Check individual permission flags +// Each permission is checked using bitwise AND operation to verify if enabled const canPrint = (permissions & ej.pdf.PdfPermissionFlag.print) !== 0; -const canCopyContent = - (permissions & ej.pdf.PdfPermissionFlag.copyContent) !== 0; -const canEditContent = - (permissions & ej.pdf.PdfPermissionFlag.editContent) !== 0; -const canEditAnnotations = - (permissions & ej.pdf.PdfPermissionFlag.editAnnotations) !== 0; -const canFillFields = - (permissions & ej.pdf.PdfPermissionFlag.fillFields) !== 0; -const canCopyForAccessibility = - (permissions & ej.pdf.PdfPermissionFlag.accessibilityCopyContent) !== 0; -const canAssembleDocument = - (permissions & ej.pdf.PdfPermissionFlag.assembleDocument) !== 0; -const canPrintInFullQuality = - (permissions & ej.pdf.PdfPermissionFlag.fullQualityPrint) !== 0; -// Destroy the document and release its resources. +const canCopyContent = (permissions & ej.pdf.PdfPermissionFlag.copyContent) !== 0; +const canEditContent = (permissions & ej.pdf.PdfPermissionFlag.editContent) !== 0; +const canEditAnnotations = (permissions & ej.pdf.PdfPermissionFlag.editAnnotations) !== 0; +const canFillFields = (permissions & ej.pdf.PdfPermissionFlag.fillFields) !== 0; +const canCopyForAccessibility = (permissions & ej.pdf.PdfPermissionFlag.accessibilityCopyContent) !== 0; +const canAssembleDocument = (permissions & ej.pdf.PdfPermissionFlag.assembleDocument) !== 0; +const canPrintInFullQuality = (permissions & ej.pdf.PdfPermissionFlag.fullQualityPrint) !== 0; +// Use the permission flags for decision-making +console.log('Printing allowed: ' + canPrint); +console.log('Copying allowed: ' + canCopyContent); +console.log('Editing allowed: ' + canEditContent); +// Clean up resources document.destroy(); {% endhighlight %} @@ -372,39 +427,55 @@ The following flags can be combined when configuring document permissions: ## Change the permissions of a PDF document -You can change the permissions of an existing secured PDF document using the `permissions` property of `PdfSecurityOptions`. Load the document using a valid password before updating the permission flags. +Modify the access restrictions on an existing secured document to grant or restrict specific operations. This allows fine-grained control over what users can do with your PDF documents. + +**Use cases for changing permissions:** +- Restricting editing capabilities while allowing printing +- Limiting copy/paste operations to prevent content theft +- Preventing form field modifications on locked forms +- Allowing printing but restricting annotation abilities +- Disabling high-quality printing for premium documents + +Load the document using a valid password before updating the permission flags using the `permissions` property of `PdfSecurityOptions`. {% tabs %} {% highlight typescript tabtitle="TypeScript" %} import { PdfDocument, PdfPermissionFlag, PdfSecurityOptions } from '@syncfusion/ej2-pdf'; -// Load the secured PDF document. +// Load the secured PDF document using the owner password +// The owner password is required to modify document permissions const document: PdfDocument = new PdfDocument(inputData, 'syncfusion'); -// Allow content copying and document assembly. -const options: PdfSecurityOptions = { +// Configure new permissions using bitwise OR (|) to combine multiple flags +// This example allows content copying and document assembly +// Use the bitwise OR operator to combine multiple permission flags +const securityOptions: PdfSecurityOptions = { permissions: PdfPermissionFlag.copyContent | PdfPermissionFlag.assembleDocument }; -document.setSecurity(options); -// Save the PDF document with the updated permissions. -document.save('Output.pdf'); -// Destroy the document and release its resources. +// Apply the new permission settings to the document +document.setSecurity(securityOptions); +// Save the document with updated permissions +document.save('UpdatedPermissions.pdf'); +// Clean up resources document.destroy(); {% endhighlight %} {% highlight javascript tabtitle="JavaScript" %} -// Load the secured PDF document. +// Load the secured PDF document using the owner password +// The owner password is required to modify document permissions const document = new ej.pdf.PdfDocument(inputData, 'syncfusion'); -// Allow content copying and document assembly. +// Configure new permissions using bitwise OR (|) to combine multiple flags +// This example allows content copying and document assembly +// Use the bitwise OR operator to combine multiple permission flags document.setSecurity({ permissions: ej.pdf.PdfPermissionFlag.copyContent | ej.pdf.PdfPermissionFlag.assembleDocument }); -// Save the PDF document with the updated permissions. -document.save('Output.pdf'); -// Destroy the document and release its resources. +// Save the document with updated permissions +document.save('UpdatedPermissions.pdf'); +// Clean up resources document.destroy(); {% endhighlight %} @@ -412,33 +483,47 @@ document.destroy(); ## How to determine whether a PDF document is password protected -To determine whether a PDF document requires a password, try loading it without a password and handle the error raised for an encrypted document. Avoid depending on an exact error-message string because the message can change between versions. +To determine whether a PDF document requires a password, try loading it without a password and check if the error message indicates the document is encrypted. This approach allows you to programmatically detect password-protected documents. {% tabs %} {% highlight typescript tabtitle="TypeScript" %} import { PdfDocument } from '@syncfusion/ej2-pdf'; -// Load the PDF document data let isPasswordProtected: boolean = false; try { - // Loading without a password fails when a valid password is required. - let document = new PdfDocument(inputData); -} catch (error.message == 'Cannot open an encrypted document. The password is invalid.') { - isPasswordProtected = true; + // Attempt to load the document without providing a password + const document: PdfDocument = new PdfDocument(inputData); + // If we reach here, the document is not password protected + isPasswordProtected = false; + document.destroy(); +} catch (error: any) { + // Check if the error message indicates an encrypted document requiring a password + if (error.message === 'Cannot open an encrypted document. The password is invalid.') { + isPasswordProtected = true; + } } +// Use isPasswordProtected to determine next action +console.log('Password protected: ' + isPasswordProtected); {% endhighlight %} {% highlight javascript tabtitle="JavaScript" %} -// Load the PDF document data. let isPasswordProtected = false; try { - // Loading without a password fails when a valid password is required. - let document = new ej.pdf.PdfDocument(inputData); -} catch (error.message == 'Cannot open an encrypted document. The password is invalid.') { - isPasswordProtected = true; + // Attempt to load the document without providing a password + const document = new ej.pdf.PdfDocument(inputData); + // If we reach here, the document is not password protected + isPasswordProtected = false; + document.destroy(); +} catch (error) { + // Check if the error message indicates an encrypted document requiring a password + if (error.message === 'Cannot open an encrypted document. The password is invalid.') { + isPasswordProtected = true; + } } +// Use isPasswordProtected to determine next action +console.log('Password protected: ' + isPasswordProtected); {% endhighlight %} {% endtabs %} @@ -456,6 +541,21 @@ The following table describes the values available after loading a secured PDF d | PDF document secured only with an owner password | Owner password | Returns null | Returns the owner password | | PDF document secured only with a user password | User password | Returns the user password | Returns the owner password. The owner password is the same as the user password and grants full permission to the user. | +## Encryption API Reference + +The following table summarizes the key methods and options for encryption operations in the JavaScript PDF Library: + +| Operation | Method/Property | Description | Use Case | +|-----------|-----------------|-------------|----------| +| **Encrypt a new document with RC4** | `PdfDocument.setSecurity({ encryptionType: PdfEncryptionType.rc4Bit128, userPassword: 'password' })` | Encrypts a document using 128-bit RC4 encryption with a user password | Legacy system compatibility, backward compatibility with older PDF readers | +| **Encrypt with permissions (RC4)** | `PdfDocument.setSecurity({ encryptionType: PdfEncryptionType.rc4Bit128, ownerPassword: 'owner', userPassword: 'user', permissions: PdfPermissionFlag.print \| ... })` | Restricts document operations using owner password and permission flags | Fine-grained access control on legacy documents | +| **Encrypt with AES (recommended)** | `PdfDocument.setSecurity({ encryptionType: PdfEncryptionType.aesBit256Rev5, ownerPassword: 'password' })` | Encrypts a document using modern AES 256-bit encryption | Securing sensitive/confidential documents, compliance requirements | +| **Decrypt a document** | `PdfDocument.setSecurity({ userPassword: '', ownerPassword: '', permissions: PdfPermissionFlag.default })` | Removes password protection and restores all permissions | Removing security from owned documents, unrestricted distribution | +| **Protect existing document** | `new PdfDocument(inputData)` + `setSecurity({ encryptionType: PdfEncryptionType.aesBit256Rev5, ... })` | Adds encryption to an unencrypted PDF document | Retroactive security, batch encryption of existing files | +| **Change password** | `new PdfDocument(inputData, 'currentPassword')` + `setSecurity({ userPassword: 'NewPassword' })` | Updates authentication credentials without changing encryption type | Credential rotation, security policy updates | +| **View permissions** | `document.permissions` + bitwise AND checks | Retrieves permission flags from an encrypted document | Auditing security settings, verifying restrictions | +| **Change permissions** | `PdfDocument.setSecurity({ permissions: PdfPermissionFlag.copyContent \| PdfPermissionFlag.assembleDocument })` | Modifies access restrictions on secured documents | Restricting editing, preventing copying, limiting operations | + ## Additional Resources - [JavaScript PDF Library](https://www.syncfusion.com/document-sdk/javascript-pdf-library) diff --git a/Document-Processing/PDF/PDF-Library/javascript/Text-Extraction.md b/Document-Processing/PDF/PDF-Library/javascript/Text-Extraction.md index b1680ec73b..6221135ad5 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/Text-Extraction.md +++ b/Document-Processing/PDF/PDF-Library/javascript/Text-Extraction.md @@ -20,7 +20,9 @@ N> The `@syncfusion/ej2-pdf-data-extract` add-on package also powers the redacti ## Working with basic text extraction synchronously -This example demonstrates how to extract plain text from a PDF document synchronously using the [PdfDataExtractor](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor) class and the `extractTextSync` method. Basic text extraction retrieves text content from the entire PDF document immediately. +The `extractTextSync` method provides the simplest way to retrieve all text content from a PDF document in a single operation. This synchronous approach is ideal when you need immediate access to the complete text and your document size permits blocking execution. + +The following example demonstrates how to extract plain text from a PDF document synchronously using the [PdfDataExtractor](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor) class: {% tabs %} {% highlight typescript tabtitle="TypeScript" %} @@ -56,16 +58,16 @@ document.destroy(); {% endhighlight %} {% endtabs %} -### Basic text extraction +## Extract text from a specific page range in a PDF document synchronously -| Method | Return Type | Description | -|---|---|---| -| [`extractTextSync()`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextsync) | `string` | Extracts plain text synchronously from all pages of the PDF document. | -| [`extractText()`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttext) | `Promise` | Extracts plain text asynchronously from all pages of the PDF document. | +When working with large PDF documents, you may want to extract text from specific pages rather than processing the entire document. The `extractTextSync` method accepts optional parameters to define the start and end page indices, allowing you to retrieve text content from a targeted page range. -## Extract text from a specific page range in a PDF document synchronously +This approach is useful for: +- Processing specific chapters or sections of a document +- Reducing memory usage with large files +- Focusing extraction on relevant content -This example demonstrates how to synchronously extract text from a PDF document by specifying a start and end page index. This approach allows you to retrieve text content from a defined range of pages for processing or analysis. +The following example shows how to extract text from a defined page range synchronously: {% tabs %} {% highlight typescript tabtitle="TypeScript" %} @@ -96,16 +98,11 @@ document.destroy(); {% endhighlight %} {% endtabs %} -### Text extraction from a specific page range - -| Method | Return Type | Description | -|---|---|---| -| [`extractTextSync(options)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextsync) | `string` | Extracts plain text synchronously from the page range specified using `startPageIndex` and `endPageIndex`. | -| [`extractText(options)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttext) | `Promise` | Extracts plain text asynchronously from the page range specified using `startPageIndex` and `endPageIndex`. | - ## Working with layout-based text extraction synchronously -This example demonstrates how to extract text from a PDF document synchronously using the [PdfDataExtractor](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor) class with layout-based options. Layout-based extraction preserves the visual structure of the source document, including line breaks and spacing. +For documents where the visual structure and formatting are important to the extracted content, use layout-based text extraction. This method preserves the original document layout, including line breaks, spacing, and paragraph structure—making the extracted text more readable and maintaining its logical organization. + +The following example demonstrates how to extract text with layout preservation using the [PdfDataExtractor](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor) class: {% tabs %} {% highlight typescript tabtitle="TypeScript" %} @@ -136,20 +133,31 @@ document.destroy(); {% endhighlight %} {% endtabs %} -### Layout-based text extraction +## Text extraction with bounds -| Method | Return Type | Description | -|---|---|---| -| [`extractTextSync(options)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextsync) | `string` | Extracts text synchronously while preserving the visual layout when `isLayout` is set to `true`. | -| [`extractText(options)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttext) | `Promise` | Extracts text asynchronously while preserving the visual layout when `isLayout` is set to `true`. | +For advanced use cases that require precise spatial information about text content, use bounds-based extraction. This method returns detailed hierarchical information including positional coordinates (bounds), font properties, size, style, and color for each text element. -## Text extraction with bounds +Bounds-based extraction is essential for: +- Highlighting or annotating specific text locations +- Implementing search result highlighting +- Applying redactions to sensitive content +- Programmatically identifying text regions for document analysis +- Building custom search interfaces with visual feedback + +The [extractTextLinesSync](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlinessync) and [extractTextLines](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlines) methods return hierarchical collections of [TextLine](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textline), [TextWord](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textword), and [TextGlyph](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textglyph) objects, allowing you to work with text at different levels of granularity. + +### Working with Lines -The following sections describe how to extract text along with positional and typographic information using the [extractTextLinesSync](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlinessync) and [extractTextLines](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlines) methods. The method returns a hierarchical collection of [TextLine](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textline), [TextWord](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textword), and [TextGlyph](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textglyph) objects. +Line-level extraction provides structured text content organized by line, with position and formatting information for each line. This granularity is useful for analyzing text structure, implementing line-based highlighting, or processing documents with multi-column layouts. -### Working with lines synchronously +The [extractTextLinesSync](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlinessync) method returns a collection of [TextLine](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textline) objects. Each TextLine object contains: +- **text**: The complete text content of the line +- **bounds**: The rectangular region occupied by the line on the page +- **pageIndex**: Which page the line appears on +- **fontName, fontStyle, fontSize**: Typographic information for the line +- **words**: A collection of word-level objects within the line -This example demonstrates how to extract text from a PDF page based on individual lines. The [extractTextLinesSync](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlinessync) method returns a collection of [TextLine](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textline) objects, allowing precise access to text content line by line. +The following example demonstrates line-level text extraction: {% tabs %} {% highlight typescript tabtitle="TypeScript" %} @@ -214,18 +222,17 @@ document.destroy(); {% endhighlight %} {% endtabs %} -### Working with lines +### Working with Words -| Method | Return Type | Description | -|---|---|---| -| [`extractTextLinesSync()`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlinessync) | `TextLine[]` | Extracts text lines synchronously from all pages of the PDF document. | -| [`extractTextLinesSync(options)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlinessync) | `TextLine[]` | Extracts text lines synchronously from the page range specified in the extraction options. | -| [`extractTextLines()`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlines) | `Promise` | Extracts text lines asynchronously from all pages of the PDF document. | -| [`extractTextLines(options)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlines) | `Promise` | Extracts text lines asynchronously from the page range specified in the extraction options. | +Word-level extraction provides fine-grained access to individual words with their positions and properties. This is particularly useful for text highlighting, word-based search result visualization, spell-checking integration, or linguistic analysis. -### Working with words synchronously +Each [TextLine](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textline) contains a collection of [TextWord](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textword) objects. Each TextWord object includes: +- **text**: The word content +- **bounds**: The position of the word on the page +- **fontName, fontStyle, fontSize**: Font properties for the word +- **glyphs**: Individual character-level data within the word -This example demonstrates how to extract words from a PDF document using the [extractTextLinesSync](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlinessync) method. Each line contains a collection of [TextWord](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textword) objects. +The following example demonstrates how to access and process word-level data: {% tabs %} {% highlight typescript tabtitle="TypeScript" %} @@ -288,18 +295,22 @@ document.destroy(); {% endhighlight %} {% endtabs %} -### Working with words +### Working with characters synchronously -| Method | Return Type | Description | -|---|---|---| -| `extractTextWordsSync()` | `TextWord[]` | Extracts text words synchronously from all pages of the PDF document. | -| `extractTextWordsSync(options)` | `TextWord[]` | Extracts text words synchronously from the page range specified in the extraction options. | -| `extractTextWords()` | `Promise` | Extracts text words asynchronously from all pages of the PDF document. | -| `extractTextWords(options)` | `Promise` | Extracts text words asynchronously from the page range specified in the extraction options. | +Character-level (glyph) extraction provides the most granular level of detail, allowing you to access individual characters with their exact positions, colors, and font properties. This level of detail is essential for: +- Precise text highlighting at the character level +- Color-aware text extraction +- Detecting rotated or specially formatted characters +- Building advanced search and annotation features -### Working with characters synchronously +Use the [extractTextLinesSync](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlinessync) method to retrieve character-level data. Each [TextGlyph](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/textglyph) object contains: +- **text**: The character content +- **bounds**: Precise position of the character +- **fontName, fontStyle, fontSize**: Font properties +- **color**: The text color +- **isRotated**: Whether the character is rotated -You can retrieve a single character and its properties, including bounds, font name, font size, and text color, using the [extractTextLinesSync](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#extracttextlinessync) method. Refer to the code sample below. +The following example demonstrates character-level extraction: {% tabs %} {% highlight typescript tabtitle="TypeScript" %} @@ -370,18 +381,24 @@ document.destroy(); {% endhighlight %} {% endtabs %} -### Working with characters +## Text Extraction API Reference -| Method | Return Type | Description | -|---|---|---| -| `extractTextCharactersSync()` | `TextGlyph[]` | Extracts text characters synchronously from all pages of the PDF document. | -| `extractTextCharactersSync(options)` | `TextGlyph[]` | Extracts text characters synchronously from the page range specified in the extraction options. | -| `extractTextCharacters()` | `Promise` | Extracts text characters asynchronously from all pages of the PDF document. | -| `extractTextCharacters(options)` | `Promise` | Extracts text characters asynchronously from the page range specified in the extraction options. | +The following table provides a comprehensive overview of all text extraction methods available in the `PdfDataExtractor` class: -### Find text synchronously +| Process | Method Signature | Return Type | Description | +|---|---|---|---| +| **Extract Text** | `extractTextSync()` | `string` | Extracts plain text synchronously from the entire PDF document. | +| **Extract Text** | `extractText()` | `Promise` | Extracts plain text asynchronously from the entire PDF document. | +| **Extract Text (Page Range)** | `extractTextSync(options: { startPageIndex: number; endPageIndex: number })` | `string` | Extracts plain text synchronously from a specified page range using start and end page indices. | +| **Extract Text (Page Range)** | `extractText(options: { startPageIndex: number; endPageIndex: number })` | `Promise` | Extracts plain text asynchronously from a specified page range using start and end page indices. | +| **Extract Layout Text** | `extractTextSync(options: { isLayout: boolean })` | `string` | Extracts layout-based text synchronously, preserving the visual structure and spacing of the source document. | +| **Extract Layout Text** | `extractText(options: { isLayout: boolean })` | `Promise` | Extracts layout-based text asynchronously, preserving the visual structure and spacing of the source document. | +| **Extract Text with Bounds** | `extractTextLinesSync(options?: { startPageIndex?: number; endPageIndex?: number })` | `TextLine[]` | Extracts text synchronously with hierarchical line, word, and character-level information including positional bounds. | +| **Extract Text with Bounds** | `extractTextLines(options?: { startPageIndex?: number; endPageIndex?: number })` | `Promise` | Extracts text asynchronously with hierarchical line, word, and character-level information including positional bounds. | -The [findTextSync](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtext) method of the [PdfDataExtractor](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor) class locates specific text in a PDF document. The method returns the page index and rectangular bounds of each matching text occurrence synchronously.. These details are useful for highlighting text, applying redaction, adding annotations, navigating between search results, and building custom search features. +### Find text + +The `findTextSync` method of the `PdfDataExtractor` class locates specific text in a PDF document. The method returns the page index and rectangular bounds of each matching text occurrence synchronously. These details are useful for highlighting text, applying redaction, adding annotations, navigating between search results, and building custom search features. The following code example demonstrates how to search for text synchronously in a PDF document. @@ -397,7 +414,7 @@ let document: PdfDocument = new PdfDocument(data); // Initialize a new instance of the `PdfDataExtractor` class let extractor: PdfDataExtractor = new PdfDataExtractor(document); // Search for the specified text and retrieve the matching occurrences synchronously -let searchResults = extractor.findTextSync('document'); +let searchResults = extractor.findTextSync('PDF', { caseSensitive: false, wholeWord: false, startPageIndex: 0, endPageIndex: document.pageCount - 1 }); // Release document resources document.destroy(); @@ -410,7 +427,7 @@ var document = new ej.pdf.PdfDocument(data); // Initialize a new instance of the PdfDataExtractor class var extractor = new ej.pdfdataextract.PdfDataExtractor(document); // Search for the specified text and retrieve the matching occurrences synchronously -var searchResults = extractor.findTextSync('document'); +var searchResults = extractor.findTextSync('PDF', { caseSensitive: false, wholeWord: false, startPageIndex: 0, endPageIndex: document.pageCount - 1 }); // Release document resources document.destroy(); @@ -420,13 +437,13 @@ document.destroy(); N> Use `findTextSync` when the search result is required immediately. For large PDF documents, use the asynchronous `findText` method to avoid blocking execution. -## Search and get the bounds of text in a PDF document +## Search for multiple text values and get the bounds -You can search for specific text in a PDF document and retrieve the location of every occurrence using the [findTextSync](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtextsync) and [findText](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtext) methods of the [PdfDataExtractor](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor) class. +You can search for multiple text values in a PDF document and retrieve the location of every occurrence using the `findTextSync` and `findText` methods of the `PdfDataExtractor` class. The `findTextSync` method searches the PDF document synchronously, while the `findText` method performs the search asynchronously. Both methods accept optional text-search settings and return the searched text together with the bounding rectangles of all matching occurrences grouped by page number. The returned bounds can be used for highlighting, redaction, annotation, and document navigation. -The following code example demonstrates how to search for text synchronously using optional search parameters and retrieve the bounds of all matching occurrences in a PDF document. +The following code example demonstrates how to search for multiple text values synchronously using optional search parameters and retrieve the bounds of all matching occurrences in a PDF document. {% tabs %} @@ -439,12 +456,22 @@ import { PdfDataExtractor, TextSearchResult, Rectangle } from '@syncfusion/ej2-p let document: PdfDocument = new PdfDocument(data); // Initialize a new instance of the PdfDataExtractor class let extractor: PdfDataExtractor = new PdfDataExtractor(document); -// Search for the specified text synchronously using optional search parameters -let textSearch: TextSearchResult = extractor.findTextSync('hello', { caseSensitive: false, wholeWord: true, startPageIndex: 0, endPageIndex: document.pageCount - 1 }); -// Get the searched text -let searchText: string = textSearch.searchText; -// Get the matching bounds grouped by page number -let searchResults: Map<number, Rectangle[]> = textSearch.searchResults; +// Search for multiple text values synchronously using optional search parameters +let textSearchResults: TextSearchResult[] = extractor.findTextSync(['hello', 'world', 'PDF'], { caseSensitive: false, wholeWord: true, startPageIndex: 0, endPageIndex: document.pageCount - 1 }); +// Iterate through each search result +textSearchResults.forEach((textSearch: TextSearchResult) => { + // Get the searched text + let searchText: string = textSearch.searchText; + // Get the matching bounds grouped by page number + let searchResults: Map<number, Rectangle[]> = textSearch.searchResults; + // Process the results for each search term + searchResults.forEach((bounds: Rectangle[], pageIndex: number) => { + // Access bounds for each matching occurrence + bounds.forEach((bound: Rectangle) => { + console.log(`Found "${searchText}" on page ${pageIndex} at bounds:`, bound); + }); + }); +}); // Release document resources document.destroy(); @@ -456,12 +483,22 @@ document.destroy(); var document = new ej.pdf.PdfDocument(data); // Initialize a new instance of the PdfDataExtractor class var extractor = new ej.pdfdataextract.PdfDataExtractor(document); -// Search for the specified text synchronously using optional search parameters -var textSearch = extractor.findTextSync('hello', { caseSensitive: false, wholeWord: true, startPageIndex: 0, endPageIndex: document.pageCount - 1 }); -// Get the searched text -var searchText = textSearch.searchText; -// Get the matching bounds grouped by page number -var searchResults = textSearch.searchResults; +// Search for multiple text values synchronously using optional search parameters +var textSearchResults = extractor.findTextSync(['hello', 'world', 'PDF'], { caseSensitive: false, wholeWord: true, startPageIndex: 0, endPageIndex: document.pageCount - 1 }); +// Iterate through each search result +textSearchResults.forEach((textSearch) => { + // Get the searched text + var searchText = textSearch.searchText; + // Get the matching bounds grouped by page number + var searchResults = textSearch.searchResults; + // Process the results for each search term + searchResults.forEach((bounds, pageIndex) => { + // Access bounds for each matching occurrence + bounds.forEach((bound) => { + console.log(`Found "${searchText}" on page ${pageIndex} at bounds:`, bound); + }); + }); +}); // Release document resources document.destroy(); @@ -477,18 +514,12 @@ Use the following table to select the text-search method that matches your requi | Method | Return Type | Description | |---|---|---| -| [`findText(text: string)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtext) | Promise | Searches for the specified text asynchronously throughout the PDF document and returns all matching occurrences with their page indexes and bounds. | -| [`findText(text: string, options)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtext) | Promise | Searches for the specified text asynchronously using the supplied text-search options and returns the matching occurrences. | -| [`findTextSync(text: string)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtextsync) | Text search result collection | Searches for the specified text synchronously throughout the PDF document and returns all matching occurrences with their page indexes and bounds. | -| [`findTextSync(text: string, options)`](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtextsync) | Text search result collection | Searches for the specified text synchronously using the supplied text-search options and returns the matching occurrences. | -Use the following table for text search options in the find text method. - -| Optional parameter | Type | Default value | Description | -| ------------------ | --------- | --------------- | ----------------------------------------------------------------------------------- | -| `caseSensitive` | `boolean` | `false` | Specifies whether the search must match uppercase and lowercase characters exactly. | -| `wholeWord` | `boolean` | `false` | Specifies whether the search must match only complete words. | -| `startPageIndex` | `number` | `0` | Specifies the zero-based index of the first page to search. | -| `endPageIndex` | `number` | Last page index | Specifies the zero-based index of the last page to search. | +| `findText(text: string)` | Promise | Searches for the specified text asynchronously throughout the PDF document and returns all matching occurrences with their page indexes and bounds. | +| `findText(text: string, options)` | Promise | Searches for the specified text asynchronously using the supplied text-search options and returns the matching occurrences. | +| `findTextSync(text: string)` | Text search result collection | Searches for the specified text synchronously throughout the PDF document and returns all matching occurrences with their page indexes and bounds. | +| `findTextSync(text: string, options)` | Text search result collection | Searches for the specified text synchronously using the supplied text-search options and returns the matching occurrences. | + +Use the following table for text search options in the find text method. | ## Additional Resources diff --git a/Document-Processing/PDF/PDF-Library/javascript/Text.md b/Document-Processing/PDF/PDF-Library/javascript/Text.md index c63d138dbd..1d78778541 100644 --- a/Document-Processing/PDF/PDF-Library/javascript/Text.md +++ b/Document-Processing/PDF/PDF-Library/javascript/Text.md @@ -583,47 +583,6 @@ document.destroy(); {% endhighlight %} {% endtabs %} -## Search and get the bounds of text in a PDF document - -You can search for specific text in a PDF document and retrieve the location of every occurrence using the [findText](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor#findtext) method of the [PdfDataExtractor](https://ej2.syncfusion.com/documentation/api/pdf-data-extract/pdfdataextractor) class. - -The `findText` method searches the PDF document for the specified text and returns the matching text occurrences along with their page index and bounding rectangles. The returned bounds can be used for operations such as highlighting, redaction, annotation, and document navigation. - -The following code example demonstrates how to search for text and retrieve the bounds of all matching occurrences in a PDF document. - -{% tabs %} - -{% highlight typescript tabtitle="TypeScript" %} - -import { PdfDocument } from '@syncfusion/ej2-pdf'; -import { PdfDataExtractor } from '@syncfusion/ej2-pdf-data-extract'; - -// Load an existing PDF document -let document: PdfDocument = new PdfDocument(data); -// Initialize a new instance of the `PdfDataExtractor` class -let extractor: PdfDataExtractor = new PdfDataExtractor(document); -// Search for the specified text and retrieve all matching occurrences -let textSearch = extractor.findText('hello'); -// Release document resources -document.destroy(); - -{% endhighlight %} - -{% highlight javascript tabtitle="JavaScript" %} - -// Load an existing PDF document -var document = new ej.pdf.PdfDocument(data); -// Initialize a new instance of the PdfDataExtractor class -var extractor = new ej.pdfdataextract.PdfDataExtractor(document); -// Search for the specified text and retrieve all matching occurrences -var textSearch = extractor.findText('hello'); -// Release document resources -document.destroy(); - -{% endhighlight %} - -{% endtabs %} - ## Additional Resources - [JavaScript PDF Library](https://www.syncfusion.com/document-sdk/javascript-pdf-library)