html生成pdf并导出(解决文字截断问题)

一、安装
npm install --save html2canvas
npm i jspdf --save
二、在需要使用的页面引入使用
import jsPDF from 'jspdf'
import html2canvas from 'html2canvas'
三、把html转化为图片,并导出成pdf

1.html

<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>

2.js

import jsPDF from 'jspdf'
import html2canvas from 'html2canvas'


//避免分页被截断
const exportPDF = (pdfDom, title) => {
    const A4_WIDTH = 592.28;
    const A4_HEIGHT = 841.89;
    // $myLoading 自定义等待动画组件,实现导出事件的异步等待交互
    // dom的id。
    let target = document.getElementById(pdfDom);
    let pageHeight = target.scrollWidth / A4_WIDTH * A4_HEIGHT;
    // 获取分割dom,此处为class类名为item的dom
    let lableListID = target.getElementsByClassName('item');
    // 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 (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);
            }
        }
    }
    pdf(pdfDom, title);
}

// 判断是否需要添加空白div
const 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;
}

const pdf = (pdfDom, title) => {
    // 避免出现浏览器滚动条导致的内容不全处理
    document.body.scrollTop = document.documentElement.scrollTop = 0
    //div内部滚动导致内容不全处理
    // document.getElementById('app').style.height = 'auto';
    setTimeout(() => {
        html2canvas(document.getElementById(pdfDom), {
            allowTaint: true,
            scale: 3,
            dpi: 300,
            // 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(`${title}.pdf`);
        })
    }, 300)
}

导出的时候调用相应的方法

  <Button key="exportPDF" type="primary" loading={pdfLoading} onClick={() => exportPDF('pdfDom', '文件标题')}>
        导出PDF
      </Button>   

原文地址:html2canvas+jsPdf前端生成PDF以及处理分页图片文字被截断问题 - 码农教程

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值