How to merge two (or more) PDF files into one single file using jsPDF and then show it using the browser's pdf viewer of the user?
My requirement is to make easier the process of printing a group of documents, instead of printing one by one just merge them all and print one single file.
I've looked at this other question here in Stack Overflow but that didn't help me too much because in this case they are creating the pdf from HTML content, and in my case i have to merge a set of pdf files together. Merge two PDF's generated with jsPDF into one document
I could get my PDF files from an url or also getting the raw content from them (the base64 code) so I was wondering if there's a way of using this library to do it. If so I only need to know what methods to use or maybe a link to the documentation (i've also seen documentation but nothing found).
How to merge two (or more) PDF files into one single file using jsPDF and then show it using the browser's pdf viewer of the user?
My requirement is to make easier the process of printing a group of documents, instead of printing one by one just merge them all and print one single file.
I've looked at this other question here in Stack Overflow but that didn't help me too much because in this case they are creating the pdf from HTML content, and in my case i have to merge a set of pdf files together. Merge two PDF's generated with jsPDF into one document
I could get my PDF files from an url or also getting the raw content from them (the base64 code) so I was wondering if there's a way of using this library to do it. If so I only need to know what methods to use or maybe a link to the documentation (i've also seen documentation but nothing found).
Share Improve this question edited Oct 5, 2024 at 22:13 desertnaut 60.4k32 gold badges152 silver badges178 bronze badges asked Feb 14, 2020 at 23:26 Emmanuel_MEmmanuel_M 811 gold badge1 silver badge4 bronze badges2 Answers
Reset to default 6The above solution uses the package pdf-lib. Currently this is the best solution to merge pdfs on the client.
When using async await with Array.map() you need also need to ensure that the documents in the ArrayBuffer[] input stay in the right order. Here is one solution how to do that (TS):
import { PDFDocument, PDFPage } from "pdf-lib";
export async function mergePdfs(pdfsToMerge: ArrayBuffer[]): Promise<ArrayBufferLike> {
const mergedPdf: PDFDocument = await PDFDocument.create();
const createInnerPromise = async (arrayBuffer: ArrayBuffer): Promise<PDFPage[]> => {
const pdf: PDFDocument = await PDFDocument.load(arrayBuffer);
return await mergedPdf.copyPages(pdf, pdf.getPageIndices());
};
const outerPromise: Promise<PDFPage[]>[] = pdfsToMerge.map((arrayBuffer) => {
const innerPromise: Promise<PDFPage[]> = createInnerPromise(arrayBuffer);
return innerPromise;
});
const resultOuterPromise: PDFPage[][] = await Promise.all(outerPromise);
resultOuterPromise.forEach((pageArray: PDFPage[]) => {
pageArray.forEach((page: PDFPage) => {
mergedPdf.addPage(page);
});
});
return (await mergedPdf.save()).buffer;
}
To create the input ArayBuffer[] you can output pdfs from jsPDF as ArrayBuffer with:
jsPdfDocument.output("arraybuffer")
and if it's a File you can use:
await file.arrayBuffer()
You can turn your jsPDF document into an array buffer (check here)
const doc = new jsPDF('p', 'mm', 'a4');
...
const arrayBuffer = doc.output('arraybuffer');
and then use the solution given here
async mergePdfs(pdfsToMerges: ArrayBuffer[]) {
const mergedPdf = await PDFDocument.create();
const actions = pdfsToMerges.map(async pdfBuffer => {
const pdf = await PDFDocument.load(pdfBuffer);
const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
copiedPages.forEach((page) => {
// console.log('page', page.getWidth(), page.getHeight());
// page.setWidth(210);
mergedPdf.addPage(page);
});
});
await Promise.all(actions);
const mergedPdfFile = await mergedPdf.save();
return mergedPdfFile;
}