页面截图导出为PDF,以及PDF强行截断分页问题的处理

页面截图导出为PDF,以及PDF强行截断分页问题的处理

需求

将页面内容截图导出为PDF文件,如果有高度过高的表格或图片,尽量不截断而是放在下一页展示。

思路

1.将需要导出的dom,都用一个特殊的类名标注起来,然后用html2Canvas将这些dom一一截图。
(这里并非将整个页面截图,而是多个dom截图再拼接,是为了判断是否截断问题。)
2.之后将得到的图片用JsPDF从上到下依次添加到一个pdf文件中即可。
3.关于截断分页的问题,需要对每一张图片和当前页面剩余高度进行比较,可以分为一下几种情况。
(1)图片高度小于当前页面剩余高度=>正常添加该图片到pdf
(2)图片高度大于当前页剩余高度,而且图片高度小于一个空白页的高度=>翻页,将图片放在最新的一页
(3)图片高度大于空白页高度=>这种情况即便是翻页也无法避免截断,所以正常添加该图片到pdf即可

实现

import html2Canvas from 'html2canvas';
import JsPDF from '../../public/js/jspdf.debug';
/**
 * [获取页面导出的pdf文件]
 * @param   {[Object]}  options  [导出pdf配置项,包括一个title属性设置文件名,以及query属性设置获取元素的条件]
 */
function getPdf(options) {
    var title = options.title || '标题';// 导出文件名,默认为“标题”
    const children = document.getElementsByClassName(options.className || 'pdf-cell');
    let canvas = [];
    let i = 0;
    function toCanvas() {
        if (children.length > 1) {
            html2Canvas(children[i], {
                dpi: 500, // 导出pdf清晰度
                background: '#fff', // 背景设为白色(默认为黑色)
            }).then(res => { // 计算每个dom的高度,方便后面计算分页
                res.imgWidth = 595.28;
                res.imgHeight = 592.28 / res.width * res.height;
                canvas.push(res);
                i++;
                if (canvas.length === children.length) {
                    paging();
                    toPdf();
                } else {
                    toCanvas();
                }
            });
        }
    }
    /**
     * [根据dom的高度初步进行分页,会将canvas组装为一个二维数组]
     */
    function paging() {
        const imgArr = [[]];
        let pageH = 0;// 页面的高度
        let allH = 0;// 当前组所有dom的高度和
        let j = 0;
        for (let k = 0; k < canvas.length; k++) { // 涉及到k--的操作,使用for循环方便
            pageH += canvas[k].imgHeight;
            if (pageH > 841.89 && canvas[k].imgHeight < 841.89) { // 当某个页面装不下下一个dom时,则分页
                imgArr[j][0].allH = allH - canvas[k].imgHeight;
                allH = pageH = 0;
                k--;
                j++;
                imgArr.push([]);
            } else {
                if (canvas[k].imgHeight > 841.89) { // 特殊情况:某个dom高度大于了页面高度,特殊处理
                    canvas[k].topH = 841.89 - (pageH - canvas[k].imgHeight);// 该dom顶部距离页面上方的距离
                    pageH = (2 * canvas[k].imgHeight - pageH) % 841.89;
                    canvas[k].pageH = pageH;// 该dom底部距离页面上方的距离
                }
                imgArr[j].push(canvas[k]);
                allH += canvas[k].imgHeight;
            }
            if (k === canvas.length - 1) imgArr[j][0].allH = allH;
        }
        canvas = imgArr;
    }
    /**
     * [生成PDF文件]
     */
    function toPdf() {
        const PDF = new JsPDF('', 'pt', 'a4');
        canvas.forEach((page, index) => {
            let allH = page[0].allH;
            let position = 0;// pdf页面偏移
            if (index !== 0 && allH <= 841.89) PDF.addPage();
            page.forEach(img => {
                if (img.imgHeight < 841.89) { // 当某个dom高度小于页面宽度,直接添加图片
                    PDF.addImage(img.toDataURL('image/jpeg', 1.0), 'JPEG', 0, position, img.imgWidth, img.imgHeight);
                    position += img.imgHeight;
                    allH -= img.imgHeight;
                } else { // 当某个dom高度大于页面宽度,则需另行处理
                    while (allH > 0) {
                        PDF.addImage(img.toDataURL('image/jpeg', 1.0), 'JPEG', 0, position, img.imgWidth, img.imgHeight);
                        allH -= img.topH || 841.89;
                        position -= img.topH || 841.89;
                        img.topH = 0;
                        if (allH > 0) PDF.addPage();
                    }
                    position = img.pageH;
                }
            });
        });
        PDF.save(title + '.pdf');
    }
    toCanvas();
}
export default getPdf;

  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
以下是使用Vue2导出PDF分页截断的步骤: 1. 首先,安装所需的模块。在命令行中运行以下命令: ```shell npm install html2canvas jspdf --save ``` 2. 在Vue组件中,引入所需的模块: ```javascript import html2canvas from 'html2canvas'; import jsPDF from 'jspdf'; ``` 3. 创建一个方法来导出PDF。在该方法中,首先使用html2canvas将页面HTML内容转换为图片,然后使用jsPDF将图片添加到PDF中。确保在转换为图片时,将页面分成多个部分以避免分页截断。 ```javascript export default { methods: { exportPDF() { const pdf = new jsPDF('p', 'mm', 'a4'); const pages = document.querySelectorAll('.page'); // 将页面分成多个部分 let y = 0; pages.forEach((page, index) => { html2canvas(page).then(canvas => { const imgData = canvas.toDataURL('image/png'); const imgWidth = pdf.internal.pageSize.getWidth(); const imgHeight = (canvas.height * imgWidth) / canvas.width; if (index !== 0) { pdf.addPage(); } pdf.addImage(imgData, 'PNG', 0, y, imgWidth, imgHeight); y += imgHeight; if (index === pages.length - 1) { pdf.save('export.pdf'); } }); }); } } } ``` 4. 在Vue模板中,添加一个按钮来触发导出PDF的方法: ```html <template> <div> <!-- 页面内容 --> <div class="page">Page 1</div> <div class="page">Page 2</div> <div class="page">Page 3</div> <!-- 导出按钮 --> <button @click="exportPDF">导出PDF</button> </div> </template> ``` 这样,当用户点击导出按钮时,将会生成一个包含所有页面内容的PDF文件,并且页面内容不会被截断
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值