Documentation
Creating PDFs
PDFs in Vue
PDFs in Nuxt
PDFs in React
PDFs in Angular
Fill an existing PDF
An application form, a contract with fields: inject(JasyForms) reads and fills the form of a PDF you
already have. The source is a URL, the File of an <input type="file">, or bytes. It works in the
browser and on the server.
The PDF reader is loaded on first use, so an app that only creates PDFs never downloads it.
Live from an Angular form
filledPdfResource() fills the PDF again whenever its values change, and loads the source only once.
Like pdfResource, it has latest() for the preview.
// application.ts
import { Component, inject } from "@angular/core";
import { FormControl, FormGroup, ReactiveFormsModule } from "@angular/forms";
import { toSignal } from "@angular/core/rxjs-interop";
import { JasyForms, JasyPdf, filledPdfResource } from "@jasy/angular";
const SOURCE = "/forms/application.pdf";
@Component({
selector: "app-application",
imports: [ReactiveFormsModule],
template: `
<form [formGroup]="form">
<input formControlName="full_name" />
<input type="checkbox" formControlName="agree" />
</form>
@if (preview.latest(); as pdf) {
<iframe [src]="pdf.safeUrl" title="Application"></iframe>
}
@if (preview.error(); as error) {
<p>{{ error.message }}</p>
}
<button (click)="send()">Download</button>
`,
})
export class Application {
private readonly forms = inject(JasyForms);
private readonly pdf = inject(JasyPdf);
readonly form = new FormGroup({
full_name: new FormControl(""),
agree: new FormControl(false),
});
// The PDF fills itself as the user types. The source is loaded once.
readonly preview = filledPdfResource(
SOURCE,
toSignal(this.form.valueChanges, { initialValue: this.form.value }),
);
async send() {
// flatten: the values become page content and can no longer be edited.
const { bytes } = await this.forms.fill(SOURCE, this.form.value, { flatten: true });
await this.pdf.download(bytes, "application.pdf");
}
}
The field names are the PDF's own. inject(JasyForms).read(source) lists them, with their types and
choices.
inject(JasyForms)
| Method | Does |
|---|---|
read(source, options?) | The fields: names, types, current values, choices. |
fill(source, values, options?) | Fills the fields by name. { flatten: true } freezes them in one step. |
flatten(source, options?) | Turns the fields into page content. |
read() returns undefined for a PDF without a form. A value that is undefined leaves its field as it
is, the way an Angular form leaves out a disabled control. A number is written as its text, as a number
input gives it. The options are those of the engine, such as password for an encrypted PDF: see
Filling a form somebody else made.
A URL goes through HttpClient, so your interceptors apply - an auth header reaches a protected form.
filledPdfResource()
filledPdfResource(source, values, { options?, injector? })
sourceis a URL, aBlobor bytes, or a function returning one. It is loaded once per source, not once per change.valuesis read likeresource({ params }). Returnundefinedfrom it, or fromsource, to wait.optionsare the fill options, and a function is tracked likevalues.
It is the same resource as pdfResource, latest()
included, and like it, it stays idle on the server.