From f907754e2d3f0937d0f7a2c01ab357956abe7cb0 Mon Sep 17 00:00:00 2001 From: Deepika Date: Tue, 15 Sep 2026 12:56:02 +0530 Subject: [PATCH 1/5] Added the sample for split PDF --- angular/split-pdf/.editorconfig | 17 +++ angular/split-pdf/.gitignore | 44 +++++++ angular/split-pdf/.prettierrc | 12 ++ angular/split-pdf/README.md | 117 +++++++++++++++++++ angular/split-pdf/angular.json | 74 ++++++++++++ angular/split-pdf/package.json | 33 ++++++ angular/split-pdf/public/favicon.ico | Bin 0 -> 15086 bytes angular/split-pdf/src/app/app.config.ts | 10 ++ angular/split-pdf/src/app/app.css | 0 angular/split-pdf/src/app/app.html | 70 +++++++++++ angular/split-pdf/src/app/app.routes.ts | 3 + angular/split-pdf/src/app/app.spec.ts | 24 ++++ angular/split-pdf/src/app/app.ts | 147 ++++++++++++++++++++++++ angular/split-pdf/src/index.html | 13 +++ angular/split-pdf/src/main.ts | 9 ++ angular/split-pdf/src/styles.css | 1 + angular/split-pdf/tsconfig.app.json | 14 +++ angular/split-pdf/tsconfig.json | 31 +++++ angular/split-pdf/tsconfig.spec.json | 14 +++ 19 files changed, 633 insertions(+) create mode 100644 angular/split-pdf/.editorconfig create mode 100644 angular/split-pdf/.gitignore create mode 100644 angular/split-pdf/.prettierrc create mode 100644 angular/split-pdf/README.md create mode 100644 angular/split-pdf/angular.json create mode 100644 angular/split-pdf/package.json create mode 100644 angular/split-pdf/public/favicon.ico create mode 100644 angular/split-pdf/src/app/app.config.ts create mode 100644 angular/split-pdf/src/app/app.css create mode 100644 angular/split-pdf/src/app/app.html create mode 100644 angular/split-pdf/src/app/app.routes.ts create mode 100644 angular/split-pdf/src/app/app.spec.ts create mode 100644 angular/split-pdf/src/app/app.ts create mode 100644 angular/split-pdf/src/index.html create mode 100644 angular/split-pdf/src/main.ts create mode 100644 angular/split-pdf/src/styles.css create mode 100644 angular/split-pdf/tsconfig.app.json create mode 100644 angular/split-pdf/tsconfig.json create mode 100644 angular/split-pdf/tsconfig.spec.json diff --git a/angular/split-pdf/.editorconfig b/angular/split-pdf/.editorconfig new file mode 100644 index 0000000..f166060 --- /dev/null +++ b/angular/split-pdf/.editorconfig @@ -0,0 +1,17 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single +ij_typescript_use_double_quotes = false + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/angular/split-pdf/.gitignore b/angular/split-pdf/.gitignore new file mode 100644 index 0000000..854acd5 --- /dev/null +++ b/angular/split-pdf/.gitignore @@ -0,0 +1,44 @@ +# See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. + +# Compiled output +/dist +/tmp +/out-tsc +/bazel-out + +# Node +/node_modules +npm-debug.log +yarn-error.log + +# IDEs and editors +.idea/ +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# Visual Studio Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/mcp.json +.history/* + +# Miscellaneous +/.angular/cache +.sass-cache/ +/connect.lock +/coverage +/libpeerconnection.log +testem.log +/typings +__screenshots__/ + +# System files +.DS_Store +Thumbs.db diff --git a/angular/split-pdf/.prettierrc b/angular/split-pdf/.prettierrc new file mode 100644 index 0000000..d6c16d7 --- /dev/null +++ b/angular/split-pdf/.prettierrc @@ -0,0 +1,12 @@ +{ + "printWidth": 100, + "singleQuote": true, + "overrides": [ + { + "files": "*.html", + "options": { + "parser": "angular" + } + } + ] +} diff --git a/angular/split-pdf/README.md b/angular/split-pdf/README.md new file mode 100644 index 0000000..4aff67e --- /dev/null +++ b/angular/split-pdf/README.md @@ -0,0 +1,117 @@ +# How to Split a PDF Document in the JavaScript PDF Library + +This sample demonstrates how to split a PDF document using the `Syncfusion JavaScript PDF Library`. + +## Features Demonstrated + +This sample shows how to: + +- Load an existing PDF document from a URL. +- Split a PDF document into individual pages. +- Split a PDF document by specified page ranges. +- Split a PDF document into smaller documents with a fixed number of pages. +- Save and download the generated PDF documents. +- Handle split operations using the document split event. +- Release resources after processing the PDF document. + +## Project Structure + +### app.ts + +The `splitIntoIndividualPages()` method performs the following operations: + +- Loads the input PDF document. +- Splits the document into individual pages. +- Generates a separate PDF document for each page. +- Downloads each generated PDF file. +- Releases resources by destroying the PDF document instance. + +The `splitPageRange()` method performs the following operations: + +- Loads the input PDF document. +- Splits the document based on the specified page ranges. +- Creates a separate PDF document for each page range. +- Downloads the generated PDF files. +- Releases resources after processing. + +The `splitFixedNumber()` method performs the following operations: + +- Loads the input PDF document. +- Splits the document into smaller PDF documents containing a fixed number of pages. +- Downloads each generated PDF file. +- Releases resources after processing. + +The `documentSplitEvent()` event handler: + +- Receives the generated PDF document data. +- Converts the document data to a `Uint8Array`. +- Creates a Blob object from the PDF data. +- Downloads the generated PDF document. + +The `getInputBytes()` helper method: + +- Downloads the PDF document from the specified URL. +- Converts the document to a `Uint8Array`. +- Returns the PDF data for further processing. + +### app.html + +The user interface includes: + +- A **Split into Individual Pages** button. +- A **Split by Page Range** button. +- A **Split by Fixed Number** button. +- A simple layout to trigger the split operations. + +When a button is clicked, the application performs the selected split operation and downloads the generated PDF files. + +## Prerequisites + +Ensure the following software is installed: + +- Node.js +- Angular CLI + +## Installation + +Install the Syncfusion JavaScript PDF Library package: + +```bash +npm install @syncfusion/ej2-pdf +``` + +## Running the Application + +Install the project dependencies: + +```bash +npm install +``` + +Start the Angular development server: + +```bash +ng serve +``` + +Then open: + +```text +http://localhost:4200/ +``` + +Use one of the available buttons to perform the desired split operation. The generated PDF documents will be downloaded automatically. + +## Additional Resources + +### Documentation + +[JavaScript PDF Library Documentation](https://help.syncfusion.com/document-processing/pdf/pdf-library/javascript/split-documents) + +### Online Demos + +[JavaScript PDF Library Demos](https://document.syncfusion.com/demos/pdf/angular/#/tailwind3/pdf/split-pdf) + +### Product Page + +[JavaScript PDF Library Product Page](https://www.syncfusion.com/document-sdk/javascript-pdf-library) \ No newline at end of file diff --git a/angular/split-pdf/angular.json b/angular/split-pdf/angular.json new file mode 100644 index 0000000..6bb8b38 --- /dev/null +++ b/angular/split-pdf/angular.json @@ -0,0 +1,74 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "cli": { + "packageManager": "npm", + "analytics": "b11d304c-687a-4245-88b2-1afb5c1c7af5" + }, + "newProjectRoot": "projects", + "projects": { + "split-pdf": { + "projectType": "application", + "schematics": {}, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular/build:application", + "options": { + "browser": "src/main.ts", + "tsConfig": "tsconfig.app.json", + "assets": [ + { + "glob": "**/*", + "input": "public" + } + ], + "styles": [ + "src/styles.css" + ] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kB", + "maximumError": "1MB" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "4kB", + "maximumError": "8kB" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular/build:dev-server", + "configurations": { + "production": { + "buildTarget": "split-pdf:build:production" + }, + "development": { + "buildTarget": "split-pdf:build:development" + } + }, + "defaultConfiguration": "development" + }, + "test": { + "builder": "@angular/build:unit-test" + } + } + } + } +} diff --git a/angular/split-pdf/package.json b/angular/split-pdf/package.json new file mode 100644 index 0000000..0f18515 --- /dev/null +++ b/angular/split-pdf/package.json @@ -0,0 +1,33 @@ +{ + "name": "split-pdf", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "test": "ng test" + }, + "private": true, + "packageManager": "npm@11.19.0", + "dependencies": { + "@angular/common": "^22.1.0", + "@angular/compiler": "^22.1.0", + "@angular/core": "^22.1.0", + "@angular/forms": "^22.1.0", + "@angular/platform-browser": "^22.1.0", + "@angular/router": "^22.1.0", + "@syncfusion/ej2-pdf": "*", + "rxjs": "~7.8.0", + "tslib": "^2.3.0" + }, + "devDependencies": { + "@angular/build": "^22.1.6", + "@angular/cli": "^22.1.6", + "@angular/compiler-cli": "^22.1.0", + "jsdom": "^28.0.0", + "prettier": "^3.8.1", + "typescript": "~6.0.2", + "vitest": "^4.0.8" + } +} diff --git a/angular/split-pdf/public/favicon.ico b/angular/split-pdf/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..57614f9c967596fad0a3989bec2b1deff33034f6 GIT binary patch literal 15086 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 Nr__JTFzvMr^FKp4S3v*( literal 0 HcmV?d00001 diff --git a/angular/split-pdf/src/app/app.config.ts b/angular/split-pdf/src/app/app.config.ts new file mode 100644 index 0000000..e60fc79 --- /dev/null +++ b/angular/split-pdf/src/app/app.config.ts @@ -0,0 +1,10 @@ +import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core'; +import { provideRouter } from '@angular/router'; +import { routes } from './app.routes'; + +export const appConfig: ApplicationConfig = { + providers: [ + provideBrowserGlobalErrorListeners(), + provideRouter(routes) + ] +}; diff --git a/angular/split-pdf/src/app/app.css b/angular/split-pdf/src/app/app.css new file mode 100644 index 0000000..e69de29 diff --git a/angular/split-pdf/src/app/app.html b/angular/split-pdf/src/app/app.html new file mode 100644 index 0000000..c861114 --- /dev/null +++ b/angular/split-pdf/src/app/app.html @@ -0,0 +1,70 @@ +
+
+

+ Split PDF Documents +

+
+ + + + + + + +
+
+
\ No newline at end of file diff --git a/angular/split-pdf/src/app/app.routes.ts b/angular/split-pdf/src/app/app.routes.ts new file mode 100644 index 0000000..dc39edb --- /dev/null +++ b/angular/split-pdf/src/app/app.routes.ts @@ -0,0 +1,3 @@ +import { Routes } from '@angular/router'; + +export const routes: Routes = []; diff --git a/angular/split-pdf/src/app/app.spec.ts b/angular/split-pdf/src/app/app.spec.ts new file mode 100644 index 0000000..c0e7141 --- /dev/null +++ b/angular/split-pdf/src/app/app.spec.ts @@ -0,0 +1,24 @@ +import { TestBed } from '@angular/core/testing'; +import { App } from './app'; + +describe('App', () => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [App], + }) + .compileComponents(); + }); + + it('should create the app', () => { + const fixture = TestBed.createComponent(App); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); + + it('should render title', async () => { + const fixture = TestBed.createComponent(App); + await fixture.whenStable(); + const compiled = fixture.nativeElement as HTMLElement; + expect(compiled.querySelector('h1')?.textContent).toContain('Hello, split-pdf'); + }); +}); diff --git a/angular/split-pdf/src/app/app.ts b/angular/split-pdf/src/app/app.ts new file mode 100644 index 0000000..4de8abc --- /dev/null +++ b/angular/split-pdf/src/app/app.ts @@ -0,0 +1,147 @@ +import { Component } from '@angular/core'; +import { PdfDocument, PdfDocumentSplitEventArgs } from '@syncfusion/ej2-pdf'; +import { Save } from '@syncfusion/ej2-file-utils'; + +@Component({ + selector: 'app-root', + styleUrl: './app.css', + templateUrl: './app.html', +}) +export class App { + + // URL of the input PDF document + private readonly documentUrl = + 'https://cdn.syncfusion.com/content/pdf-resources/pdf-succinctly.pdf'; + + // Stores the PDF document as a byte array + private documentBytes!: Uint8Array; + + // Load the PDF document when the component initializes + async ngOnInit(): Promise { + this.documentBytes = await this.getInputBytes(this.documentUrl); + } + + /** + * Split the PDF document into individual pages + */ + async splitIntoIndividualPages(): Promise { + + // Load the input PDF document + const inputDocument = new PdfDocument(this.documentBytes); + + // Assign the split event handler + inputDocument.splitEvent = documentSplitEvent; + + // Split the document so that each page becomes a separate PDF + inputDocument.split(); + + // Triggered for each generated PDF document + function documentSplitEvent( + sender: PdfDocument, + args: PdfDocumentSplitEventArgs + ): void { + + // Convert the split PDF data to a Uint8Array + const pdfBytes = new Uint8Array(args.pdfData); + + // Download the generated PDF document + Save.save( + 'output_' + args.index + '.pdf', + new Blob( + [pdfBytes.buffer.slice(0)], + { type: 'application/pdf' } + ) + ); + } + + // Release resources used by the PDF document + inputDocument.destroy(); + } + + /** + * Split the PDF document based on specific page ranges + */ + async splitPageRange(): Promise { + + // Load the input PDF document + const inputDocument = new PdfDocument(this.documentBytes); + + // Assign the split event handler + inputDocument.splitEvent = documentSplitEvent; + + // Split the document into separate PDFs for the specified page ranges + inputDocument.splitByPageRanges([[1, 2], [3, 4]]); + + // Triggered for each generated PDF documen + function documentSplitEvent( + sender: PdfDocument, + args: PdfDocumentSplitEventArgs + ): void { + + // Convert the split PDF data to a Uint8Array + const pdfBytes = new Uint8Array(args.pdfData); + + // Download the generated PDF document + Save.save( + 'output_' + args.index + '.pdf', + new Blob( + [pdfBytes.buffer.slice(0)], + { type: 'application/pdf' } + ) + ); + } + + // Release resources used by the PDF document + inputDocument.destroy(); + } + + /** + * Split the PDF document into smaller PDFs with a fixed number of pages + */ + async splitFixedNumber(): Promise { + + // Load the input PDF document + const inputDocument = new PdfDocument(this.documentBytes); + + // Assign the split event handler + inputDocument.splitEvent = documentSplitEvent; + + // Split the document into PDFs containing one page each + inputDocument.splitByFixedNumber(1); + + // Triggered for each generated PDF document + function documentSplitEvent( + sender: PdfDocument, + args: PdfDocumentSplitEventArgs + ): void { + + // Convert the split PDF data to a Uint8Array + const pdfBytes = new Uint8Array(args.pdfData); + + // Download the generated PDF document + Save.save( + 'output_' + args.index + '.pdf', + new Blob( + [pdfBytes.buffer.slice(0)], + { type: 'application/pdf' } + ) + ); + } + // Release resources used by the PDF document + inputDocument.destroy(); + } + + /** + * Retrieves a PDF document from the specified URL + * and returns its content as a Uint8Array + */ + private async getInputBytes(url: string): Promise { + + // Send a request to retrieve the PDF document + const response = await fetch(url); + + // Convert the response content to a Uint8Array + return new Uint8Array(await response.arrayBuffer()); + } + +} diff --git a/angular/split-pdf/src/index.html b/angular/split-pdf/src/index.html new file mode 100644 index 0000000..0f03ba9 --- /dev/null +++ b/angular/split-pdf/src/index.html @@ -0,0 +1,13 @@ + + + + + SplitPdf + + + + + + + + diff --git a/angular/split-pdf/src/main.ts b/angular/split-pdf/src/main.ts new file mode 100644 index 0000000..260619c --- /dev/null +++ b/angular/split-pdf/src/main.ts @@ -0,0 +1,9 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; +import { App } from './app/app'; +import { registerLicense } from '@syncfusion/ej2-base'; + +registerLicense('Your-License-Key'); + +bootstrapApplication(App, appConfig) + .catch((err) => console.error(err)); diff --git a/angular/split-pdf/src/styles.css b/angular/split-pdf/src/styles.css new file mode 100644 index 0000000..90d4ee0 --- /dev/null +++ b/angular/split-pdf/src/styles.css @@ -0,0 +1 @@ +/* You can add global styles to this file, and also import other style files */ diff --git a/angular/split-pdf/tsconfig.app.json b/angular/split-pdf/tsconfig.app.json new file mode 100644 index 0000000..cb151e1 --- /dev/null +++ b/angular/split-pdf/tsconfig.app.json @@ -0,0 +1,14 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "types": [] + }, + "include": [ + "src/**/*.ts" + ], + "exclude": [ + "src/**/*.spec.ts" + ] +} diff --git a/angular/split-pdf/tsconfig.json b/angular/split-pdf/tsconfig.json new file mode 100644 index 0000000..d2fbb9c --- /dev/null +++ b/angular/split-pdf/tsconfig.json @@ -0,0 +1,31 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "compileOnSave": false, + "compilerOptions": { + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "isolatedModules": true, + "experimentalDecorators": true, + "importHelpers": true, + "target": "ES2022", + "module": "preserve" + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true + }, + "files": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/angular/split-pdf/tsconfig.spec.json b/angular/split-pdf/tsconfig.spec.json new file mode 100644 index 0000000..9c8efb9 --- /dev/null +++ b/angular/split-pdf/tsconfig.spec.json @@ -0,0 +1,14 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "types": [ + "vitest/globals" + ] + }, + "include": [ + "src/**/*.d.ts", + "src/**/*.spec.ts" + ] +} From e681590105923ebb4659d4bb1531bb95ccfe5c29 Mon Sep 17 00:00:00 2001 From: deepika134 <87310214+deepika134@users.noreply.github.com> Date: Tue, 15 Sep 2026 13:07:15 +0530 Subject: [PATCH 2/5] Update main.ts --- angular/split-pdf/src/main.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/angular/split-pdf/src/main.ts b/angular/split-pdf/src/main.ts index 260619c..2c8e698 100644 --- a/angular/split-pdf/src/main.ts +++ b/angular/split-pdf/src/main.ts @@ -2,7 +2,6 @@ import { bootstrapApplication } from '@angular/platform-browser'; import { appConfig } from './app/app.config'; import { App } from './app/app'; import { registerLicense } from '@syncfusion/ej2-base'; - registerLicense('Your-License-Key'); bootstrapApplication(App, appConfig) From a5f591bff732cfd8ed03940c6b26b8e145ce5ee2 Mon Sep 17 00:00:00 2001 From: Manikandan020120 Date: Wed, 16 Sep 2026 13:03:01 +0530 Subject: [PATCH 3/5] Added the sample for individual form field flatten --- .../.editorconfig | 17 ++++ .../individual-form-field-flatten/.gitignore | 44 ++++++++ .../individual-form-field-flatten/.prettierrc | 12 +++ .../individual-form-field-flatten/README.md | 96 ++++++++++++++++++ .../angular.json | 74 ++++++++++++++ .../package.json | 33 ++++++ .../public/favicon.ico | Bin 0 -> 15086 bytes .../src/app/app.config.ts | 10 ++ .../src/app/app.css | 0 .../src/app/app.html | 44 ++++++++ .../src/app/app.routes.ts | 3 + .../src/app/app.spec.ts | 24 +++++ .../src/app/app.ts | 63 ++++++++++++ .../src/index.html | 13 +++ .../individual-form-field-flatten/src/main.ts | 8 ++ .../src/styles.css | 1 + .../tsconfig.app.json | 14 +++ .../tsconfig.json | 31 ++++++ .../tsconfig.spec.json | 14 +++ 19 files changed, 501 insertions(+) create mode 100644 angular/individual-form-field-flatten/.editorconfig create mode 100644 angular/individual-form-field-flatten/.gitignore create mode 100644 angular/individual-form-field-flatten/.prettierrc create mode 100644 angular/individual-form-field-flatten/README.md create mode 100644 angular/individual-form-field-flatten/angular.json create mode 100644 angular/individual-form-field-flatten/package.json create mode 100644 angular/individual-form-field-flatten/public/favicon.ico create mode 100644 angular/individual-form-field-flatten/src/app/app.config.ts create mode 100644 angular/individual-form-field-flatten/src/app/app.css create mode 100644 angular/individual-form-field-flatten/src/app/app.html create mode 100644 angular/individual-form-field-flatten/src/app/app.routes.ts create mode 100644 angular/individual-form-field-flatten/src/app/app.spec.ts create mode 100644 angular/individual-form-field-flatten/src/app/app.ts create mode 100644 angular/individual-form-field-flatten/src/index.html create mode 100644 angular/individual-form-field-flatten/src/main.ts create mode 100644 angular/individual-form-field-flatten/src/styles.css create mode 100644 angular/individual-form-field-flatten/tsconfig.app.json create mode 100644 angular/individual-form-field-flatten/tsconfig.json create mode 100644 angular/individual-form-field-flatten/tsconfig.spec.json diff --git a/angular/individual-form-field-flatten/.editorconfig b/angular/individual-form-field-flatten/.editorconfig new file mode 100644 index 0000000..f166060 --- /dev/null +++ b/angular/individual-form-field-flatten/.editorconfig @@ -0,0 +1,17 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single +ij_typescript_use_double_quotes = false + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/angular/individual-form-field-flatten/.gitignore b/angular/individual-form-field-flatten/.gitignore new file mode 100644 index 0000000..854acd5 --- /dev/null +++ b/angular/individual-form-field-flatten/.gitignore @@ -0,0 +1,44 @@ +# See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. + +# Compiled output +/dist +/tmp +/out-tsc +/bazel-out + +# Node +/node_modules +npm-debug.log +yarn-error.log + +# IDEs and editors +.idea/ +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# Visual Studio Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/mcp.json +.history/* + +# Miscellaneous +/.angular/cache +.sass-cache/ +/connect.lock +/coverage +/libpeerconnection.log +testem.log +/typings +__screenshots__/ + +# System files +.DS_Store +Thumbs.db diff --git a/angular/individual-form-field-flatten/.prettierrc b/angular/individual-form-field-flatten/.prettierrc new file mode 100644 index 0000000..d6c16d7 --- /dev/null +++ b/angular/individual-form-field-flatten/.prettierrc @@ -0,0 +1,12 @@ +{ + "printWidth": 100, + "singleQuote": true, + "overrides": [ + { + "files": "*.html", + "options": { + "parser": "angular" + } + } + ] +} diff --git a/angular/individual-form-field-flatten/README.md b/angular/individual-form-field-flatten/README.md new file mode 100644 index 0000000..b21636a --- /dev/null +++ b/angular/individual-form-field-flatten/README.md @@ -0,0 +1,96 @@ +# How to Flatten an Individual Form Field in the JavaScript PDF Library + +This sample demonstrates how to flatten an individual form field using the `Syncfusion JavaScript PDF Library`. + +## Features Demonstrated + +This sample shows how to: + +- Load an existing PDF document from a URL. +- Access the form fields of a loaded PDF document. +- Locate a specific field of the form using its index. +- Fill a text box field with sample text. +- Flatten an individual form field to remove editability. +- Save and download the generated PDF document. +- Release resources after processing the PDF document. + +## Project Structure + +### app.ts + +The `flattenIndividualFormField()` method performs the following operations: + +- Downloads the input PDF document from the specified URL. +- Loads the existing PDF document. +- Accesses the form from the loaded PDF document. +- Retrieves the individual form field to be flattened. +- Fills the text box field with sample text. +- Flattens the individual form field. +- Saves the modified PDF as `Output.pdf`. +- Releases resources by destroying the PDF document instance. + +The `getPdfAsUint8Array()` helper method: + +- Retrieves a PDF document from the specified URL. +- Converts the file into a `Uint8Array`. +- Returns the PDF data for further processing. + +### app.html + +The user interface includes: + +- A **Flatten Individual Form Field** button. +- A simple layout to trigger the flatten operation. + +When the button is clicked, the application flattens an individual form field in the PDF document and downloads the generated output file. + +## Prerequisites + +Ensure the following software is installed: + +- Node.js +- Angular CLI + +## Installation + +Install the Syncfusion JavaScript PDF Library package: + +```bash +npm install @syncfusion/ej2-pdf +``` + +## Running the Application + +Install the project dependencies: + +```bash +npm install +``` + +Start the Angular development server: + +```bash +ng serve +``` + +Then open: + +```text +http://localhost:4200/ +``` + +Click **Flatten Individual Form Field** to load the form PDF, flatten the selected field, and download the output file. + +## Additional Resources + +### Documentation + +[JavaScript PDF Library Documentation](https://help.syncfusion.com/document-processing/pdf/pdf-library/javascript/working-with-forms) + +### Online Demos + +[JavaScript PDF Library Demos](https://document.syncfusion.com/demos/pdf/angular/#/tailwind3/pdf/) + +### Product Page + +[JavaScript PDF Library Product Page](https://www.syncfusion.com/document-sdk/javascript-pdf-library) \ No newline at end of file diff --git a/angular/individual-form-field-flatten/angular.json b/angular/individual-form-field-flatten/angular.json new file mode 100644 index 0000000..7cbb833 --- /dev/null +++ b/angular/individual-form-field-flatten/angular.json @@ -0,0 +1,74 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "cli": { + "packageManager": "npm", + "analytics": "b11d304c-687a-4245-88b2-1afb5c1c7af5" + }, + "newProjectRoot": "projects", + "projects": { + "individual-form-field-flatten": { + "projectType": "application", + "schematics": {}, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular/build:application", + "options": { + "browser": "src/main.ts", + "tsConfig": "tsconfig.app.json", + "assets": [ + { + "glob": "**/*", + "input": "public" + } + ], + "styles": [ + "src/styles.css" + ] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kB", + "maximumError": "1MB" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "4kB", + "maximumError": "8kB" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular/build:dev-server", + "configurations": { + "production": { + "buildTarget": "individual-form-field-flatten:build:production" + }, + "development": { + "buildTarget": "individual-form-field-flatten:build:development" + } + }, + "defaultConfiguration": "development" + }, + "test": { + "builder": "@angular/build:unit-test" + } + } + } + } +} diff --git a/angular/individual-form-field-flatten/package.json b/angular/individual-form-field-flatten/package.json new file mode 100644 index 0000000..0ca309c --- /dev/null +++ b/angular/individual-form-field-flatten/package.json @@ -0,0 +1,33 @@ +{ + "name": "individual-form-field-flatten", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "test": "ng test" + }, + "private": true, + "packageManager": "npm@11.19.0", + "dependencies": { + "@angular/common": "^22.1.0", + "@angular/compiler": "^22.1.0", + "@angular/core": "^22.1.0", + "@angular/forms": "^22.1.0", + "@angular/platform-browser": "^22.1.0", + "@angular/router": "^22.1.0", + "@syncfusion/ej2-pdf": "*", + "rxjs": "~7.8.0", + "tslib": "^2.3.0" + }, + "devDependencies": { + "@angular/build": "^22.1.6", + "@angular/cli": "^22.1.6", + "@angular/compiler-cli": "^22.1.0", + "jsdom": "^28.0.0", + "prettier": "^3.8.1", + "typescript": "~6.0.2", + "vitest": "^4.0.8" + } +} diff --git a/angular/individual-form-field-flatten/public/favicon.ico b/angular/individual-form-field-flatten/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..57614f9c967596fad0a3989bec2b1deff33034f6 GIT binary patch literal 15086 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 Nr__JTFzvMr^FKp4S3v*( literal 0 HcmV?d00001 diff --git a/angular/individual-form-field-flatten/src/app/app.config.ts b/angular/individual-form-field-flatten/src/app/app.config.ts new file mode 100644 index 0000000..e60fc79 --- /dev/null +++ b/angular/individual-form-field-flatten/src/app/app.config.ts @@ -0,0 +1,10 @@ +import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core'; +import { provideRouter } from '@angular/router'; +import { routes } from './app.routes'; + +export const appConfig: ApplicationConfig = { + providers: [ + provideBrowserGlobalErrorListeners(), + provideRouter(routes) + ] +}; diff --git a/angular/individual-form-field-flatten/src/app/app.css b/angular/individual-form-field-flatten/src/app/app.css new file mode 100644 index 0000000..e69de29 diff --git a/angular/individual-form-field-flatten/src/app/app.html b/angular/individual-form-field-flatten/src/app/app.html new file mode 100644 index 0000000..b7dad06 --- /dev/null +++ b/angular/individual-form-field-flatten/src/app/app.html @@ -0,0 +1,44 @@ +
+
+

+ Flatten Individual Form Field +

+
+ + + +
+
+
\ No newline at end of file diff --git a/angular/individual-form-field-flatten/src/app/app.routes.ts b/angular/individual-form-field-flatten/src/app/app.routes.ts new file mode 100644 index 0000000..dc39edb --- /dev/null +++ b/angular/individual-form-field-flatten/src/app/app.routes.ts @@ -0,0 +1,3 @@ +import { Routes } from '@angular/router'; + +export const routes: Routes = []; diff --git a/angular/individual-form-field-flatten/src/app/app.spec.ts b/angular/individual-form-field-flatten/src/app/app.spec.ts new file mode 100644 index 0000000..e66afd9 --- /dev/null +++ b/angular/individual-form-field-flatten/src/app/app.spec.ts @@ -0,0 +1,24 @@ +import { TestBed } from '@angular/core/testing'; +import { App } from './app'; + +describe('App', () => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [App], + }) + .compileComponents(); + }); + + it('should create the app', () => { + const fixture = TestBed.createComponent(App); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); + + it('should render title', async () => { + const fixture = TestBed.createComponent(App); + await fixture.whenStable(); + const compiled = fixture.nativeElement as HTMLElement; + expect(compiled.querySelector('h2')?.textContent).toContain('Flatten Individual Form Field'); + }); +}); diff --git a/angular/individual-form-field-flatten/src/app/app.ts b/angular/individual-form-field-flatten/src/app/app.ts new file mode 100644 index 0000000..b534407 --- /dev/null +++ b/angular/individual-form-field-flatten/src/app/app.ts @@ -0,0 +1,63 @@ +import { Component } from '@angular/core'; +import { + PdfDocument, PdfTextBoxField +} from '@syncfusion/ej2-pdf'; + +@Component({ + selector: 'app-root', + standalone: true, + templateUrl: './app.html' +}) + +export class App { + + // URL of the form filling PDF document + private readonly formFillingDocument = + 'https://cdn.syncfusion.com/content/pdf-resources/form-filling-document.pdf'; + + /** + * Flattens an individual form field in a PDF document + */ + async flattenIndividualFormField(): Promise { + + // Retrieve the source PDF document as a byte array + const documentBytes = await this.getPdfAsUint8Array(this.formFillingDocument); + + // Load an existing PDF document + const document = new PdfDocument(documentBytes); + + // Get the form from the loaded PDF document + const form = document.form; + + // Retrieve the individual form field to be flattened + const field = form.fieldAt(0) as PdfTextBoxField; + if (field instanceof PdfTextBoxField) { + + // Fill the text box field with the required text + field.text = '01/01/2000'; + + // Flatten the individual form field + field.flatten = true; + } + + // Save the output PDF document + document.save('Output.pdf'); + + // Destroy the document to free resources + document.destroy(); + } + + /** + * Retrieves a PDF document from the specified URL + * and returns its content as a Uint8Array + */ + private async getPdfAsUint8Array(url: string): Promise { + + // Send a request to retrieve the PDF document + const response = await fetch(url); + + // Convert the response content to a Uint8Array + return new Uint8Array(await response.arrayBuffer()); + } + +} \ No newline at end of file diff --git a/angular/individual-form-field-flatten/src/index.html b/angular/individual-form-field-flatten/src/index.html new file mode 100644 index 0000000..d6d1ef6 --- /dev/null +++ b/angular/individual-form-field-flatten/src/index.html @@ -0,0 +1,13 @@ + + + + + IndividualFormFieldFlatten + + + + + + + + diff --git a/angular/individual-form-field-flatten/src/main.ts b/angular/individual-form-field-flatten/src/main.ts new file mode 100644 index 0000000..2c8e698 --- /dev/null +++ b/angular/individual-form-field-flatten/src/main.ts @@ -0,0 +1,8 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; +import { App } from './app/app'; +import { registerLicense } from '@syncfusion/ej2-base'; +registerLicense('Your-License-Key'); + +bootstrapApplication(App, appConfig) + .catch((err) => console.error(err)); diff --git a/angular/individual-form-field-flatten/src/styles.css b/angular/individual-form-field-flatten/src/styles.css new file mode 100644 index 0000000..90d4ee0 --- /dev/null +++ b/angular/individual-form-field-flatten/src/styles.css @@ -0,0 +1 @@ +/* You can add global styles to this file, and also import other style files */ diff --git a/angular/individual-form-field-flatten/tsconfig.app.json b/angular/individual-form-field-flatten/tsconfig.app.json new file mode 100644 index 0000000..cb151e1 --- /dev/null +++ b/angular/individual-form-field-flatten/tsconfig.app.json @@ -0,0 +1,14 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "types": [] + }, + "include": [ + "src/**/*.ts" + ], + "exclude": [ + "src/**/*.spec.ts" + ] +} diff --git a/angular/individual-form-field-flatten/tsconfig.json b/angular/individual-form-field-flatten/tsconfig.json new file mode 100644 index 0000000..d2fbb9c --- /dev/null +++ b/angular/individual-form-field-flatten/tsconfig.json @@ -0,0 +1,31 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "compileOnSave": false, + "compilerOptions": { + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "isolatedModules": true, + "experimentalDecorators": true, + "importHelpers": true, + "target": "ES2022", + "module": "preserve" + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true + }, + "files": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/angular/individual-form-field-flatten/tsconfig.spec.json b/angular/individual-form-field-flatten/tsconfig.spec.json new file mode 100644 index 0000000..9c8efb9 --- /dev/null +++ b/angular/individual-form-field-flatten/tsconfig.spec.json @@ -0,0 +1,14 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "types": [ + "vitest/globals" + ] + }, + "include": [ + "src/**/*.d.ts", + "src/**/*.spec.ts" + ] +} From 0532aba45b6082b7b9f4015e96fac49d180982ce Mon Sep 17 00:00:00 2001 From: Deepika Date: Thu, 17 Sep 2026 15:30:37 +0530 Subject: [PATCH 4/5] Added the sample for redaction --- angular/redaction/.editorconfig | 17 ++ angular/redaction/.gitignore | 44 ++++++ angular/redaction/.prettierrc | 12 ++ angular/redaction/README.md | 59 +++++++ angular/redaction/angular.json | 74 +++++++++ angular/redaction/package.json | 34 ++++ angular/redaction/public/favicon.ico | Bin 0 -> 15086 bytes angular/redaction/src/app/app.config.ts | 10 ++ angular/redaction/src/app/app.css | 0 angular/redaction/src/app/app.html | 69 ++++++++ angular/redaction/src/app/app.routes.ts | 3 + angular/redaction/src/app/app.spec.ts | 24 +++ angular/redaction/src/app/app.ts | 200 ++++++++++++++++++++++++ angular/redaction/src/index.html | 13 ++ angular/redaction/src/main.ts | 8 + angular/redaction/src/styles.css | 1 + angular/redaction/tsconfig.app.json | 14 ++ angular/redaction/tsconfig.json | 31 ++++ angular/redaction/tsconfig.spec.json | 14 ++ 19 files changed, 627 insertions(+) create mode 100644 angular/redaction/.editorconfig create mode 100644 angular/redaction/.gitignore create mode 100644 angular/redaction/.prettierrc create mode 100644 angular/redaction/README.md create mode 100644 angular/redaction/angular.json create mode 100644 angular/redaction/package.json create mode 100644 angular/redaction/public/favicon.ico create mode 100644 angular/redaction/src/app/app.config.ts create mode 100644 angular/redaction/src/app/app.css create mode 100644 angular/redaction/src/app/app.html create mode 100644 angular/redaction/src/app/app.routes.ts create mode 100644 angular/redaction/src/app/app.spec.ts create mode 100644 angular/redaction/src/app/app.ts create mode 100644 angular/redaction/src/index.html create mode 100644 angular/redaction/src/main.ts create mode 100644 angular/redaction/src/styles.css create mode 100644 angular/redaction/tsconfig.app.json create mode 100644 angular/redaction/tsconfig.json create mode 100644 angular/redaction/tsconfig.spec.json diff --git a/angular/redaction/.editorconfig b/angular/redaction/.editorconfig new file mode 100644 index 0000000..f166060 --- /dev/null +++ b/angular/redaction/.editorconfig @@ -0,0 +1,17 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single +ij_typescript_use_double_quotes = false + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/angular/redaction/.gitignore b/angular/redaction/.gitignore new file mode 100644 index 0000000..854acd5 --- /dev/null +++ b/angular/redaction/.gitignore @@ -0,0 +1,44 @@ +# See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. + +# Compiled output +/dist +/tmp +/out-tsc +/bazel-out + +# Node +/node_modules +npm-debug.log +yarn-error.log + +# IDEs and editors +.idea/ +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# Visual Studio Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/mcp.json +.history/* + +# Miscellaneous +/.angular/cache +.sass-cache/ +/connect.lock +/coverage +/libpeerconnection.log +testem.log +/typings +__screenshots__/ + +# System files +.DS_Store +Thumbs.db diff --git a/angular/redaction/.prettierrc b/angular/redaction/.prettierrc new file mode 100644 index 0000000..d6c16d7 --- /dev/null +++ b/angular/redaction/.prettierrc @@ -0,0 +1,12 @@ +{ + "printWidth": 100, + "singleQuote": true, + "overrides": [ + { + "files": "*.html", + "options": { + "parser": "angular" + } + } + ] +} diff --git a/angular/redaction/README.md b/angular/redaction/README.md new file mode 100644 index 0000000..984f1b4 --- /dev/null +++ b/angular/redaction/README.md @@ -0,0 +1,59 @@ +# Redaction + +This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 22.1.6. + +## Development server + +To start a local development server, run: + +```bash +ng serve +``` + +Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. + +## Code scaffolding + +Angular CLI includes powerful code scaffolding tools. To generate a new component, run: + +```bash +ng generate component component-name +``` + +For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: + +```bash +ng generate --help +``` + +## Building + +To build the project run: + +```bash +ng build +``` + +This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. + +## Running unit tests + +To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: + +```bash +ng test +``` + +## Running end-to-end tests + +For end-to-end (e2e) testing, run: + +```bash +ng e2e +``` + +Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. + +## Additional Resources + +For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. diff --git a/angular/redaction/angular.json b/angular/redaction/angular.json new file mode 100644 index 0000000..56a6611 --- /dev/null +++ b/angular/redaction/angular.json @@ -0,0 +1,74 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "cli": { + "packageManager": "npm", + "analytics": "1b4d8d79-bfcf-4f5c-ac0e-8420d7292efc" + }, + "newProjectRoot": "projects", + "projects": { + "redaction": { + "projectType": "application", + "schematics": {}, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular/build:application", + "options": { + "browser": "src/main.ts", + "tsConfig": "tsconfig.app.json", + "assets": [ + { + "glob": "**/*", + "input": "public" + } + ], + "styles": [ + "src/styles.css" + ] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kB", + "maximumError": "1MB" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "4kB", + "maximumError": "8kB" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular/build:dev-server", + "configurations": { + "production": { + "buildTarget": "redaction:build:production" + }, + "development": { + "buildTarget": "redaction:build:development" + } + }, + "defaultConfiguration": "development" + }, + "test": { + "builder": "@angular/build:unit-test" + } + } + } + } +} diff --git a/angular/redaction/package.json b/angular/redaction/package.json new file mode 100644 index 0000000..b1ebb7a --- /dev/null +++ b/angular/redaction/package.json @@ -0,0 +1,34 @@ +{ + "name": "redaction", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "test": "ng test" + }, + "private": true, + "packageManager": "npm@11.19.0", + "dependencies": { + "@angular/common": "^22.1.0", + "@angular/compiler": "^22.1.0", + "@angular/core": "^22.1.0", + "@angular/forms": "^22.1.0", + "@angular/platform-browser": "^22.1.0", + "@angular/router": "^22.1.0", + "@syncfusion/ej2-pdf": "^34.2.5", + "@syncfusion/ej2-pdf-data-extract": "^34.2.5", + "rxjs": "~7.8.0", + "tslib": "^2.3.0" + }, + "devDependencies": { + "@angular/build": "^22.1.6", + "@angular/cli": "^22.1.6", + "@angular/compiler-cli": "^22.1.0", + "jsdom": "^28.0.0", + "prettier": "^3.8.1", + "typescript": "~6.0.2", + "vitest": "^4.0.8" + } +} diff --git a/angular/redaction/public/favicon.ico b/angular/redaction/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..57614f9c967596fad0a3989bec2b1deff33034f6 GIT binary patch literal 15086 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 Nr__JTFzvMr^FKp4S3v*( literal 0 HcmV?d00001 diff --git a/angular/redaction/src/app/app.config.ts b/angular/redaction/src/app/app.config.ts new file mode 100644 index 0000000..e60fc79 --- /dev/null +++ b/angular/redaction/src/app/app.config.ts @@ -0,0 +1,10 @@ +import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core'; +import { provideRouter } from '@angular/router'; +import { routes } from './app.routes'; + +export const appConfig: ApplicationConfig = { + providers: [ + provideBrowserGlobalErrorListeners(), + provideRouter(routes) + ] +}; diff --git a/angular/redaction/src/app/app.css b/angular/redaction/src/app/app.css new file mode 100644 index 0000000..e69de29 diff --git a/angular/redaction/src/app/app.html b/angular/redaction/src/app/app.html new file mode 100644 index 0000000..4cfc438 --- /dev/null +++ b/angular/redaction/src/app/app.html @@ -0,0 +1,69 @@ +
+
+

+ Redaction in JavaScript PDF Library +

+ +
+ + + + + + +
+
\ No newline at end of file diff --git a/angular/redaction/src/app/app.routes.ts b/angular/redaction/src/app/app.routes.ts new file mode 100644 index 0000000..dc39edb --- /dev/null +++ b/angular/redaction/src/app/app.routes.ts @@ -0,0 +1,3 @@ +import { Routes } from '@angular/router'; + +export const routes: Routes = []; diff --git a/angular/redaction/src/app/app.spec.ts b/angular/redaction/src/app/app.spec.ts new file mode 100644 index 0000000..ebec8e4 --- /dev/null +++ b/angular/redaction/src/app/app.spec.ts @@ -0,0 +1,24 @@ +import { TestBed } from '@angular/core/testing'; +import { App } from './app'; + +describe('App', () => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [App], + }) + .compileComponents(); + }); + + it('should create the app', () => { + const fixture = TestBed.createComponent(App); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); + + it('should render title', async () => { + const fixture = TestBed.createComponent(App); + await fixture.whenStable(); + const compiled = fixture.nativeElement as HTMLElement; + expect(compiled.querySelector('h1')?.textContent).toContain('Hello, redaction'); + }); +}); diff --git a/angular/redaction/src/app/app.ts b/angular/redaction/src/app/app.ts new file mode 100644 index 0000000..9d76a0d --- /dev/null +++ b/angular/redaction/src/app/app.ts @@ -0,0 +1,200 @@ +import { Component, } from '@angular/core'; +import { + PdfBrush, PdfDocument, PdfFontFamily, PdfFontStyle +} from '@syncfusion/ej2-pdf'; +import { + PdfRedactor, PdfRedactionRegion, ApplicationPlatform +} from '@syncfusion/ej2-pdf-data-extract'; + +@Component({ + selector: 'app-root', + styleUrl: './app.css', + templateUrl: './app.html', +}) +export class App { + + // URL of the input PDF document + private readonly documentUrl = + 'https://cdn.syncfusion.com/content/pdf-resources/credit_card_statement.pdf'; + + // Stores the PDF document as a byte array + private documentBytes!: Uint8Array; + + // Load the PDF document when the component initializes + async ngOnInit(): Promise { + this.documentBytes = await this.getInputBytes(this.documentUrl); + } + + /** + * Redact content from a specified region in the PDF document + */ + async redactContent(): Promise { + + // Load the PDF document from the byte array + let pdfdocument: PdfDocument = new PdfDocument(this.documentBytes); + + // Create a PDF redactor instance + let redactor: PdfRedactor = new PdfRedactor(pdfdocument); + + // Create a collection to hold redaction regions + let redactions: PdfRedactionRegion[] = []; + + // Define the area to be redacted on the first page + let redaction: PdfRedactionRegion = new PdfRedactionRegion( + 0, + { x: 70, y: 120, width: 200, height: 80 } + ); + + // Add the redaction region to the collection + redactions.push(redaction); + + // Add all redaction regions to the redactor + redactor.add(redactions); + + // Create a canvas callback required for the redaction process + const canvasRenderCallback = (): { + canvas: any, + applicationPlatform: ApplicationPlatform + } => { + + // Create an HTML canvas element + const canvas = document.createElement('canvas'); + + // Return the canvas and platform information + return { canvas: canvas, applicationPlatform: ApplicationPlatform.typescript }; + }; + + // Apply the redaction to the PDF document + await redactor.redact(canvasRenderCallback); + + // Save the redacted PDF document + pdfdocument.save('output.pdf'); + + // Release resources used by the PDF document + pdfdocument.destroy(); + } + + /** + * Apply a fill color to the redacted area + */ + async applyRedactionFillColor(): Promise { + + // Load the PDF document from the byte array + let pdfdocument: PdfDocument = new PdfDocument(this.documentBytes); + + // Create a PdfRedactor instance + let redactor: PdfRedactor = new PdfRedactor(pdfdocument); + + // Create a collection for redaction regions + let redactions: PdfRedactionRegion[] = []; + + // Define the redaction region + let redaction: PdfRedactionRegion = new PdfRedactionRegion( + 0, + { x: 70, y: 120, width: 200, height: 80 } + ); + + // Set the fill color of the redacted area + redaction.fillColor = { r: 0, g: 0, b: 0 }; + + // Add the redaction region to the collection + redactions.push(redaction); + + // Add the redaction region to the redactor + redactor.add(redactions); + + // Create a canvas callback + const canvasRenderCallback = (): { + canvas: any, + applicationPlatform: ApplicationPlatform + } => { + + // Create a canvas element + const canvas = document.createElement('canvas'); + + // Return the canvas and platform details + return { canvas: canvas, applicationPlatform: ApplicationPlatform.typescript }; + }; + + // Apply the redaction with the fill color + await redactor.redact(canvasRenderCallback); + + // Save the output PDF document + pdfdocument.save('output.pdf'); + + // Release resources used by the PDF document + pdfdocument.destroy(); + } + + /** + * Customize the text appearance within the redacted area + */ + async customizeTextAppearance(): Promise { + + // Load the PDF document from the byte array + let pdfdocument: PdfDocument = new PdfDocument(this.documentBytes); + + // Create a PdfRedactor instance + let redactor: PdfRedactor = new PdfRedactor(pdfdocument); + + // Create a collection for redaction regions + let redactions: PdfRedactionRegion[] = []; + + // Create a redaction region with appearance customization enabled + let redaction: PdfRedactionRegion = new PdfRedactionRegion( + 0, + { x: 70, y: 120, width: 200, height: 80 }, + true + ); + + // Embed a Helvetica font + let font = pdfdocument.embedFont(PdfFontFamily.helvetica, 10, PdfFontStyle.regular); + + // Draw custom text in the redacted area + redaction.appearance.normal.graphics.drawString( + 'Redacted Text', + font, + { x: 30, y: 40, width: 80, height: 20 }, + new PdfBrush({ r: 0, g: 0, b: 0 }) + ); + + // Add the redaction region to the collection + redactions.push(redaction); + + // Add the redaction regions to the redactor + redactor.add(redactions); + + // Create a canvas callback + const canvasRenderCallback = (): { + canvas: any, + applicationPlatform: ApplicationPlatform + } => { + // Create a canvas element + const canvas = document.createElement('canvas'); + // Return the canvas and platform information + return { canvas: canvas, applicationPlatform: ApplicationPlatform.typescript }; + }; + + // Apply the customized redaction + await redactor.redact(canvasRenderCallback); + + // Save the output PDF document + pdfdocument.save('output.pdf'); + + // Release resources used by the PDF document + pdfdocument.destroy(); + } + + /** + * Retrieves a PDF document from the specified URL + * and returns its content as a Uint8Array + */ + private async getInputBytes(url: string): Promise { + + // Send a request to retrieve the PDF document + const response = await fetch(url); + + // Convert the response content to a Uint8Array + return new Uint8Array(await response.arrayBuffer()); + } +} diff --git a/angular/redaction/src/index.html b/angular/redaction/src/index.html new file mode 100644 index 0000000..5c4b0ca --- /dev/null +++ b/angular/redaction/src/index.html @@ -0,0 +1,13 @@ + + + + + Redaction + + + + + + + + diff --git a/angular/redaction/src/main.ts b/angular/redaction/src/main.ts new file mode 100644 index 0000000..2c8e698 --- /dev/null +++ b/angular/redaction/src/main.ts @@ -0,0 +1,8 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; +import { App } from './app/app'; +import { registerLicense } from '@syncfusion/ej2-base'; +registerLicense('Your-License-Key'); + +bootstrapApplication(App, appConfig) + .catch((err) => console.error(err)); diff --git a/angular/redaction/src/styles.css b/angular/redaction/src/styles.css new file mode 100644 index 0000000..90d4ee0 --- /dev/null +++ b/angular/redaction/src/styles.css @@ -0,0 +1 @@ +/* You can add global styles to this file, and also import other style files */ diff --git a/angular/redaction/tsconfig.app.json b/angular/redaction/tsconfig.app.json new file mode 100644 index 0000000..cb151e1 --- /dev/null +++ b/angular/redaction/tsconfig.app.json @@ -0,0 +1,14 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "types": [] + }, + "include": [ + "src/**/*.ts" + ], + "exclude": [ + "src/**/*.spec.ts" + ] +} diff --git a/angular/redaction/tsconfig.json b/angular/redaction/tsconfig.json new file mode 100644 index 0000000..d2fbb9c --- /dev/null +++ b/angular/redaction/tsconfig.json @@ -0,0 +1,31 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "compileOnSave": false, + "compilerOptions": { + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "isolatedModules": true, + "experimentalDecorators": true, + "importHelpers": true, + "target": "ES2022", + "module": "preserve" + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true + }, + "files": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/angular/redaction/tsconfig.spec.json b/angular/redaction/tsconfig.spec.json new file mode 100644 index 0000000..9c8efb9 --- /dev/null +++ b/angular/redaction/tsconfig.spec.json @@ -0,0 +1,14 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "types": [ + "vitest/globals" + ] + }, + "include": [ + "src/**/*.d.ts", + "src/**/*.spec.ts" + ] +} From d2bccc1724ef7333119c900e4f1fccf8eeb5c49c Mon Sep 17 00:00:00 2001 From: Deepika Date: Thu, 17 Sep 2026 15:46:36 +0530 Subject: [PATCH 5/5] Added the README.md file for the redaction sample --- angular/redaction/README.md | 117 ++++++++++++++++++++++++++---------- 1 file changed, 86 insertions(+), 31 deletions(-) diff --git a/angular/redaction/README.md b/angular/redaction/README.md index 984f1b4..c1092b4 100644 --- a/angular/redaction/README.md +++ b/angular/redaction/README.md @@ -1,59 +1,114 @@ -# Redaction +# How to Redact Content in a PDF Document Using the JavaScript PDF Library -This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 22.1.6. +This sample demonstrates how to redact content in a PDF document using the `Syncfusion JavaScript PDF Library`. -## Development server +## Features Demonstrated -To start a local development server, run: +This sample shows how to: -```bash -ng serve -``` +- Load an existing PDF document from a URL. +- Redact content from a specified region in a PDF document. +- Apply a custom fill color to the redacted area. +- Customize the text displayed in the redacted region. +- Save and download the redacted PDF document. +- Release resources after processing the PDF document. -Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. +## Project Structure -## Code scaffolding +### app.ts -Angular CLI includes powerful code scaffolding tools. To generate a new component, run: +The `redactContent()` method performs the following operations: -```bash -ng generate component component-name -``` +- Loads the input PDF document. +- Creates a redaction region on the specified page. +- Adds the redaction region to the PDF redactor. +- Applies the redaction to permanently remove the content. +- Saves the redacted PDF document. +- Releases resources after processing. -For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: +The `applyRedactionFillColor()` method performs the following operations: -```bash -ng generate --help -``` +- Loads the input PDF document. +- Creates a redaction region. +- Applies a custom fill color to the redacted area. +- Processes the redaction. +- Saves the modified PDF document. +- Releases resources after processing. -## Building +The `customizeTextAppearance()` method performs the following operations: -To build the project run: +- Loads the input PDF document. +- Creates a redaction region with appearance customization enabled. +- Adds custom text within the redacted area. +- Applies the redaction. +- Saves the resulting PDF document. +- Releases resources after processing. -```bash -ng build -``` +The `getInputBytes()` helper method performs the following operations: +  +- Downloads the PDF document from the specified URL. +- Converts the document content to a `Uint8Array`. +- Returns the PDF data for further processing. + +### app.html + +The user interface includes: + +- A **Redact Content** button. +- An **Apply Fill Color** button. +- A **Customize Text Appearance** button. +- A simple layout to trigger the redaction operations. + +When a button is clicked, the application performs the selected redaction operation and downloads the resulting PDF document. + +## Prerequisites -This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. +Ensure the following software is installed: -## Running unit tests +- Node.js +- Angular CLI -To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: +## Installation +Install the Syncfusion packages: +  ```bash -ng test +npm install @syncfusion/ej2-pdf +npm install @syncfusionej2-pdf-data-extract ``` -## Running end-to-end tests +## Running the Application -For end-to-end (e2e) testing, run: +Install the project dependencies: ```bash -ng e2e +npm install ``` -Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. +Start the Angular development server: + +```bash +ng serve +``` + +Then open: + +```text +http://localhost:4200/ +``` + +Use one of the available buttons to perform the desired redaction operation. The resulting PDF document will be downloaded automatically. ## Additional Resources -For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. +### Documentation + +[JavaScript PDF Library Documentation](https://help.syncfusion.com/document-processing/pdf/pdf-library/javascript/redaction) + +### Online Demos + +[JavaScript PDF Library Demos](https://document.syncfusion.com/demos/pdf/angular/#/tailwind3/pdf/redaction) + +### Product Page + +[JavaScript PDF Library Product Page](https://www.syncfusion.com/document-sdk/javascript-pdf-library) \ No newline at end of file