1

正常用法

引入jspdf.min.js

var doc = new jsPDF()
doc.text('Hello world!', 10, 10)
doc.save('a4.pdf')

api可查看官方说明 jsPDF

根据不同需求,使用中并没有想象中那么容易。

问题1:输入中文时,生成的pdf内容变成乱码

解决方法:

引入jspdf.customfonts.min.js 和 default_vfs.js

var doc = new jsPDF();

doc.addFont('NotoSansCJKjp-Regular.ttf', 'NotoSansCJKjp', 'normal');

doc.setFont('NotoSansCJKjp');
doc.text(15, 30, 'こんにちは。はじめまして。');

//multi-lines Test
var paragraph = '相次いで廃止された寝台列車に代わり、いまや夜間の移動手段として主力になりつつある夜行バス。「安い」「寝ながら移動できる」などのメリットを生かすため、運行ダイヤはどのように組まれているのでしょうか。夜遅く出て、朝早く着くというメリット夜行バスを使うメリットといえば、各種アンケートでもいちばん多い回答の「安い」以外に、';
var lines = doc.splitTextToSize(paragraph, 150);
doc.text(15, 60, lines);

doc.save('custom_fonts.pdf');

参考 jsPDF-CustomFonts-support

问题2:如何给文字添加超链接

解决方法:

pdf.textWithLink('下载', 30, 40, { url: 'https://www.google.com/' });

问题3:导出后的pdf黑黑的一片

解决方法:

由于html内容过长,图片较多较长的时候。jsPDF无法导出,可以对页面进行分步截取,然后进行拼接,还可以进行更好的分页

pdf.addPage();

问题4:分步导出后的pdf还是黑黑的一片

解决方法:

导出PDF时,先只显示第一步需要导出的内容,导出完毕后,隐藏导出的页面内容,显示下一步需要导出的页面内容。

以下为部分函数源码,可作为参考

