Created
May 3, 2023 15:58
-
-
Save stacklast/dd5601f39baeb853be3b0816c2729d08 to your computer and use it in GitHub Desktop.
Using html2canvas and jsPDF to download html as PDF.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| letterSettings: { | |
| MARGIN_INCHES: 0.5, | |
| WIDTH_INCHES: 8.5, | |
| HEIGHT_INCHES: 11 | |
| } | |
| */ | |
| import constants from "../constants"; | |
| import { jsPDF } from "jspdf"; | |
| import * as html2canvas from "html2canvas"; | |
| export default async function downloadPdf(htmElement, fileName, isSigned = false) { | |
| // To avoid the image will be cut by scroll, we need to scroll top before html2canvas. | |
| window.pageYOffset = 0; | |
| document.documentElement.scrollTop = 0; | |
| document.body.scrollTop = 0; | |
| const iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream; | |
| const options = { | |
| scale: 1, | |
| allowTaint: true, | |
| useCORS: true, | |
| scrollY: 0, | |
| backgroundColor: '#FFFFFF', | |
| removeContainer: true, | |
| imageTimeout: 15000, | |
| windowWidth: '1280px', | |
| onclone: function (clonedDoc) { | |
| const signatures = clonedDoc.getElementsByClassName('signature'); | |
| if (signatures.length > 0) { | |
| let tempSignature = signatures[0]; | |
| let newSignatureText = document.createElement('span'); | |
| newSignatureText.className = tempSignature.className + ' signature-clone'; | |
| newSignatureText.innerText = tempSignature.value ? tempSignature.value : tempSignature.placeholder; | |
| tempSignature.parentNode.replaceChild(newSignatureText,tempSignature); | |
| } | |
| const textAreas = clonedDoc.querySelectorAll('textarea'); | |
| if (textAreas.length > 0) { | |
| for (let index = 0; index < textAreas.length; index++) { | |
| const textArea = textAreas[index]; | |
| const newTextAreaDiv = clonedDoc.createElement('div'); | |
| newTextAreaDiv.className = textArea.className + ' textarea-clone'; | |
| newTextAreaDiv.setAttribute('contenteditable', true); | |
| newTextAreaDiv.innerText = textArea.value ? textArea.value : textArea.placeholder; | |
| textArea.parentNode.replaceChild(newTextAreaDiv,textArea); | |
| } | |
| } | |
| }, | |
| ignoreElements: function (element) { | |
| if ('e-signature-container' == element.id && !isSigned) { | |
| return true; | |
| } | |
| if ('button' == element.tagName.toLowerCase()) { | |
| return true; | |
| } | |
| } | |
| }; | |
| await html2canvas(htmElement, options).then(canvas => { | |
| const image = { type: 'image/jpeg', quality: 1.0 }; | |
| const imgWidth = constants.letterSettings.WIDTH_INCHES; | |
| const pageHeight = constants.letterSettings.HEIGHT_INCHES; | |
| const fullHeightPixels = canvas.height; | |
| const innerPageWidth = imgWidth - constants.letterSettings.MARGIN_INCHES * 2; | |
| const pageHeightPixels = Math.floor(canvas.width * (pageHeight / imgWidth)); | |
| const numberOfPages = Math.ceil(fullHeightPixels / pageHeightPixels); | |
| let innerPageHeight = pageHeight - constants.letterSettings.MARGIN_INCHES * 2; | |
| let pageCanvas = document.createElement('canvas'); | |
| let pageContext = pageCanvas.getContext('2d'); | |
| pageCanvas.width = canvas.width; | |
| pageCanvas.height = pageHeightPixels; | |
| let pdf = new jsPDF('p', 'in', [imgWidth, pageHeight]); | |
| pdf.setDisplayMode('fullwidth', 'continuous', 'FullScreen'); | |
| for (let page = 0; page < numberOfPages; page++) { | |
| if (page === numberOfPages - 1 && fullHeightPixels % pageHeightPixels !== 0) { | |
| pageCanvas.height = fullHeightPixels % pageHeightPixels; | |
| innerPageHeight = (pageCanvas.height * innerPageWidth) / pageCanvas.width; | |
| } | |
| pageContext.fillStyle = 'white'; | |
| pageContext.fillRect(0, 0, pageCanvas.width, pageCanvas.height); | |
| pageContext.drawImage(canvas, 0, page * pageHeightPixels, pageCanvas.width, pageCanvas.height, 0, 0, pageCanvas.width, pageCanvas.height); | |
| if (page > 0) { | |
| pdf.addPage(); | |
| } | |
| let imgData = pageCanvas.toDataURL('image/' + image.type, image.quality); | |
| pdf.addImage(imgData, image.type, constants.letterSettings.MARGIN_INCHES, constants.letterSettings.MARGIN_INCHES, innerPageWidth, innerPageHeight); | |
| } | |
| if (iOS) { | |
| const link = pdf.output("bloburl"); | |
| const a = document.createElement("a"); | |
| a.href = link; | |
| a.target = '_blank'; | |
| a.download = fileName +'.pdf'; | |
| a.click(); | |
| } else { | |
| pdf.save(fileName +'.pdf'); | |
| } | |
| }).catch(error => { | |
| console.error("Error " + error); | |
| }); | |
| } | |
| /* | |
| HOW TO USE | |
| const htmElement = document.getElementById('contract-pdf-container'); | |
| const fileName = 'filename'; | |
| await downloadPdf(htmElement, fileName, this.controller.isSigned); | |
| */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment