Pdf-Ops
Demo website
Table of Contents
Description
This node js package is able to perform various pdf tasks as desired and is able to save the resultant pdf as a new file or return a file Buffer.
Installation
npm install --save pdf-ops
Features
- Split PDFs
- Merge PDFs
- Rotate PDFs
- Resize PDFs
- Add Margin to the PDFs
- Convert images to Pdf
Usage Examples
Note - Some of the functions in this module only work on the clients side, not on server side
Note - All the pdf files in these examples are not kept directly inside of the root folder but in a folder named "test_files" inside the root folder
Split Pdfs
Split PDF into single paged PDFs
import { PdfSplitter } from 'pdf-ops';
(async () => {
const splitter = new PdfSplitter();
await splitter.split(pdf1);
const split = await splitter.getPdfBuffer();
})();
For pdf1 the pdfs formed will be split
Split PDF with range specification
import { PdfSplitter } from 'pdf-ops';
(async () => {
const splitter = new PdfSplitter();
await splitter.splitWithRange(pdf2, [1, [2, 3], [4, 6], ['end', 3]]);
const splitWithRange = await splitter.getPdfBuffer();
})();
For pdf2 the files formed will be splitWithRange
Split multiple PDFs with a single object
-
You can keep on adding more and more pdf files in the same object, when you will save the pdfs, all of them will be in the same folder, in the order in which they were splitted
-
Saving the file does not clear out the existing object, as you populate more and more pdfs in the same object they will keep on getting accumulated.
-
For clearing all the pdfs stored in the object you can use splitter.clearDoc()
to reinitialize a the PdfSplitter object
-
Let us put all the above into a expample for explanation
import { PdfSplitter } from 'pdf-ops';
(async () => {
const splitter = new PdfSplitter();
await splitter.splitWithRange(pdf1, [
[1, 3],
[4, 6],
]);
await splitter.split(pdf2);
const split1 = await splitter.getPdfBuffer();
await splitter.split(pdf4);
const split2 = await splitter.getPdfBuffer();
await splitter.clearDoc();
await splitter.splitWithRange(pdf3, [['end', 'start']]);
const split3 = await splitter.getPdfBuffer();
})();
Merge Splitted PDfs into a sigle PDF
import { PdfMerger, PdfSplitter } from 'pdf-ops';
(async () => {
const splitter = new PdfSplitter();
await splitter.splitWithRange(pdf1, [[1, 3]]);
await splitter.split(pdf2);
await splitter.splitWithRange(pdf1, [[4, 6]]);
const merger = new PdfMerger();
await merger.merge(splitter.getDocs());
const split_merged = await merger.getPdfBuffer();
})();
Get array of buffer of the resultant PDFs
- Getting the buffer (Uint8Array) is pretty straight foward. You can access buffer by
await splitter.getPdfBuffer()
and it will return you the array of buffers of all the splitted pdfs
import { PdfSplitter } from 'pdf-ops';
(async () => {
const splitter = new PdfSplitter();
await splitter.splitWithRange(pdf1, [[1, 3]]);
await splitter.split(pdf2);
await splitter.splitWithRange(pdf1, [[4, 6]]);
const bufferList = await splitter.getPdfBuffer();
})();
Merge Pdfs
Merge multiple PDFs (all pages of all PDFs) into a single PDF
import { PdfMerger } from 'pdf-ops';
(async () => {
const merger = new PdfMerger();
await merger.merge([pdf1, pdf2, pdf3]);
const merged = await merger.getPdfBuffer();
})();
In this example pdf1, pdf2, and pdf3 will generate merged.pdf
Merge multiple PDFs with range specification
import { PdfMerger } from 'pdf-ops';
(async () => {
const merger = new PdfMerger();
await merger.mergeWithRange([
{
filepath: pdf4,
range: [1, 5],
},
{
filepath: pdf1,
range: [1, 2],
},
{
filepath: pdf2,
range: [3, 4],
},
{
filepath: pdf3,
range: [5, 6],
},
]);
const mergedWithRange = await merger.getPdfBuffer();
})();
In this example pdf1, pdf2, pdf3, and pdf4 will generate mergedWithRange.pdf
rules to specify range
Merge multiple PDFs multiple times with a single object
-
You can keep on adding more and more pdfs in the same object and save whenever you want.
-
Saving the pdf file does not clear the object and if you add new pages into it, they will succeed the pages already present in the object
-
For clearing the object you can use merger.clearDoc()
. This will remove all the pages from the object
-
Let's put all the above into one example for explanation
import { PdfMerger } from 'pdf-ops';
(async () => {
const merger = new PdfMerger();
await merger.mergeWithRange([
{
filepath: pdf1,
range: [1, 2],
},
{
filepath: pdf2,
range: [5, 6],
},
]);
await merger.merge([pdf4]);
const merge1 = await merger.getPdfBuffer();
await merger.mergeWithRange([
{
filepath: pdf3,
range: [[2, 4]],
},
]);
const merge2 = await merger.getPdfBuffer();
await merger.clearDoc();
await merger.mergeWithRange([
{
filepath: pdf1,
range: [1, 6],
},
{
filepath: pdf2,
range: [1, 6],
},
{
filepath: pdf3,
range: [1, 6],
},
{
filepath: pdf4,
range: [1, 6],
},
]);
const merge3 = await merger.getPdfBuffer();
})();
Get buffer of the resultant PDF
- Getting the buffer (Uint8Array) is pretty straight foward. You can access buffer by
await merger.getPdfBuffer()
and it will return you the buffer of the merged pdf
import { PdfMerger } from 'pdf-ops';
(async () => {
const merger = new PdfMerger();
await merger.mergeWithRange([
{ filepath: pdf1, range: [1, 2] },
{ filepath: pdf2, range: [5, 6] },
]);
await merger.merge([pdf4]);
const buffer = await merger.getPdfBuffer();
console.log(buffer);
})();
Rotate Pdfs
Rotate all pages of a PDF
import { PdfRotator } from 'pdf-ops';
(async () => {
const rotator = new PdfRotator();
await rotator.rotate(pdf1, 90);
const rotated = await rotator.getPdfBuffer();
})();
In this example pdf1 will generate rotated.pdf
Rotate pages of different PDFs with range specification
import { PdfRotator } from 'pdf-ops';
(async () => {
const rotator = new PdfRotator();
await rotator.rotateWithRange([
{
file: pdf1,
range: [1, 2, 5, 6],
degree: 90,
},
{
file: pdf2,
range: [1, 5],
degree: -90,
},
{
file: pdf3,
range: [5, 6, 1, 2],
degree: 180,
},
]);
await rotator.getPdfBuffer();
})();
In this example pdf1, pdf2, and pdf3 will generate rotatedWithRange.pdf
Merge multiple rotated pdf with single object
-
The rotated pdfs rotated with a single object will be automatically merged in order in which they were rotated
-
The object will not be cleared after saving the file, therefore the pdfs will keep on getting merged into the previously rotated pdf files
-
For clearing the pages in the object use await rotator.clearDoc()
-
Lets put all this into an example for explanation
import { PdfRotator } from 'pdf-ops';
(async () => {
const rotator = new PdfRotator();
await rotator.rotate(pdf1, 90);
await rotator.rotateWithRange([
{
file: pdf3,
range: [[2, 5]],
degree: 180,
},
]);
const rotated1 = await rotator.getPdfBuffer();
await rotator.rotateWithRange([
{
file: pdf2,
range: [1, 6],
degree: -90,
},
]);
const rotated2 = await rotator.getPdfBuffer();
await rotator.clearDoc();
await rotator.rotate(pdf4, 0);
const rotated3 = await rotator.getPdfBuffer();
})();
Get buffer of the resultant rotated PDF
- Getting the buffer (Uint8Array) is pretty straight foward. You can access buffer by
await rotator.getPdfBuffer()
and it will return you the buffer of the resultant pdf
import { PdfRotator } from 'pdf-ops';
(async () => {
const rotator = new PdfRotator();
await rotator.rotate(pdf1, 90);
await rotator.rotateWithRange([
{
file: pdf3,
range: [[2, 5]],
degree: 180,
},
]);
await rotator.rotate(pdf4, 0);
const buffer = await rotator.getPdfBuffer();
console.log(buffer);
})();
Resize Pdfs
Resize all pages of a PDF
import { PdfResizer } from 'pdf-ops';
(async () => {
const resizer = new PdfResizer();
const options = {
size: 'A3',
};
await resizer.resize(pdf3, options);
const resized = await resizer.getPdfBuffer();
})();
In this example pdf3 will generate resized.pdf
Possible values in resize options
default_option_values = {
orientation: 'portrait',
mode: 'shrink-to-fit',
position: 'center',
size: 'A4',
};
type resizeOptions = {
orientation: 'portrait' | 'landscape';
mode: 'shrink-to-fit' | 'fit-to-page' | 'crop';
position:
| 'center'
| 'top-left'
| 'top-right'
| 'bottom-right'
| 'bottom-left'
| 'center-left'
| 'center-right'
| 'center-top'
| 'center-bottom';
size:
| [number, number]
| 'do-not-change'
| '4A0'
| '2A0'
| 'A0'
| 'A1'
| 'A2'
| 'A3'
| 'A4'
| 'A5'
| 'A6'
| 'A7'
| 'A8'
| 'A9'
| 'A10'
| 'B0'
| 'B1'
| 'B2'
| 'B3'
| 'B4'
| 'B5'
| 'B6'
| 'B7'
| 'B8'
| 'B9'
| 'B10'
| 'C0'
| 'C1'
| 'C2'
| 'C3'
| 'C4'
| 'C5'
| 'C6'
| 'C7'
| 'C8'
| 'C9'
| 'C10'
| 'RA0'
| 'RA1'
| 'RA2'
| 'RA3'
| 'RA4'
| 'SRA0'
| 'SRA1'
| 'SRA2'
| 'SRA3'
| 'SRA4'
| 'Executive'
| 'Folio'
| 'Legal'
| 'Letter'
| 'Tabloid';
};
Resize pages of different PDFs with range specification
import { PdfResizer } from 'pdf-ops';
(async () => {
const resizer = new PdfResizer();
await resizer.resizeWithRange([
{
file: pdf1,
range: [[3, 5]],
options: {
size: 'Letter',
orientation: 'landscape',
},
},
{
file: pdf4,
range: [[2, 3]],
options: {
size: 'A5',
mode: 'crop',
},
},
]);
const resizedWithRange = await resizer.getPdfBuffer();
})();
In this example pdf1 and pdf4 will generate resizedWithRange.pdf
Merge multiple resized pdf with single object
-
The resized pdfs resized with a single object will be automatically merged in order in which they were resized
-
The object will not be cleared after saving the file, therefore the pdfs will keep on getting merged into the previously resized pdf files
-
For clearing the pages in the object use await resizer.clearDoc()
-
Lets put all this into an example for explanation
import { PdfResizer } from 'pdf-ops';
(async () => {
const resizer = new PdfResizer();
await resizer.resize(pdf3, {
size: 'A3',
mode: 'crop',
position: 'top-left',
});
await resizer.resizeWithRange([
{
file: pdf4,
range: [1, 2, 5],
options: { size: 'A5' },
},
]);
const resized1 = await resizer.getPdfBuffer();
await resizer.resize(pdf1, {
size: 'A4',
orientation: 'landscape',
position: 'center-right',
});
const resized2 = await resizer.getPdfBuffer();
await resizer.clearDoc();
await resizer.resizeWithRange([
{
file: pdf2,
range: [2, 3],
},
]);
const resized3 = await resizer.getPdfBuffer();
})();
Get buffer of the resultant resized PDF
- Getting the buffer (Uint8Array) is pretty straight foward. You can access buffer by
await resizer.getPdfBuffer()
and it will return you the buffer of the resultant pdf
import { PdfResizer } from 'pdf-ops';
(async () => {
const resizer = new PdfResizer();
await resizer.resize(pdf3, { size: 'A3', mode: 'crop' });
await resizer.resizeWithRange([
{
file: pdf4,
range: [1, 2],
options: { size: 'A5' },
},
]);
const buffer = await resizer.getPdfBuffer();
console.log(buffer);
})();
Add Margin to the Pdf
Add margin to all the pages of the pdf
import { PdfMarginManipulator } from 'pdf-ops';
(async () => {
const marginManipulator = new PdfMarginManipulator();
await marginManipulator.addMargin(pdf3, [20, 10, 5, 15]);
const addedMargin = await marginManipulator.getPdfBuffer();
})();
In this example pdf3 will generate addedMargin.pdf
Add margin to pages of different PDFs with a range specification
import { PdfMarginManipulator } from 'pdf-ops';
(async () => {
const marginManipulator = new PdfMarginManipulator();
await marginManipulator.addMarginWithRange([
{
file: pdf1,
range: [1, 2],
margin: [10, 10, 10, 10],
},
{
file: pdf2,
range: [3, 4],
margin: [20, 20, 20, 20],
},
{
file: pdf3,
range: [5, 6],
margin: [30, 30, 30, 30],
},
]);
const addedMarginWithRange = await marginManipulator.getPdfBuffer();
})();
In this example pdf1, pdf2 and pdf3 will generate addedMarginWithRange.pdf
Merge multiple pdfs with added margin with single object
-
The pdfs with added margin with a single object will be automatically merged in order in which they were manipulated
-
The object will not be cleared after saving the file, therefore the pdfs will keep on getting merged into the previously manipulated pdf files
-
For clearing the pages in the object use await marginManipulator.clearDoc()
-
Lets put all this into an example for explanation
import { PdfMarginManipulator } from 'pdf-ops';
(async () => {
const marginManipulator = new PdfMarginManipulator();
await marginManipulator.addMargin(pdf1, [0, 10, 10, 10]);
await marginManipulator.addMarginWithRange([
{
file: pdf2,
range: [[2, 4]],
margin: [10, 0, 10, 10],
},
]);
const addMargin1 = await marginManipulator.getPdfBuffer();
await marginManipulator.addMargin(pdf3, [10, 10, 0, 10]);
const addMargin2 = await marginManipulator.getPdfBuffer();
await marginManipulator.clearDoc();
await marginManipulator.addMarginWithRange([
{
file: pdf4,
range: [1, 5, 6],
margin: [10, 10, 10, 0],
},
]);
const addMargin3 = await marginManipulator.getPdfBuffer();
})();
Get buffer of the resultant pdf with added margin
- Getting the buffer (Uint8Array) is pretty straight foward. You can access buffer by
await marginManipulator.getPdfBuffer()
and it will return you the buffer of the resultant pdf
import { PdfMarginManipulator } from 'pdf-ops';
(async () => {
const marginManipulator = new PdfMarginManipulator();
await marginManipulator.addMargin(pdf1, [0, 10, 10, 10]);
await marginManipulator.addMarginWithRange([
{
file: pdf2,
range: [[2, 4]],
margin: [10, 0, 10, 10],
},
]);
const buffer = await marginManipulator.getPdfBuffer();
console.log(buffer);
})();
Convert images to PDF
Convert all images to pdf
import { ImageToPdfConverter } from 'pdf-ops';
(async () => {
const converter = new ImageToPdfConverter();
const options = {
size: 'B3',
orientation: 'portrait',
mode: 'crop',
position: 'bottom-left',
opacity: 0.8,
margin: [0, 10, 20, 30],
};
await converter.createPdf(
['test_files/images3/img1.png', 'test_files/images3/img2.png', 'test_files/images3/img3.png'],
options,
);
await converter.getPdfBuffer();
})();
If img1, img2 and img3 then imgToPdf.pdf will look like this
Possible values in image to pdf options
export type createOptions = resizeOptions & {
opacity?: number,
margin?: [number, number, number, number],
};
default_create_options = {
size: 'do-not-change',
orientation: 'portrait',
mode: 'shrink-to-fit',
position: 'center',
opacity: 1,
margin: [0, 0, 0, 0],
};
For resize option click on this
Merge the converted images with single object
import { ImageToPdfConverter } from 'pdf-ops';
(async () => {
const converter = new ImageToPdfConverter();
await converter.createPdf(
['test_files/images3/img1.png', 'test_files/images3/img2.png', 'test_files/images3/img3.png'],
{
size: 'B3',
orientation: 'portrait',
margin: [0, 10, 20, 30],
},
);
await converter.createPdf(
['test_files/images2/img5.png', 'test_files/images2/img6.png', 'test_files/images2/img7.png'],
{
size: 'A4',
position: 'center-top',
margin: [20, 20, 20, 20],
},
);
await converter.getPdfBuffer();
})();
If img1, img2, img3, img5, img6, img7 then imgToPdfMerged.pdf will look like this
Get buffer of the resultant image inserted pdf
- Getting the buffer (Uint8Array) is pretty straight foward. You can access buffer by
converter.getImageBuffer()
and it will return you the array of buffers of the resultant pdf
import { ImageToPdfConverter } from 'pdf-ops';
(async () => {
const converter = new ImageToPdfConverter();
await converter.createPdf(
['test_files/images3/img1.png', 'test_files/images3/img2.png', 'test_files/images3/img3.png'],
{
size: 'B3',
orientation: 'portrait',
margin: [0, 10, 20, 30],
},
);
const buffer = await converter.getPdfBuffer();
console.log(buffer);
})();
Rules for specifying range
-
Single Page Selection: To select a single page, specify the page number as an integer. For example: [1] selects page 1.
-
Multiple Page Selection: To select multiple non-consecutive pages, list the page numbers as separate integers within square brackets. For example: [1, 2, 3] selects pages 1, 2, and 3.
-
Page Range Selection: To select a range of consecutive pages, specify the starting and ending page numbers as a two-element array within square brackets. For example: [5, 10] selects pages 5 to 10, inclusive.
-
Mixed Page Selection: To select a combination of single pages, page ranges, and the start or end of the PDF, provide them as separate elements in the array. For example: [1, 2, 3, [6, 10], [7, "end"]] selects pages 1, 2, 3, 6 to 10, page 7 to the end of the PDF.
-
To select from a specific page to the end of the PDF, use the string "end" as the second element in the array. For example: [7, "end"] selects page 7 to the end of the PDF.
-
To select from the start of the PDF to a specific page, use the string "start" as the first element in the array. For example: ["start", 3] selects from the start of the PDF to page 3.
-
Reverse Page Selection: To select pages in reverse order, specify the page numbers in reverse order within a two-element array.
-
To select a range of pages in reverse order, provide the ending page number as the first element and the starting page number as the second element in the array. For example: [10, 6] selects pages 10 to 6 in reverse order.
-
To select from a specific page to the beginning of the PDF in reverse, use the "start" keyword as the second element and the page number as the first element in the array. For example: [4, "start"] selects page 4 to the beginning of the PDF in reverse order.
File input
- You can give any of the follow type as input to the variable:
- Blob: raw file.
- File: input file from the DOM
- ArrayBuffer: Input file using fs module
- Uint8Array: Input file using fs module
- PDFDocument: PDFDocument object from pdf-lib