var exporting = false;
    var progressLen = $('.cut-box').length;
    var resultBoxLength = $('.result-box').length;
    $('.export-pdf').click(function(){
        if(exporting){
            return false;
        }
        exporting = true;
        console.log('export-pdf')
        // 保存时先显示所有测试图片,隐藏按钮
        var imglen = $('img.lazy').length;
        for(var i=0;i<imglen;i++){
            console.log($('img.lazy:eq('+i+')').attr('data-original'))
            $('img.lazy:eq('+i+')').attr('src',$('img.lazy:eq('+i+')').attr('data-original'))
        }
        // return;
        $("#pdfContent").addClass('exporting');
        $('.containte_edit .export-pdf span').html('生成中...');
        $('.export-pdf').css('display','none');
        $('body').css({'height':'100%','overflow':'hidden'});
        var firstResultLen = $('.result-box:eq(0) .cut-box').length;
        // var resultBoxLength = 1;
        var resultBoxIndex = 0;        
        var progressIndex = 0;
        var pdf = new jsPDF('', 'pt', 'a4');

        html2canvas(
            $('.containte_edit'),
                {
                    dpi: 172,//导出pdf清晰度
                    height:$('.containte_edit').offset().top+$('.containte_edit').innerHeight(),
                    onrendered: function (canvas) {
                        var contentWidth = canvas.width;
                        var contentHeight = canvas.height;
                        var imgWidth = 555.28;
                        var imgHeight = 555.28 / contentWidth * contentHeight;

                        var pageData = canvas.toDataURL('image/jpeg', 1.0);
                        pdf.addFont('NotoSansCJKjp-Regular.ttf', 'NotoSansCJKjp', 'normal');
                        pdf.setFont('NotoSansCJKjp');
                        pdf.addImage(pageData, 'JPEG', 20, 20, imgWidth, imgHeight);
                        pdf.textWithLink('导导导导导导导导导', 30, 40, { url: '<?php echo $host;?>' });
                        pdf.textWithLink('导导导导', 500, 40, { url: '<?php echo base_url('testing/downLoadFile/'.$proj_num);?>' });
                        $('.export-pdf').css('display','inline-block');
                        setProgress(progressIndex);
                        newHtmlCanvas(pdf,resultBoxIndex,progressIndex);
                    },
                    //背景设为白色(默认为黑色)
                    background: "#fff",
                    useCORS:true
                })
    })
    //pdf 要输入的pdf,boxLength循环长度,h当前截取的位置
    function newHtmlCanvas(pdf,resultBoxIndex,progressIndex){
        console.log('resultBoxIndex:'+resultBoxIndex);
        console.log($('.result-box:eq('+resultBoxIndex+') .cut-box:eq(0)').offset().top)
        var cutBoxLen = $('.result-box:eq('+resultBoxIndex+') .cut-box').length;
        var cutBoxIndex = 1;
        if(resultBoxIndex!=0){
            pdf.addPage();
        }
        var firstSub = 0;
        if(resultBoxIndex==0){
            firstSub = 120;
        }
        html2canvas(
            $('.result-box:eq('+resultBoxIndex+')'),
            {
                dpi: 172,//导出pdf清晰度
                height:$('.result-box:eq('+resultBoxIndex+') .cut-box:eq(0)').offset().top+$('.result-box:eq('+resultBoxIndex+') .cut-box:eq(0)').innerHeight()-firstSub,
                onrendered: function (canvas) {
                    var contentWidth = canvas.width;
                    var contentHeight = canvas.height;

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

                    var pageData = canvas.toDataURL('image/jpeg', 1.0);
                    //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
                    //当内容未超过pdf一页显示的范围,无需分页
                    if(resultBoxIndex==0){
                        position=80;
                        // pageHeight = pageHeight -position;
                    }
                    if (leftHeight < pageHeight) {
                        pdf.addImage(pageData, 'JPEG', 20, 20, imgWidth, imgHeight);
                    } else {
                        while (leftHeight > 0) {
                            pdf.addImage(pageData, 'JPEG', 20, position, imgWidth, imgHeight)
                            leftHeight -= pageHeight;
                            position -= 841.89;
                            //避免添加空白页
                            if (leftHeight > 0) {
                                pdf.addPage();
                            }
                        }
                    }
                    if(cutBoxLen>cutBoxIndex){
                        console.log('有1个以上的子cut-box');
                        $('.result-box:eq('+resultBoxIndex+') .cut-box:eq('+(cutBoxIndex-1)+')').css('display','none');
                        $('.result-box:eq('+resultBoxIndex+') .cut-box:eq('+(cutBoxIndex)+')').css('display','inline-block');
                        pdf.addPage();
                        progressIndex++;
                        setProgress(progressIndex);
                        connectHtmlCanvas(pdf,resultBoxIndex,cutBoxLen,cutBoxIndex,progressIndex);
                    }else{
                        console.log('只有1个子cut-box');
                        if(resultBoxIndex==resultBoxLength-1){
                            console.log('当前为最后一个resultbox');
                            console.log('endPage')
                            pdf.save('content.pdf');
                            $("#pdfContent").removeClass('exporting');
                            $('.containte_edit .export-pdf span').html('生成PDF');
                            $('.result-box').show();
                            $('.result-box .cut-box').show();
                            $('body').css({'height':'auto','overflow':'auto'});
                            exporting = false;
                            setProgress(0);
                        }else{
                            console.log('addPage');
                            console.log('当前不是最后一个resultbox');
                            pdf.addPage();
                            $('.result-box:eq('+(resultBoxIndex+1)+')').show().siblings('.result-box').hide();
                            resultBoxIndex++;
                            progressIndex++;
                            setProgress(progressIndex);
                            newHtmlCanvas(pdf,resultBoxIndex,progressIndex);
                        }
                    }
                },
                //背景设为白色(默认为黑色)
                background: "#fff",
                useCORS:true
            }
        )
    }
    function connectHtmlCanvas(pdf,resultBoxIndex,cutBoxLen,cutBoxIndex,progressIndex){
        console.log('cutBoxLen:'+cutBoxLen+'cutBoxIndex:'+cutBoxIndex);
        html2canvas(
            $('.result-box:eq('+resultBoxIndex+') .cut-box:eq('+cutBoxIndex+')'),
            {
                dpi: 172,//导出pdf清晰度
                onrendered: function (canvas) {
                    var contentWidth = canvas.width;
                    var contentHeight = canvas.height;

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

                    var pageData = canvas.toDataURL('image/jpeg', 1.0);
                    //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
                    //当内容未超过pdf一页显示的范围,无需分页
                    if (leftHeight < pageHeight) {
                        pdf.addImage(pageData, 'JPEG', 20, 30, imgWidth, imgHeight);
                    } else {
                        while (leftHeight > 0) {
                            pdf.addImage(pageData, 'JPEG', 20, position, imgWidth, imgHeight)
                            leftHeight -= pageHeight;
                            position -= 841.89;
                            //避免添加空白页
                            if (leftHeight > 0) {
                                pdf.addPage();
                            }
                        }
                    }
                    if(cutBoxIndex==cutBoxLen-1){
                        console.log('当前为父div里最后一个cut-box');
                        if(resultBoxIndex==resultBoxLength-1){
                            console.log('当前为最后一个result-box');
                            pdf.save('content.pdf');
                            $("#pdfContent").removeClass('exporting');
                            $('.containte_edit .export-pdf span').html('生成PDF');
                            $('body').css({'height':'auto','overflow':'auto'});
                            $('.result-box').show();
                            $('.result-box .cut-box').show();
                            exporting = false;
                            setProgress(0);
                        }else{
                            console.log('当前不是最后一个result-box');
                            $('.result-box:eq('+(resultBoxIndex+1)+')').show().siblings('.result-box').hide();
                            resultBoxIndex++;
                            progressIndex++;
                            setProgress(progressIndex);
                            newHtmlCanvas(pdf,resultBoxIndex,progressIndex);
                        }
                    }else{
                        console.log('当前不是父div里最后一个cut-box');
                        $('.result-box:eq('+resultBoxIndex+') .cut-box:eq('+cutBoxIndex+')').css('display','none');
                        $('.result-box:eq('+resultBoxIndex+') .cut-box:eq('+(cutBoxIndex+1)+')').css('display','inline-block');
                        cutBoxIndex++;
                        pdf.addPage();
                        progressIndex++;
                        setProgress(progressIndex);
                        connectHtmlCanvas(pdf,resultBoxIndex,cutBoxLen,cutBoxIndex,progressIndex)
                    }
                },
                //背景设为白色(默认为黑色)
                background: "#fff",
                useCORS:true
            }
        )
    }
    // 设置进度条
    function setProgress(progressIndex){
        var progress = Math.round((progressIndex/progressLen)*100) +'%';
        $('.containte_edit .export-pdf i').css('width',progress);
    }


月魂祭夏
114 声望1 粉丝