【问题标题】:Using jspdf to save html page as pdf, saved pdf contains incomplete page content if browser is zoomed, Why?使用jspdf将html页面保存为pdf,如果浏览器缩放,保存的pdf包含不完整的页面内容,为什么?
【发布时间】:2017-05-26 15:41:15
【问题描述】:

我正在使用 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';
});

【问题讨论】:

    标签: javascript pdf pdf-generation jspdf html2canvas


    【解决方案1】:

    这是我在使用 jsPDF 的新 .html() 方法放大页面时设法获取整页 pdf 的方法。首先,我force the page zoom level back to 100% 在将其转换为 pdf 之前。之后一定要重置html2canvas option中的scale,否则会返回空白页。

    <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 是的,这是一个错字。它应该是相同的元素。
    • 错字:“let srcwidth”需要大写 W,否则你的“更好的方法”对我来说效果很好!
    【解决方案2】:

    我遇到了同样的问题, 为此,我制作了打印 div 的副本,并在单击打印按钮时将 div 副本附加到我的 dom 与 ma​​rgin-top:500px

    在我得到它的图像之后,我隐藏了这个 div 的副本,并设置了 ma​​rgin-top:0px

    我希望这对你有用。

    【讨论】:

    • 给出最高边距的逻辑是什么?您的页面上部是否被截断?
    • 给我一个关于上述问题的示例。我会给你解决方案。
    • 默认情况下,第二张图片的样式为 **diplay:none;margin-top:0px ** 即它将被隐藏,当您单击打印图片按钮时,它的样式将更改为 ** diplay:block;margin-top:500px ** 即在页面底部可见。一旦你得到你的画布,现在将它的样式替换回 **diplay:none;margin-top:0px ** 这将起作用
    • 我将在星期一发布一个演示该问题的示例小提琴。由于某些原因,目前无法这样做。
    • 这在 jsfiddle 站点中按预期工作,但在我的 IDE 中的实际代码中不起作用。知道有什么区别吗?无论如何,我会在一段时间后接受这个答案,因为解决方案是可以证明的,至少它提供了一些线索。
    猜你喜欢
    • 2016-04-05
    • 2016-08-29
    • 1970-01-01
    • 2015-06-18
    • 1970-01-01
    • 2018-04-30
    • 2018-07-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多