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

How to insert QR code from html to an existing pdf? #927

Closed
crthc opened this issue Jul 1, 2021 · 4 comments
Closed

How to insert QR code from html to an existing pdf? #927

crthc opened this issue Jul 1, 2021 · 4 comments

Comments

@crthc
Copy link

crthc commented Jul 1, 2021

Hi, thanks for contributing with this library!

I'm working on a project with typescript in Angular where I'm creating a QR code which I get from the DOM and create a new pdf file with the QR Code in it. However, I need to modify an existing pdf file with several pages and insert the QR Code in every page.

I inserted the QR Code into a new PDF with this method using the jsPDF library.

public createPDF() {
    const canvas: any = document.querySelector('#qr canvas');
    const imgWidth = 100;
    const imgHeight = (canvas?.height * imgWidth) / canvas?.width;
    const contentDataURL = canvas?.toDataURL('image/png');
    const pdf = new jsPDF('p', 'mm', 'a4');
    pdf.addImage(contentDataURL, 'PNG', 0, 0, imgWidth, imgHeight);
    pdf.save('contract_' + this.contractDischarge + '.pdf');
  }

As I discovered with pdf-lib, it's possible to modify an existing PDF and add png or jpeg image. But is it possible to insert a QR Code that I get from the html with querySelector and insert it to every page of an existing PDF and how?

I tried reproducing a method that draw text to an existing pdf, but I cannot download it to check if it works, because download does not work in the typescript method.

import { degrees, PDFDocument, rgb, StandardFonts } from 'pdf-lib';

 public async modifyPdf() {
    const url = 'https://pdf-lib.js.org/assets/with_update_sections.pdf'
    const existingPdfBytes = await fetch(url).then(res => res.arrayBuffer())
  
    const pdfDoc = await PDFDocument.load(existingPdfBytes)
    const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica)
  
    const pages = pdfDoc.getPages()
    const firstPage = pages[0]
    const { width, height } = firstPage.getSize()
    firstPage.drawText('This text was added with JavaScript!', {
      x: 5,
      y: height / 2 + 300,
      size: 50,
      font: helveticaFont,
      color: rgb(0.95, 0.1, 0.1),
      rotate: degrees(-45),
    })
  
    const pdfBytes = await pdfDoc.save()

download(pdfBytes, "pdf-lib_modification_example.pdf", "application/pdf");

  }

Therefore, how could you insert a QR Code that's got from the Html with querySelector and add it to an existing PDF file on every page? and how could you download that pdf on a class method with typescript, since dowload does not work.

Thank you very much!

@crthc
Copy link
Author

crthc commented Jul 2, 2021

So, I ended up with the solution I was looking for!

The following method converts canvas to a PNG image, then embed the image into an existing pdf and draw the image in every page of the document on the top right corner. Finally, it opens up a new tab where you can get the pdf and download it.

 public async embedQrToPdf() {
    const pdf = 'assets/documents/any.pdf';
    const canvas: any = document.querySelector('#qr canvas');
    const contentDataURL = canvas?.toDataURL('image/png');
    const pngUrl = contentDataURL;
 

    const existingPdfBytes = await fetch(pdf).then(res => res.arrayBuffer());
    const pngImageBytes = await fetch(pngUrl).then((res) => res.arrayBuffer());
  
    const pdfDoc = await PDFDocument.load(existingPdfBytes);

    const pngImage = await pdfDoc.embedPng(pngImageBytes);
    const pngDims = pngImage.scale(0.250);
  
    const pages = pdfDoc.getPages();
    
    pages.forEach(page => {
      page.drawImage(pngImage, {
        x: 510,
        y: 775,
        width: pngDims.width,
        height: pngDims.height,
      })
    })
   
    const pdfBytes = await pdfDoc.save();

    let file = new Blob([pdfBytes], { type: 'application/pdf' });
    let fileURL = URL.createObjectURL(file);
    window.open(fileURL);
  }

@crthc crthc closed this as completed Jul 2, 2021
@crthc crthc reopened this Jul 2, 2021
@Hopding
Copy link
Owner

Hopding commented Sep 22, 2021

Your solution looks pretty much like what I'd do 👍

@peterzhai
Copy link

Hello,
when I drawed a image from a canvas.toDataURL() with pdfDoc.embedPng(base64) in the nodejs, it fail and no response.But I used the existing png image,It was success。the file below is converd from the base64 . Has It ever happened to you? Thank you very much!
base64

@shadoath
Copy link

@crthc I like this solution. I want to do this with dynamically generated QR codes.
Would this also be possible by doing it like this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants