html2canvas+jsPDF导出超长网页的PDF

项目需求:有一个网页大概60000px的高度,现在需要导出为PDF


index.vue







JS

import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';
import { message } from 'ant-design-vue';


// jsPDFs实例
let pdf = new jsPDF({
    unit: 'pt',
    format: 'a4',
    orientation: 'p',
    // format: [550, 550]
});

// 对图片进行等比缩放
function resizeImage(imgWidth, imgHeight, maxWidth = 590) {
    // 计算当前图片的宽高比
    const ratio = imgWidth / imgHeight;

    // 如果最大宽度小于当前宽度,则按最大宽度进行缩放
    if (imgWidth > maxWidth) {
        return {
            newWidth: maxWidth,
            newHeight: maxWidth / ratio
        };
    } else { // 否则,图片本身就在允许的最大宽度内,不需要缩放
        return {
            newWidth: imgWidth,
            newHeight: imgHeight
        };
    }
}


async function toCanvas(element,scrolledHeight=0,viewHeight=window.innerHeight) {
    // 放大倍率
    const scaleRatio = window.devicePixelRatio * 2
    const canvas = await html2canvas(element, {
        scale: scaleRatio,
        useCORS: true,
        width: document.querySelector("#myList").scrollWidth,
        height: Math.min(element.scrollHeight,  viewHeight),
        windowWidth: document.querySelector("#myList").scrollWidth,
        windowHeight: document.querySelector("#myList").scrollHeight,
        x: 0,
        y: scrolledHeight,
    })
    let canvasImg = canvas.toDataURL("image/jpeg",1);
    return { width:canvas.width, height:canvas.height, data: canvasImg}
}


// 循环生成PDF
let pdfImgTop = 0
let pageHeight = 0
async function loopGeneratePDF(targetElement, scrolledHeight = 0, viewHeight =window.innerHeight) {
    const A4_HEIGHT = 900
    if (scrolledHeight >= targetElement.scrollHeight) {
        message.success("生成PDF成功");
        return;
    }
    const { data: imgData, height, width } = await toCanvas(targetElement, scrolledHeight, viewHeight);
    // console.log("图片",imgData)
    const { newWidth, newHeight } = resizeImage(width, height);
    pdf.addImage(imgData, 'JPEG', 0, pdfImgTop, newWidth, newHeight);
    const pages = pdf.internal.getNumberOfPages()
    message.success(`生成第${pages}页`)
    // 下一次需要截取的开始高度
    scrolledHeight += Math.floor(height / 2);
    pdfImgTop += newHeight;
    // 如果当前页内容不足一页A4纸的高度,则递归调用并调整视图高度
    if (A4_HEIGHT>scrolledHeight) {
        // 剩余页面的高度
        pageHeight = A4_HEIGHT - scrolledHeight;
        return loopGeneratePDF(targetElement, scrolledHeight, pageHeight);
    }
    else {
        if(targetElement.scrollHeight - scrolledHeight > A4_HEIGHT || pdfImgTop>A4_HEIGHT){
            pdf.addPage();
            pdfImgTop = 10;
        }
        return loopGeneratePDF(targetElement, scrolledHeight-20);
    }

}

export const outCanvas = async function (targetElement) {
    if (!(targetElement instanceof HTMLElement)) {
        return;
    }
    await loopGeneratePDF(targetElement,0,window.innerHeight)
   return pdf.save('test.pdf');
}



你可能感兴趣的:(vue,web前端,pdf,vue.js,javascript,html2canvas)