Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

value can be null or undefined #65

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
36db2bc
Update libs, switch from _.pluck to _.map
Jan 24, 2017
357afe0
Adds example of () breaking filling of pdfs.
Jan 24, 2017
ad2a4e2
Includes fdf lib and fixes bugs with special chars
Jan 24, 2017
077de97
initial working, tested conversion to streams
jasonphillips Mar 19, 2017
8501ca5
Merge branch 'master' into stream
jasonphillips Mar 19, 2017
1fd1808
Merge pull request #1 from jasonphillips/stream
jasonphillips Mar 19, 2017
594991f
Update README.md
jasonphillips Mar 19, 2017
bb420f6
Update LICENSE.md
jasonphillips Mar 19, 2017
11fbda3
add respoitory field
jasonphillips Mar 19, 2017
290972d
Merge branch 'master' of https://github.com/jasonphillips/pdffiller
jasonphillips Mar 19, 2017
fff1b57
Update README.md
jasonphillips Mar 19, 2017
d47c228
Update README.md
jasonphillips Mar 20, 2017
f76e55a
Add README note for OSX users
jasonphillips Mar 20, 2017
dfe99cf
send spawned process stdout data as soon as ready
jasonphillips Mar 21, 2017
1a88811
Merge branch 'master' of https://github.com/jasonphillips/pdffiller
jasonphillips Mar 21, 2017
33edd88
Create .travis.yml
jasonphillips Mar 22, 2017
cd7ea34
Update README.md
jasonphillips Mar 22, 2017
6082529
Update README.md
jasonphillips Mar 22, 2017
aa05961
Add AWS.S3 example code
jasonphillips Mar 23, 2017
3f745c6
Update README.md
jasonphillips Mar 23, 2017
50b5c16
Update README.md
webtaculars Oct 4, 2018
b1557a5
Merge pull request #3 from webtaculars/patch-1
jasonphillips Oct 9, 2018
d840950
Added error message if escapeString fails
Dec 5, 2018
6268d38
add initial utf test
jasonphillips Jan 16, 2020
73ebc18
Merge branch 'esacpeString-Error-Message' of git://github.com/SChetwy…
jasonphillips Jan 16, 2020
a641f34
Merge branch 'SChetwynd-esacpeString-Error-Message'
jasonphillips Jan 16, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
language: node_js
node_js:
- "node"
before_install:
- sudo apt-get -qq update
- sudo apt-get install -y pdftk
3 changes: 2 additions & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
MIT License (MIT)

