使用jspdf将HTML页面保存为PDF,如果浏览器进行缩放,则保存的PDF文件包含不完整的页面内容,为什么?

8
我正在使用jspdf和html2canvas组合将HTML页面保存为PDF。单击按钮时,会保存当前页面的PDF副本。问题在于,如果您缩放页面,然后单击按钮,则保存的PDF包含当前页面的不完整部分。由于缩放而在页面上看不到的大部分内容将在保存的PDF页面中被剪切。解决方案是什么? 以下是在单击保存按钮时调用的js代码-
var pdf = new jsPDF('l', 'pt', 'a4');
var source = $('#someId')[0];
var options = {
   background  : '#eee'
};

pdf.addHTML(source, options, function(){
pdf.save('abcd.pdf');
});

编辑

借鉴Saurabh的方法,我尝试了类似的做法,但没有编写任何额外div元素的代码。在保存为pdf之前,我将屏幕大小设置为固定宽度,在打印后将宽度恢复到默认正常状态。如果有问题,我们可以始终通过调整屏幕高度来解决,以便在生成的pdf中即使缩放也能显示良好。以下是我使用的代码:

var pdf = new jsPDF('l', 'pt', 'a4');
var source = $('#someId')[0];
var options = {
   background  : '#eee'
};
var width = source.clientWidth;
source.style.width = '1700px';
pdf.addHTML(source, options,                 
function(){
pdf.save('abcd.pdf');
source.style.width = width+'px';
});
2个回答

10
这是我使用jsPDF的新方法.html()来获取完整页面pdf且页面处于缩放状态的方法。首先,我在转换为pdf之前将页面缩放级别强制重置为100%。重要的是在此之后重置scale选项中的html2canvas选项,否则它会返回一个空白页面。
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.debug.js" 
    integrity="sha384-NaWTHo/8YCBYJ59830LTz/P4aQZK1sS0SneOgAvhsIl3zBu8r9RevNg5lHCHAuQ/"
    crossorigin="anonymous"></script>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
<!-- html2canvas 1.0.0-alpha.11 or higher version is needed -->
<script>
    function download() {
        // Bring the page zoom level back to 100%
        const scale = window.innerWidth / window.outerWidth;
        if (scale != 1) {
           document.body.style.zoom = scale;            
        }

        let pdf = new jsPDF('p', 'pt', 'a4');
        pdf.html(document.getElementById('idName'), {
            html2canvas: {
                scale: 1 // default is window.devicePixelRatio
            },
            callback: function () {
                // pdf.save('test.pdf');
                window.open(pdf.output('bloburl')); // to debug
            }
        });
    }
</script>

更新:更好的方法是根据比例因子调整html2canvas.scale。
function download() {
    let pWidth = pdf.internal.pageSize.width; // 595.28 is the width of a4
    let srcWidth = document.getElementById('idName').scrollWidth;
    let margin = 18; // narrow margin - 1.27 cm (36);
    let scale = (pWidth - margin * 2) / srcWidth;
    let pdf = new jsPDF('p', 'pt', 'a4');
    pdf.html(document.getElementById('idName'), {
        x: margin,
        y: margin,
        html2canvas: {
            scale: scale,
        },
        callback: function () {
            window.open(pdf.output('bloburl'));
        }
    });
}

在这个例子中,这两个document.getElementById()调用应该指向同一个元素,而且应该先声明let pdf在函数里吗?我一直收到“错误:元素未附加到文档”的错误消息。 - shenn
@shenn 是的,这是一个打字错误。应该是同一个元素。 - Weihui Guo
1
笔误:应该是 "let srcWidth",不过你的“更好的方法”对我很有用! - wildhart

3
我也遇到了同样的问题, 我所做的是复制打印div,然后在点击打印按钮时,将div副本附加到我的dom上,并设置 margin-top:500px 获取图像后,隐藏此div副本,并设置 margin-top:0px 希望这对你有用。

2
给顶部留出边距的逻辑是什么?你的页面上部被裁剪了吗? - shanti
1
给我一个示例fiddle,其中包含上述问题。我将在其中提供解决方案。 - Saurabh Agrawal
1
在jsfiddle网站上可以正常工作,但在我的IDE中实际代码中却无法工作。有什么区别吗?我会在一段时间后接受这个答案,因为解决方案是可证明的,而且至少提供了一些线索。 - shanti
@Vignesh,请为此发布一个单独的问题。 :) - Saurabh Agrawal
@SaurabhAgrawal 这个问题是由另一个人发布的。请参考以下链接 https://dev59.com/TKTja4cB1Zd3GeqPA2Ee - Vignesh
显示剩余15条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接