Reputation: 1928
My environment is node v12.16.1 with typescript added.
I am using pdf-lib v1.16.0
(https://www.npmjs.com/package/pdf-lib) in order to fill the form for given PDF file. Library source code can be found here https://github.com/Hopding/pdf-lib and more on docs here https://pdf-lib.js.org/.
Regarding fonts pdf-lib
has a set of called StandardFonts
which is provided inside the lib.
export enum StandardFonts {
Courier = 'Courier',
CourierBold = 'Courier-Bold',
CourierOblique = 'Courier-Oblique',
CourierBoldOblique = 'Courier-BoldOblique',
Helvetica = 'Helvetica',
HelveticaBold = 'Helvetica-Bold',
HelveticaOblique = 'Helvetica-Oblique',
HelveticaBoldOblique = 'Helvetica-BoldOblique',
TimesRoman = 'Times-Roman',
TimesRomanBold = 'Times-Bold',
TimesRomanItalic = 'Times-Italic',
TimesRomanBoldItalic = 'Times-BoldItalic',
Symbol = 'Symbol',
ZapfDingbats = 'ZapfDingbats',
}
Very often you would have requirement to apply font which is not on the list. One example is when you have some user documents/forms to fill and then to apply electronical signature on it in order to approve them. Sometimes that electronic signature can be of a different font type, chosen by the user.
So, how we can add new font type of our choice?
Upvotes: 11
Views: 25737
Reputation: 1215
If you're using @pdf-lib/fontkit
in a typescript project the way you import fontkit
is different.
import * as fontkit from '@pdf-lib/fontkit';
This approach ensures compatibility with TypeScript and allows you to take advantage of TypeScript's type checking and IntelliSense features.
However, if you encounter issues with the import statement provided in other answers, you might need to switch to this syntax.
Here's an example of how to use @pdf-lib/fontkit to embed a custom font in a PDF document:
import path from 'path';
import * as fs from 'fs';
import * as path from 'path';
import { PDFDocument, PDFForm } from 'pdf-lib';
import fontkit from '@pdf-lib/fontkit';
const pdfBytes = fs.readFileSync(path.join(__dirname, `/w_template/` + fileName + '.pdf'));
const pdfDoc = await PDFDocument.load(pdfBytes);
pdfDoc.registerFontkit(fontkit);
// Load font and embed it into the PDF document
const fontBytes = fs.readFileSync(path.join(__dirname, 'HouschkaHead-BoldItalic.otf'));
const customFont = await pdfDoc.embedFont(fontBytes);
const form = pdfDoc.getForm();
const textField = form.getTextField('signature');
textField.setFontSize(11);
textField.setText('stefan z');
textField.updateAppearances(customFont);
// Form flattening makes the form read-only (not editable)
form.flatten();
const modifiedPdf = await pdfDoc.save();
Upvotes: 0
Reputation: 1070
If anyone is struggling to change the fontSize
in filling text fields using the latest inbuilt function called setFontSize()
. You can use this approach.
const { PDFDocument, setFontAndSize } = require('pdf-lib');
const pdfDoc = await PDFDocument.load(file);
const form = pdfDoc.getForm();
const textField = form.getTextField('106Mobile.1');
textField.setText('This works fine');
const da = textField.acroField.getDefaultAppearance() ?? '';
const newDa = da + '\n' + setFontAndSize('Courier', 8).toString(); //setFontAndSize() method came to resuce
textField.acroField.setDefaultAppearance(newDa);
I had to use this because I got an error saying
No /DA (default appearance) entry found for field: 106Title.1
when setting font sizes to some text fields (not all of it). But I degenerately had those text fields. Fixed it using the above workaround.
Upvotes: 7
Reputation: 1928
From the specs https://www.npmjs.com/package/pdf-lib#embed-font-and-measure-text
pdf-lib relies on a sister module to support embedding custom fonts: @pdf-lib/fontkit. You must add the @pdf-lib/fontkit module to your project and register it using pdfDoc.registerFontkit(...) before embedding custom fonts.
We have to npm i --save @pdf-lib/fontkit
and we have to have source from where which we will read the font. In my case I have added .otf
file in project and loaded font. Files are structured like on the image:
import path from 'path';
import fs from 'fs';
import {PDFDocument, PDFForm, StandardFonts, PDFFont} from 'pdf-lib';
import fontkit from '@pdf-lib/fontkit';
const pdfBytes = fs.readFileSync(path.join(__dirname, `/w_template/` + fileName + '.pdf'));
const pdfDoc = await PDFDocument.load(pdfBytes);
pdfDoc.registerFontkit(fontkit);
//load font and embed it to pdf document
const fontBytes = fs.readFileSync(path.join(__dirname, 'HouschkaHead-BoldItalic.otf'));
const customFont = await pdfDoc.embedFont(fontBytes);
const form = pdfDoc.getForm();
const textField = form.getTextField('signature');
textField.setFontSize(11);
textField.setText('stefan z');
textField.updateAppearances(customFont);
// form flatten is available from v1.16.0 and it makes form read-only (not editable)
form.flatten();
const modifiedPdf = await pdfDoc.save();
And this is the final result: check how the signature input form field is different from rest of input fields which are filled with default font
Bonus: if you want to play with color of the text of inputs in form, this is what I have found while digging more under the library source code (it might be not optimal, but it can give you starting point for more things):
import {setFillingRgbColor} from 'pdf-lib'
const textField = form.getTextField(fieldName);
const da = textField.acroField.getDefaultAppearance() ?? '';
const newDa = da + '\n' + setFillingRgbColor(1, 0, 0).toString();
textField.acroField.setDefaultAppearance(newDa);
Upvotes: 20