Copyright (c) 2014-2016 John Taylor
This Fork: Copyright (c) 2017 Jason Phillips
Original Library: Copyright (c) 2014-2016 John Taylor

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
196 changes: 106 additions & 90 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,40 @@
PDF Filler (Node.js)
PDF Filler Stream
======
[![NPM](https://nodei.co/npm/pdffiller.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/pdffiller/)

[![npm version](https://badge.fury.io/js/pdffiller-stream.svg)](https://badge.fury.io/js/pdffiller-stream) [![Build Status](https://travis-ci.org/jasonphillips/pdffiller-stream.svg?branch=master)](https://travis-ci.org/jasonphillips/pdffiller-stream)

> This is a fork of the [pdf-filler](https://github.com/pdffillerjs/pdffiller) package, modified to return promises and readable streams, by piping data in/out of a spawned pdftk process instead of temporarily writing files to disk.

> The goal is cleaner integration, in eg. a microservices context, where it is preferable not to write multiple temporary files to disk and where you may wish to stream the generated pdf directly to a service like AWS.

A node.js PDF form field data filler and FDF generator toolkit. This essentially is a wrapper around the PDF Toolkit library <a target="_blank" href="http://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/">PDF ToolKit</a>.


Quick start
-----------

First, run `npm install pdffiller --save` for your app.
**You must first have `pdftk` (from pdftk-server, found [here](https://www.pdflabs.com/tools/pdftk-server/)) installed correctly on your platform.**

Import the module using:
Then, install this library:

```js
var pdfFiller = require('pdffiller');

// ...
```bash
npm install pdffiller-stream --save
```

**Note for MacOS / OSX Developers** - the main `pdftk` package for OSX is currently broken as of OS 10.11, but PDFLabs released an alternative build that should work normally on the platform: https://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/pdftk_server-2.02-mac_osx-10.11-setup.pkg



## Examples

#### 1.Fill PDF with existing FDF Data

````javascript
var pdfFiller = require('pdffiller');
import pdfFiller from 'pdffiller-stream';

var sourcePDF = "test/test.pdf";
var destinationPDF = "test/test_complete.pdf";
var data = {
const sourcePDF = "test/test.pdf";

const data = {
"last_name" : "John",
"first_name" : "Doe",
"date" : "Jan 1, 2013",
Expand All @@ -38,52 +45,86 @@ var data = {
"nascar" : "Off"
};

pdfFiller.fillForm( sourcePDF, destinationPDF, data, function(err) {
if (err) throw err;
console.log("In callback (we're done).");
});
pdfFiller.fillForm( sourcePDF, data)
.then((outputStream) => {
// use the outputStream here;
// will be instance of stream.Readable
}).catch((err) => {
console.log(err);
});

````

This will take the test.pdf, fill the fields with the data values
and create a complete filled in PDF (test_filled_in.pdf). Note that the
resulting PDF will be read-only.
This will take the test.pdf, fill the fields with the data values and stream a filled in, read-only PDF.

Alternatively,
A chainable convenience method `toFile` is attached to the response, if you simply wish to write the stream to a file with no fuss:

````javascript
```javascript
pdfFiller.fillForm( sourcePDF, data)
.toFile('outputFile.PDF')
.then(() => {
// your file has been written
}).catch((err) => {
console.log(err);
});
```

var shouldFlatten = false;
You could also stream the resulting data directly to AWS, doing something like this with an instantiated `s3` client:

```javascript
pdfFiller.fillForm( sourcePDF, data)
.then((outputStream) => {
const Body = outputStream;
const Bucket = 'some-bucket';
const Key = 'myFancyNewFilledPDF';
const ContentType = 'application/pdf';

const uploader = new AWS.S3.ManagedUpload({
params: {Bucket, Key, Body, ContentType},
service: s3,
});

uploader.promise().then((data) => {/* do something with AWS response */})

}).catch((err) => {
console.log(err);
});

pdfFiller.fillFormWithFlatten( sourcePDF, destinationPDF, data, shouldFlatten, function(err) {
if (err) throw err;
console.log("In callback (we're done).");
})
````
```

Calling
`fillFormWithFlatten()` with `shouldFlatten = false` will leave any unmapped fields
still editable, as per the `pdftk` command specification.
Calling `fillFormWithFlatten()` with `shouldFlatten = false` will leave any unmapped fields still editable, as per the `pdftk` command specification.

```javascript

const shouldFlatten = false;

pdfFiller.fillFormWithFlatten(sourcePDF, data, shouldFlatten)
.then((outputStream) {
// etc, same as above
})
```


#### 2. Generate FDF Template from PDF

````javascript
var pdfFiller = require('pdffiller');
import pdfFiller from 'pdffiller-stream';

var sourcePDF = "test/test.pdf";
const sourcePDF = "test/test.pdf";

// Override the default field name regex. Default: /FieldName: ([^\n]*)/
var nameRegex = null;
const nameRegex = null;

var FDF_data = pdfFiller.generateFDFTemplate( sourcePDF, nameRegex, function(err, fdfData) {
if (err) throw err;
const FDF_data = pdfFiller.generateFDFTemplate(sourcePDF, nameRegex).then((fdfData) => {
console.log(fdfData);
}).catch((err) => {
console.log(err);
});

````

This will print out this
```
```json
{
"last_name" : "",
"first_name" : "",
Expand All @@ -93,14 +134,15 @@ This will print out this
"basketball" : "",
"hockey" : "",
"nascar" : ""
};
}
```

#### 3. Map form fields to PDF fields
````javascript
var pdfFiller = require('pdffiller');
import pdfFiller from 'pdffiller-stream';

const conversionMap = {

var convMap = {
"lastName": "last_name",
"firstName": "first_name",
"Date": "date",
Expand All @@ -111,55 +153,25 @@ var convMap = {
"nascarField": "nascar"
};

var fieldJson = [
{
"title" : "lastName",
"fieldfieldType": "Text",
"fieldValue": "John"
},
{
"title" : "firstName",
"fieldfieldType": "Text",
"fieldValue": "Doe"
},
{
"title" : "Date",
"fieldType": "Text",
"fieldValue": "Jan 1, 2013"
},
{
"title" : "footballField",
"fieldType": "Button",
"fieldValue": false
},
{
"title" : "baseballField",
"fieldType": "Button",
"fieldValue": true
},
{
"title" : "bballField",
"fieldType": "Button",
"fieldValue": false
},
{
"title" : "hockeyField",
"fieldType": "Button",
"fieldValue": true
},
{
"title" : "nascarField",
"fieldType": "Button",
"fieldValue": false
}
];
const FormFields = {
"lastName" : "John",
"firstName" : "Doe",
"Date" : "Jan 1, 2013",
"footballField" : "Off",
"baseballField" : "Yes",
"bballField" : "Off",
"hockeyField" : "Yes",
"nascarField" : "Off"
};

var mappedFields = pdfFiller.mapForm2PDF( fieldJson, convMap );
console.log(mappedFields);
pdfFiller.mapForm2PDF(data, convMap).then((mappedFields) => {
console.log(mappedFields);
});
````

This will print out the object below.
```
```json

{
"last_name" : "John",
"first_name" : "Doe",
Expand All @@ -169,14 +181,15 @@ This will print out the object below.
"basketball" : "Off",
"hockey" : "Yes",
"nascar" : "Off"
};

}
```

#### 4. Convert fieldJson to FDF data
````javascript
var pdfFiller = require('pdffiller');
import pdfFiller from 'pdffiller-stream';

var fieldJson = [
const fieldJson = [
{
"title" : "last_name",
"fieldfieldType": "Text",
Expand Down Expand Up @@ -219,12 +232,15 @@ var fieldJson = [
}
];

var FDFData = pdfFiller.convFieldJson2FDF( fieldJson );

const FDFData = pdfFiller.convFieldJson2FDF(data);

console.log(FDFData)
````

This will print out this
````
This will print out:

````json
{
"last_name" : "John",
"first_name" : "Doe",
Expand Down
72 changes: 72 additions & 0 deletions fdf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
var fs = require('fs');
var _ = require('lodash');

// only this sequence in FDF header requires char codes
var headerChars = new Buffer(
(String.fromCharCode(226)) +
(String.fromCharCode(227)) +
(String.fromCharCode(207)) +
(String.fromCharCode(211)) +
"\n"
);

var header = Buffer.concat([
new Buffer("%FDF-1.2\n"),
headerChars,
new Buffer(
"1 0 obj \n" +
"<<\n" +
"/FDF \n" +
"<<\n" +
"/Fields [\n"
)
]);

var footer = new Buffer(
"]\n" +
">>\n" +
">>\n" +
"endobj \n" +
"trailer\n" +
"\n" +
"<<\n" +
"/Root 1 0 R\n" +
">>\n" +
"%%EOF\n"
)

var escapeString = function escapeString(value) {
var out = value.toString();
out = out.replace(/\\/g, "\\\\");
out = out.replace(/\(/g, "\\(");
out = out.replace(/\)/g, "\\)");
out = out.toString("utf8");
return out;
}

exports.createFdf = function (data) {
var body = new Buffer([]);

_.mapKeys(data, function (value, name) {
try {
body = Buffer.concat([
body,
new Buffer(
"<<\n" +
"/T (" +
escapeString(name) +
")\n" +
"/V (" +
escapeString(value) +
")\n" +
">>\n"
)
]);
} catch (err) {
let errMsg = "Cannot escape string: '" + name + ": " + value + "'.";
throw Error(errMsg);
}
});

return Buffer.concat([header, body, footer]);
}
Loading