html2canvas+jsPdf前端生成PDF以及处理分页图片文字被截断问题

注:使用html2canvas将DOM生成canvas,然后生成对应的图片,将图片生成pdf

html2canvas.js和jsPdf.js   插件在阿里网盘

一、如果需要生成pdf的区域有div内部滚动,只会下载可视区域内容bug解决

  解题:在点击下载事件之前,改变样式,先把滚动区域变成正常的从上到下铺开,完成之后再把样式改回来

二、如果需要生成的pdf的区域很长,浏览器出现了滚动条,只会下载可视区域内容bug解决

  解题:点击的时候先把滚动条回到0位置就可以

方法:

pdf() {
                // 避免出现浏览器滚动条导致的内容不全处理
                document.body.scrollTop = 0;
                //div内部滚动导致内容不全处理
                document.getElementById("app").style.height = 'auto';
                setTimeout(()=>{
                    html2canvas(document.getElementById("upload"), {
                        background: '#FFF',
                        allowTaint : true,
                        height: document.getElementById('upload').scrollHeight,
                        windowHeight: document.getElementById('upload').scrollHeight
                    }).then(canvas => {
                        var contentWidth = canvas.width;
                        var contentHeight = canvas.height;

                        //一页pdf显示html页面生成的canvas高度;
                        var pageHeight = contentWidth / 592.28 * 841.89;
                        //未生成pdf的html页面高度
                        var leftHeight = contentHeight;
                        //页面偏移
                        var position = 0;
                        //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
                        var imgWidth = 595.28;
                        var imgHeight = 592.28 / contentWidth * contentHeight;

                        var pageData = canvas.toDataURL('image/jpeg', 1.0);

                        var pdf = new jsPDF('p', 'pt', 'a4');

                        //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
                        //当内容未超过pdf一页显示的范围,无需分页
                        if (leftHeight < pageHeight) {
                            pdf.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight);
                        } else {
                            while (leftHeight > 0) {
                                pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
                                leftHeight -= pageHeight;
                                position -= 841.89;
                                //避免添加空白页
                                if (leftHeight > 0) {
                                    pdf.addPage();
                                }
                            }
                        }
                        pdf.save("content.pdf");
                        document.getElementById("app").style.height = '100%';
                    })
                
                },300)
                
            },
            

 三、pdf出现分页时图片文字被截断问题(如下图所示,解决方法参考:https://blog.csdn.net/qq_32244819/article/details/109678481)

解题:获取所有的需要下载的外层盒子,循环处理这些盒子,获取当前盒子距离顶部的高度offsetTop加上盒子的高度是否大于a4纸的高度,如果大于就在之前插入空白盒子,把内容挤下去

 

 

 

dom结构(需要在下载区域的所有外层盒子添加类似于item这样的类名)

<div class="content" id="content">
    <div class="item">内容</div>
    <div class="item">内容</div>
    <!--    每一块dom的class类设置成item(自定义)以此处理内容分割  -->
    <div class="item">内容</div>
    <div class="item">内容</div>
</div>

组件内编写导出方法,methods方法 outPutPdfFn,(其中isSplit方法判断是否要分割)

 代码如下:

 //避免分页被截断
            outPutPdfFn () {
                let vm = this;
                const A4_WIDTH = 592.28;
                const A4_HEIGHT = 841.89;
                // $myLoading 自定义等待动画组件,实现导出事件的异步等待交互
                vm.$nextTick(() => {
                    // dom的id。
                    let target = document.getElementById('upload');
                    let pageHeight = target.scrollWidth / A4_WIDTH * A4_HEIGHT;
                    // 获取分割dom,此处为class类名为item的dom
                    let lableListID = document.getElementsByClassName('item');
                    // 进行分割操作,当dom内容已超出a4的高度,则将该dom前插入一个空dom,把他挤下去,分割
                    for (let i = 0; i < lableListID.length; i++) {
                        let multiple = Math.ceil((lableListID[i].offsetTop + lableListID[i].offsetHeight) / pageHeight);
                        if (this.isSplit(lableListID, i, multiple * pageHeight)) {
                            let divParent = lableListID[i].parentNode; // 获取该div的父节点
                            let newNode = document.createElement('div');
                            newNode.className = 'emptyDiv';
                            newNode.style.background = '#01195e';
                            let _H = multiple * pageHeight - (lableListID[i].offsetTop + lableListID[i].offsetHeight);
                            newNode.style.height = _H + 30 + 'px';
                            newNode.style.width = '100%';
                            let next = lableListID[i].nextSibling; // 获取div的下一个兄弟节点
                            // 判断兄弟节点是否存在
                            console.log(next);
                            if (next) {
                                // 存在则将新节点插入到div的下一个兄弟节点之前,即div之后
                                divParent.insertBefore(newNode, next);
                            } else {
                                // 不存在则直接添加到最后,appendChild默认添加到divParent的最后
                                divParent.appendChild(newNode);
                            }
                        }
                    }
                    this.pdf();
                });
            },
            // 判断是否需要添加空白div
            isSplit (nodes, index, pageHeight) {
                // 计算当前这块dom是否跨越了a4大小,以此分割
                if (nodes[index].offsetTop + nodes[index].offsetHeight < pageHeight && nodes[index + 1] && nodes[index + 1].offsetTop + nodes[index + 1].offsetHeight > pageHeight) {
                    return true;
                }
                return false;
            },
            pdf() {
                // 避免出现浏览器滚动条导致的内容不全处理
                document.body.scrollTop = 0;
                //div内部滚动导致内容不全处理
                document.getElementById("app").style.height = 'auto';
                setTimeout(()=>{
                    html2canvas(document.getElementById("upload"), {
                        background: '#01195e',
                        allowTaint : true,
                        // height: document.getElementById('upload').scrollHeight,
                        // windowHeight: document.getElementById('upload').scrollHeight
                    }).then(canvas => {
                        var contentWidth = canvas.width;
                        var contentHeight = canvas.height;

                        //一页pdf显示html页面生成的canvas高度;
                        var pageHeight = contentWidth / 592.28 * 841.89;
                        //未生成pdf的html页面高度
                        var leftHeight = contentHeight;
                        //页面偏移
                        var position = 0;
                        //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
                        var imgWidth = 595.28;
                        var imgHeight = 592.28 / contentWidth * contentHeight;

                        var pageData = canvas.toDataURL('image/jpeg', 1.0);

                        var pdf = new jsPDF('', 'pt', 'a4');

                        //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
                        //当内容未超过pdf一页显示的范围,无需分页
                        if (leftHeight < pageHeight) {
                            pdf.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight);
                        } else {
                            while (leftHeight > 0) {
                                pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
                                leftHeight -= pageHeight;
                                position -= 841.89;
                                //避免添加空白页
                                if (leftHeight > 0) {
                                    pdf.addPage();
                                }
                            }
                        }
                        pdf.save("content.pdf");
                        document.getElementById("app").style.height = '100%';
                        document.getElementsByClassName("emptyDiv")[0].parentNode.removeChild(document.getElementsByClassName("emptyDiv")[0]);
                    })
                
                },300)
                
            },

 

posted @ 2022-03-09 09:57  杰_森  阅读(9030)  评论(3编辑  收藏  举报