html2canvas+jspdf实现html网页转pdf,并解决图片跨域及分页问题

  • 7,376 views
  • 阅读模式

项目中需要将html页面转化为pdf保存下来,于是开始尝试网页转图片再转pdf的方案(即html2canvas+jspdf),经历了一番折腾,最终终于实现了html转pdf,虽然因为一些问题最终没有选择这种方案,但还是决定先记录下来...

直接上干货--源码:

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.4/jspdf.debug.js"></script>
    <script src="~/Content/js/healthyCabin/monitorData/html2canvas.js"></script>
    <script>
        var downPdf = document.getElementById("exportToPdf");
        downPdf.onclick = function () {
            // 要导出pdf的节点
            var elements = document.getElementsByClassName("pdf_page");
            var imgMap = new Map();
            for (var index = 0; index < elements.length; index++) {
                var mapIndex = index;
                html2canvas(elements[index], {
                    allowTaint: true, // 支持跨域
                    useCORS: true, // 是否允许网页中img元素跨域,这个设置需要img元素支持及服务器支持
                    scale: 2, // 这个影响生成图片的清晰度
                    background: "#F5F5F5" //背景
                }).then((canvas) => {
                    var img = new Image();
                    img.width = canvas.width;
                    img.height = canvas.height;
                    img.src = canvas.toDataURL('image/jpeg', 1.0);
                    imgMap.set(mapIndex, img); // 按照顺序保存图片

                    if(imgMap.size == elements.length) { // 当所有图片都转化完毕,则进行保存操作
                        var pdf = new jsPDF('', 'pt', 'a4');
                        for(var i = 0; i < imgMap.size; i++) {
                            // canvas尺寸
                            var canvasWidth = imgMap.get(i).width;
                            var canvasHeight = imgMap.get(i).height;
                            var pageData = imgMap.get(i).src;
                            addOneImg(pdf, pageData, canvasWidth, canvasHeight);
                            if(i < imgMap.size-1) {
                                pdf.addPage(); // 如果还有图片未添加到pdf,则增加一个页面
                            }
                        }
                        // 所有图片添加完毕,保存
                        pdf.save("report_"+checkId+".pdf");
                    }
                });

            };
        }
        // img转化为pdf并保存
        var addOneImg = function (pdf, pageData, canvasWidth, canvasHeight) {

            // a4纸的尺寸[595.28,841.89]
            var a4Width = 595.28;
            var a4Height = 841.89;

            //html页面生成的canvas在pdf中图片的宽高
            var imgWidth = a4Width;
            var imgHeight = a4Width / canvasWidth * canvasHeight;

            //一页pdf显示html页面生成的canvas高度;
            var pageHeight = canvasWidth / a4Width * a4Height;

            addPages(pdf, pageData, 0, imgWidth, imgHeight, canvasHeight, pageHeight, a4Height);


        }

        // 递归的方式对页面进行截取并添加到pdf中
        var addPages = function (pdf, pageData, position, imgWidth, imgHeight, canvasHeight, pageHeight, a4Height) {
            pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
            // 减去已经绘制的区域
            canvasHeight -= pageHeight;
            position -= a4Height;
            // 当还有内容未生成pdf,则新加页面,并添加图片
            if (canvasHeight > 0) {
                pdf.addPage();
                addPages(pdf, pageData, position, imgWidth, imgHeight, canvasHeight, pageHeight, a4Height);
            }
        }
    </script>

需要注意的有以下几点:

  1. 这段代码是以a4纸的标准转换pdf,而且能够通过配置分页节点,达到分页可控的效果。
  2. 跨域方法:一. useCORS:true,并在后台header中添加Access-Control-Allow-Origin: *    二. 使用allowTaint: true, 然后如下图修改html2canvas.js

html2canvas+jspdf实现html网页转pdf,并解决图片跨域及分页问题

如图,修改img.crossOrigin = 'anonymous'为img.crossOrigin = '',并修改img.src = src为img.src = src + (src.contain("?") ? "&" : "?") + "h2c_t" + new Date().getTime(),或者也可以直接下载下方提供的js:

js下载(点击下面文本链接进行下载):

html2canvas.js          jspdf.js

原文博客:IT老五(html2canvas+jspdf实现html网页转pdf,并解决图片跨域及分页问题)

html2canvas+jspdf实现html网页转pdf,并解决图片跨域及分页问题
IT老五(it-lao5):关注公众号,一起源创,一起学习!

weinxin
扫码关注微信公众号--IT老五
微信扫一扫关注公众号,获取更多实用app,订阅地址不定时更新
Liu, Thinkin
  • 本文由 发表于 2019-08-21 17:51:40
  • 转载请务必保留本文链接:https://itlao5.com/1032.html
评论  1  访客  1
    • zzz
      zzz 0

      因为什么问题没有选择这种方式呢,是有更好的方法吗,能否分享一下咧

    匿名

    发表评论

    匿名网友 填写信息

    :?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

    确定