Search code examples
javascriptjspdf

Merge two PDF's generated with jsPDF into one document


I'm using jsPDF for generation of document from HTML (with using .html() method) and it works fine. But now I need to do next:

  1. Create jsPDF object.
  2. Add content with using .html() method.
  3. Add new page to created document.
  4. Add content to second page with using the same .html() method.
  5. Save created document.

Here is the code example:

var doc = new jsPDF({ orientation: 'p', format: 'a4'  });
doc.html(document.getElementById('test'), {
   callback: function (doc) {
      doc.addPage('a4', 'p');
      doc.html(document.getElementById('test'), {
         callback: function (doc) {
            doc.output('dataurlnewwindow');
      }
   }
}

Problem is the second page is always blank. The idea is to create two separate documents with using .html() method and then merge this two document into one and save it.

So question is - is it possible in jsPDF to merge two documents into one and save it then?

Thanks in advance!


Solution

  • I can successfully merge multi jsPDF object to one pdf file with this:

    // .ts
     private async generatePdfList(type: string, page = 1) {
        console.log('STEP 1:', new Date());
        const elements = document.querySelectorAll('.staff-list-receipt');
        const elementArray = Array.from(elements);
        const bufferPromises: Promise<any>[] = elementArray
          .filter(element => !!element)
          .map(element => this.elementToPdfBuffer(type, element, page));
        const pdfArrayBuffers = await Promise.all(bufferPromises);
        console.log('STEP 2:', new Date());
        const mergedPdf = await this.mergePdfs(pdfArrayBuffers);
        const pdfUrl = URL.createObjectURL(
          new Blob([mergedPdf], { type: 'application/pdf' }),
        );
      }
    
      async elementToPdfBuffer(type, element, page) {
        // option 1:
        // const pdf: jsPDF = html2pdf().from(element).toPdf().get("pdf");
        // option 2:
        new jsPDF().fromHTML(element);
        const pdfBuffer = await pdf.output("arraybuffer");
        return pdfBuffer;
      }
    
      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;
      }