Search code examples
javascriptvue.jsnuxt.jsjspdfhtml2canvas

How to download pdf in nuxt project?


 <div  style="height: 0;position:  fixed;  left: 50%; top: 0; transform: translateX(-50%);
       z-index: -1;overflow: hidden">
          <ticket-pdf v-if="pdfData" :pdfData="pdfData" :downloadBtn="downloadBtn"  @download="downloadBtn = $event"  />   </div>

In my nuxt project, i need to download pdf file in my main componet .When user clicked download button it will be downloaded directlty without previewing pdf component. So i hide my ticket-pdf component inside my main component . This way works in localhost but when i published my project to test area it does not work. It download only 1 empty page. and i face with this mistake.

Failed to load resource: the server responded with a status of 500 ()

If i open my pdf file in a other page and i can preview and download it also. But i need to doownload it without routing anywhere and directly in my main component

  printPDF() {
            const html2canvasOptions = {
                allowTaint: true,
                removeContainer: true,
                imageTimeout: 15000,
                logging: true,
                useCORS: true,
                scrollX: 0,
                scrollY: 0,
                scale: 2,
            };
            // Initialize the PDF.
            let pdf = new jsPDF('p', 'in', [8.5, 11], false);
            let totalPage = 0
//i have many pages and countof pages changes . It depends. so firstly i calculate page count and create pdf.
            let pageCount = document.querySelectorAll('[id^=contentPrint]').length
             for (let i = 0; i < pageCount; i++) {

                const contentPrint = document.getElementById('contentPrint-' + i);
                html2canvas(contentPrint, html2canvasOptions)
                    .then((canvas) => {

                        const image = {type: 'jpeg', quality: 1};
                        const margin = [0.5, 0.5];

                        let imgWidth = 8.5;
                        let pageHeight = 11;

                        let innerPageWidth = imgWidth - margin[0] * 2;
                        let innerPageHeight = pageHeight - margin[1] * 2;

                        // Calculate the number of pages.
                        let pxFullHeight = canvas.height;
                        let pxPageHeight = Math.floor(canvas.width * (pageHeight / imgWidth));
                        let nPages = Math.ceil(pxFullHeight / pxPageHeight);
                        totalPage += nPages

                        // Define pageHeight separately so it can be trimmed on the final page.
                        pageHeight = innerPageHeight;

                        // Create a one-page canvas to split up the full image.
                        let pageCanvas = document.createElement('canvas');
                        let pageCtx = pageCanvas.getContext('2d');
                        pageCanvas.width = canvas.width;
                        pageCanvas.height = pxPageHeight;


                        for (let page = 0; page <= nPages; page++) {
                            // Trim the final page to reduce file size.
                            if (page === nPages - 1 && pxFullHeight % pxPageHeight !== 0) {
                                pageCanvas.height = pxFullHeight % pxPageHeight;
                                pageHeight = (pageCanvas.height * innerPageWidth) / pageCanvas.width;
                            }

                            // Display the page.
                            let w = pageCanvas.width;
                            let h = pageCanvas.height;
                            pageCtx.fillStyle = 'white';
                            pageCtx.fillRect(0, 0, w, h);
                            pageCtx.drawImage(canvas, 0, page * pxPageHeight, w, h, 0, 0, w, h);

                            // Add the page to the PDF.
                            if (page > 0) pdf.addPage();

                            let imgData = pageCanvas.toDataURL('image/' + image.type, image.quality);
                            pdf.addImage(imgData, image.type, margin[1], margin[0], innerPageWidth, pageHeight);

                        }

                    });
            }

            setTimeout(() => {
               // pdf.deletePage(totalPage + 1)
                pdf.save("e-ticket" + '.pdf')

            }, 3000)

            setTimeout(() => {
                this.$emit("download", this.download);
            }, 4000)
        },

This is how i create pdf area. When user clicked download button i create pdf and download it thanks to my props.


Solution

  •     printPDF() {
                window.scrollTo(0, 0);
                // Initialize the PDF.
                let pdf = new jsPDF('p', 'in', [8.5, 11], false);
                let totalPage = 0
                let counter = 0
                let myArray = []
                let pageCount = document.querySelectorAll('[id^=contentPrint]').length
    
                for (let i = 0; i < pageCount; i++) {
                    myArray.push('contentPrint-' + i)
                }
    
                for (let i = 0; i < pageCount; i++) {
    
                    const contentPrint = document.getElementById('contentPrint-' + i);
    
                    html2canvas(contentPrint, {
                        scale: 2, useCORS: true, allowTaint: true, scrollY: 0
                    }).then((canvas) => {
    .................
    ........
    .....
                        counter = counter + 1;
                        callBack();
                    })
                }
    
                const callBack = () => {
                    if (myArray.length === counter) { 
                        pdf.save("filename" + '.pdf')
                        this.$emit("download", this.download);
                    }
                }
            },
    
        
    

    the problem was about my settimeout function . ın there ı would call pdf.save before pdf created and sure every browser works in different speed. so if we use callback function after all process done , then we can obtain our pdf rpint