乐趣区

关于javascript:Javascript-html2canvas-jsPDF-导出PDF解决一半文字在上一页一半文字在下一页的问题

        var pdfContent = document.getElementById("pdfDiv");
        var width = pdfContent.offsetWidth; // 获取 dom 宽度
        var height = pdfContent.offsetHeight; // 获取 dom 高度
        var canvas = document.createElement("canvas"); // 创立一个 canvas 节点
        var scale = 3; // 定义任意放大倍数 反对小数,越大越清晰
        var offsetTop = pdfContent.offsetTop;
        var rect = pdfContent.getBoundingClientRect();// 获取元素绝对于视察的偏移量
        canvas.width = width * scale; // 定义 canvas 宽度 * 缩放
        canvas.height = (height + offsetTop) * scale; // 定义 canvas(高度 + 偏移量)* 缩放
        var content = canvas.getContext("2d");
        content.scale(scale, scale); // 获取 context, 设置 scale
        content.translate(-rect.left, -rect.top);// 设置 context 地位,值为绝对于视窗的偏移量负值,让图片复位
        // content.translate(-rect.left, -rect.top + 135);// 设置 context 地位,值为绝对于视窗的偏移量负值,让图片复位
        var opts = {
            background: "#fff",
            scale: scale, // 增加的 scale 参数
            canvas: canvas, // 自定义 canvas
            // logging: true, // 日志开关,便于查看 html2canvas 的外部执行流程
            width: width, //dom 原始宽度
            height: height,
            useCORS: true, //【重要】开启跨域配置
            allowTaint: true,
            taintTest: false,
            // scrollY: 0,
            // scrollX: 0

        };
        html2canvas(pdfContent,opts).then(function (canvas) {downloadCanvasWithMargin(canvas);
        })
        //-----------------------
        function downloadCanvasWithMargin(canvas){
        // 敞开锯齿
        var context = canvas.getContext('2d');
        context.mozImageSmoothingEnabled = false;
        context.webkitImageSmoothingEnabled = false;
        context.msImageSmoothingEnabled = false;
        context.imageSmoothingEnabled = false;

        let contentWidth = canvas.width;
        let contentHeight = canvas.height;
        // 一页 pdf 显示 html 页面生成的 canvas 高度;
        let pageHeight = contentWidth / 595.28 * 841.89;
        // 未生成 pdf 的 html 页面高度
        let leftHeight = contentHeight;
        let cutStartHeight = 0;
        let canvasArr = [];
        if(leftHeight > pageHeight) {while (leftHeight > 0) {// 复制出 (0, cutStartHeight) 开始,contentWidth 宽和 pageHeight 高的图片
                let cutImage = context.getImageData(0, cutStartHeight, contentWidth, pageHeight);
                // 以通明背景开始,抛弃
                if(cutImage.data[0] === 0 ){
                    leftHeight -= pageHeight;
                    cutStartHeight += pageHeight;
                    continue;
                }
                // 从图像底部开始校验色彩,直到验证到已红色结尾才开始切图像
                let moveUpPx = 0; // 上移 px 数
                let totalLength = cutImage.data.length;
                let lineLength = 4 * contentWidth * 1; // 一行的 data 容量
                let leftLength = totalLength - lineLength;
                let rightLength = totalLength;
                let circle = 0; // 循环次数
                let pointRatio = 0.98; // 一行非给定色彩的占比系数
                let pointRatioNum = contentWidth * pointRatio;
                while(circle === moveUpPx){
                    circle ++;
                    let ignorePoint = 0;
                    for(let i = leftLength; i< rightLength ; i+=4){if(cutImage.data[i] === 255 || cutImage.data[i] === 251){if(cutImage.data[i] === cutImage.data[i+1] && cutImage.data[i] === cutImage.data[i+2]){ignorePoint++;}
                        }
                    }
                    if(ignorePoint < pointRatioNum){
                        leftLength -= lineLength;
                        rightLength -= lineLength;
                        moveUpPx ++;
                    }
                }
                if(moveUpPx > 0){cutImage = context.getImageData(0, cutStartHeight, contentWidth, pageHeight - moveUpPx);
                }
                leftHeight -= pageHeight + moveUpPx;
                cutStartHeight += pageHeight - moveUpPx;
                // 创立新图片
                let nCanvas = document.createElement("canvas"); // 创立一个 canvas 节点
                nCanvas.width = canvas.width;
                nCanvas.height = pageHeight - moveUpPx;
                let nContext = nCanvas.getContext("2d");
                nContext.mozImageSmoothingEnabled = false;
                nContext.webkitImageSmoothingEnabled = false;
                nContext.msImageSmoothingEnabled = false;
                nContext.imageSmoothingEnabled = false;
                nContext.putImageData(cutImage, 0, 0)
                canvasArr.push(nCanvas);
            }
        }else{canvasArr.push(canvas);
        }
        // 解决尾页图片通明背景
        let lastCanvas = canvasArr[canvasArr.length - 1];
        let ctx = lastCanvas.getContext("2d");
        // 将 canvas 的通明背景设置成红色 -- 解决 translate 后便彩色背景的问题
        let imageData = ctx.getImageData(0, 0, lastCanvas.width, lastCanvas.height);
        for(var i = 0; i < imageData.data.length; i += 4) {
            // 当该像素是通明的,则设置成红色
            if(imageData.data[i + 3] === 0) {imageData.data[i] = 255;
                imageData.data[i + 1] = 255;
                imageData.data[i + 2] = 255;
                imageData.data[i + 3] = 255;
            }
        }
        ctx.putImageData(imageData, 0, 0);

        var pdf = new jsPDF('','pt','a4');
        let leftMargin = 20;
        let topMargin = 20;
        let a4Width = 595.28;
        let a4Height = 841.89;
        let imgWidth = a4Width - leftMargin * 2;
        let imgHeight = a4Height - 2 * topMargin;
        for(let i =0; i < canvasArr.length; i++){let curCanvas = canvasArr[i];
            let pageData = curCanvas.toDataURL('image/jpeg', 1.0);
            // 小于切分的高度,要换算比例高
            if(curCanvas.height < pageHeight){
                let ratioHeight = imgWidth / curCanvas.width * curCanvas.height;
                pdf.addImage(pageData, 'JPEG', leftMargin, topMargin, imgWidth, ratioHeight);
            }else{pdf.addImage(pageData, 'JPEG', leftMargin, topMargin, imgWidth, imgHeight);
            }
            if(i < (canvasArr.length-1)){pdf.addPage();
            }
        }
        let date = new Date();
        let year = date.getFullYear();
        let month = date.getMonth() + 1;
        let day = date.getDate();
        let milliSeconds = date.getMilliseconds();
        pdf.save(year + month + day + milliSeconds +'.pdf');
    }
退出移动版