Problem : I have an existing PDF form ( *.pdf ) that needs to be filled out. How can I fill it dynamically by using the Node JS?
-
AFAIK the common way for such tasks is reading template data from some template file (formatted as docx, xml - like JasperReports - or another), and transforming this template to PDF, including data substitution – lospejos Dec 25 '16 at 15:41
-
Did you checked this? http://pdfhummus.com/ – lospejos Dec 25 '16 at 15:43
7 Answers
Check out the following modules on npm:
The node-pdffiller
is a wrapper for PDFtk, the PDF Toolkit:
There's a lot of good documentation on the website of PDFKit:
Those modules have different features and API. You should find something that suits your needs.
There's also a nice article:
- Generating a PDF with Express & Node.js by Koen van Gilst (it uses PDFKit)

- 107,747
- 29
- 201
- 177
-
1when i use an example "generateFDFTemplate" of pdffiller I get an error "spawn pdftk ENOENT" How can i fix it? I'm also require('pdfkit'); – M.Tae Dec 26 '16 at 15:46
-
@M.Tae, https://stackoverflow.com/questions/27688804/how-do-i-debug-error-spawn-enoent-on-node-js. Too complicated for me lol. I suggest trying something else. – FBaez51 Apr 07 '20 at 15:28
-
in 2020 it is hard to run PDFtk (PDF Tool Kit). At last there are some docker images to help you run PDFtk but it is not easy to run docker image from NPM module... – Marecky Nov 26 '20 at 16:40
-
2If one wants to fill PDF forms, every mentioned library has some flaws. Libs `pdffiller`, `fill-pdf`, `node-pdffiller (deprecated)` use PDFtk (which I can't compile on Ubuntu 18.04, and in docker it is cumbersome to run from NodeJS, and I think it has issues to fill checkboxes). `pdf-fill-form` is written in C++ it is native NodeJS library (great!) but does not support filling checkboxes :( And pdfkit is just generating library (no support for forms) – Marecky Nov 26 '20 at 17:07
-
3As in 2021 none of this work, some require 10GB of addititional stuff to be downloaded and installed just to compile a 10 line file, and that wont work either. – Botond Kopacz Sep 03 '21 at 03:27
-
Some of the npm modules in this answer aren't free, open source or have restrictive licenses - not mentioning they require dependencies that don't run in every environment. I have found another answer that worked for me: https://stackoverflow.com/a/69776081/5881371 This is also the lightest way I found of doing it in node.js - it doesn't require installing 20Mbs+ of dependencies. – Jakub Pawlowski May 09 '23 at 00:47
For anyone still searching for a solution, give pdf-lib (https://pdf-lib.js.org / https://www.npmjs.com/package/pdf-lib) a look.
There's a nice thread on how to fill in PDF form text fields using the pdf-lib Node.js package: https://github.com/Hopding/pdf-lib/issues/48

- 716
- 8
- 10
I know this is a late response but I found a good library called PDF-LIB
It is so feature rich;
This is an example of a code to work with it
const { PDFDocument } = require('pdf-lib')
const fs = require('fs')
const util = require('util')
const data = {
"name": "Alice Alley",
"dateOfBirth": "01/01/1990",
"favoriteFood": "Glue"
}
async function createPdf(input, output) {
const readFile = util.promisify(fs.readFile)
function getStuff() {
return readFile(input)
}
const file = await getStuff()
const pdfDoc = await PDFDocument.load(file)
const form = pdfDoc.getForm()
Object.keys(data).forEach((element) => {
const field = form.getTextField(element)
field.setText(data[element])
})
const pdfBytes = await pdfDoc.save()
fs.writeFile(output, pdfBytes, () => {
console.log('PDF created!')
})
}
createPdf("input.pdf", "output.pdf")
// PDF library https://pdf-lib.js.org/
// PDF form creation https://www.pdfescape.com/
You actually need to create a form inside your PDF file then give each field a name in order to reference it using the code.
PDF Escape is a website that you upload your PDF then you create a form over it using the "Form Field" button... Over each field right click and select "Object properties..." and assign a name to the field with which you will reference by the code later, then save the file, download it and put it in the project directory.
Note: If you want your fields uneditable and be filled only by script you need to make the field "Read only" in the "Object properties..." also.
After that give the input file name to the createPdf function as well as the output name.
The data object consists on having the keys as the field names in the PDF document and the values as the values that you want to put in the document later.

- 418
- 1
- 5
- 16
-
1Has anyone given this solution a try? Cause I'm gonna try it. ill report back in a few days on the results – Josh Pachner Oct 26 '22 at 04:51
-
1reporting back. It worked amazingly! if anyone is scrolling through make sure to upvote this answer. a perfect example of someone coming in clutch many years later. – Josh Pachner Oct 28 '22 at 00:55
I read documentation for over a dozen packages and implemented about 5, the only one I could get to work with the requirements being in Node JS and can load a remote PDF file from my MongoDB and fill it was pdfform.js.
More details here.

- 63
- 8
I have faced the same problem but got the best solution that was pdf-fill-form
Just try this and feel the magic:
var pdfFillForm = require('pdf-fill-form');
var fs = require('fs');
pdfFillForm.write('test.pdf', { "myField": "myField fill value" }, { "save": "pdf", 'cores': 4, 'scale': 0.2, 'antialias': true } )
.then(function(result) {
fs.writeFile("test123.pdf", result, function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
}, function(err) {
console.log(err);
});

- 161
- 1
- 11
-
4I need a standalone solution that doesn't use a software installed like pdfkit for example. – M.Abulsoud Oct 07 '19 at 08:31
node-pdftk worked for me smoothly.
let DOCUMENTDIRECTORY = //directory holding your empty pdfs;
async function producePDFs(documents, outputDirectory) {
promises = [];
for (let document of documents) {
var fields = document["fieldsWithValue"];
var fieldsWithValue = {};
for (var i = 0; i < fields.length; i++) {
fieldsWithValue[fields[i]["name"]] = fields[i]["value"];
}
console.log(fieldsWithValue);
promises.push(
new Promise(function (resolve, reject) {
pdftk
.input(DOCUMENTDIRECTORY + document["file"]["fileName"])
.fillForm(fieldsWithValue)
.flatten()
.output(outputDirectory + document["file"]["fileName"])
.then((buffer) => {
getFile(outputDirectory + document["file"]["fileName"], 1000).then(
//1 second
(val) => {
if (val) resolve(1);
}
);
})
.catch((err) => {
console.log(err);
// handle errors
});
})
);
}
return Promise.all(promises).then(function () {
return 1;
});
}
async function getFile(path, time) {
return new Promise((resolve, reject) => {
const timeout = setInterval(function () {
const file = path;
const fileExists = fs.existsSync(file);
console.log("Checking for: ", file);
console.log("Exists: ", fileExists);
if (fileExists) {
clearInterval(timeout);
resolve(1);
}
}, time);
});
}

- 482
- 1
- 7
- 12
-
2I'm trying to get node-pdftk to work for me smoothly, but your answer doesn't show how. – Rayner Jun 18 '20 at 08:55
-
@Rayner Not the prettiest thing but I added what worked for me. Let me know of any questions! – FBaez51 Jun 19 '20 at 12:17
const { PDFDocument } = require('pdf-lib');
const fs = require('fs');
const util = require('util');
async function createPdf(input, output) {
try {
const readFile = util.promisify(fs.readFile);
function getStuff() {
return readFile(input);
}
const file = await getStuff();
const pdfDoc = await PDFDocument.load(file);
const form = pdfDoc.getForm();
const nameField = form.getTextField('CharacterName 2');
const ageField = form.getTextField('Age');
const heightField = form.getTextField('Height');
const weightField = form.getTextField('Weight');
const eyesField = form.getTextField('Eyes');
const skinField = form.getTextField('Skin');
const hairField = form.getTextField('Hair');
const alliesField = form.getTextField('Allies');
const factionField = form.getTextField('FactionName');
const backstoryField = form.getTextField('Backstory');
const traitsField = form.getTextField('Feat+Traits');
const treasureField = form.getTextField('Treasure');
nameField.setText('Template');
ageField.setText('24 years');
heightField.setText(`5' 1"`);
weightField.setText('196 lbs');
eyesField.setText('blue');
skinField.setText('white');
hairField.setText('brown');
// characterImageField.setImage(marioImage);
alliesField.setText(
[
`Allies:`,
` • Princess Daisy`,
` • Princess Peach`,
` • Rosalina`,
` • Geno`,
` • Luigi`,
` • Donkey Kong`,
` • Yoshi`,
` • Diddy Kong`,
``,
`Organizations:`,
` • Italian Plumbers Association`,
].join('\n')
);
factionField.setText(`Mario's Emblem`);
backstoryField.setText(
[
`Mario is a fictional character in the Mario video game franchise, `,
`owned by Nintendo and created by Japanese video game designer Shigeru `,
`Miyamoto. Serving as the company's mascot and the eponymous `,
`protagonist of the series, Mario has appeared in over 200 video games `,
`since his creation. Depicted as a short, pudgy, Italian plumber who `,
`resides in the Mushroom Kingdom, his adventures generally center `,
`upon rescuing Princess Peach from the Koopa villain Bowser. His `,
`younger brother and sidekick is Luigi.`,
].join('\n')
);
traitsField.setText(
[
`Mario can use three basic three power-ups:`,
` • the Super Mushroom, which causes Mario to grow larger`,
` • the Fire Flower, which allows Mario to throw fireballs`,
` • the Starman, which gives Mario temporary invincibility`,
].join('\n')
);
treasureField.setText(['• Gold coins', '• Treasure chests'].join('\n'));
const pdfBytes = await pdfDoc.save();
fs.writeFile(output, pdfBytes, () => {
console.log('PDF created!');
});
} catch (err) {
console.log(err);
}
}
createPdf('input.pdf', 'output.pdf');

- 824
- 9
- 11