javascript jsPDF addHTML 将低质量图像导出为 PDF

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29166163/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 10:09:28  来源:igfitidea点击:

jsPDF addHTML exporting low quality image to PDF

javascriptpdfjspdf

提问by Mohammad Faizan khan

Simple question searching from last 2 days but didnt find solution i am converting html to pdf using this addHTML api of jsPDF

过去 2 天搜索的简单问题,但没有找到解决方案,我正在使用 jsPDF 的 addHTML api 将 html 转换为 pdf

$('#loadPdf').on('click', function() {
        var pdf = new jsPDF('p', 'in', 'a4');
        pdf.addHTML($('#complete')[0], function() {
            pdf.save('new.pdf');
            pdf.output('datauri');
        });
    });

this is producing blur image pdf the text is showing blurry. I searched a lot find some links (share below) but didn't get answer.

这是产生模糊图像pdf文本显示模糊。我搜索了很多找到一些链接(在下面分享)但没有得到答案。

html2canvas-generates-blurry-images

html2canvas-generates-blurry-images

addHTML image quality

添加HTML图像质量

jspdf and addHTML / blurry font

jspdf 和 addHTML / 模糊字体

is there any way available to get high quality image pdf. If i don't use addHTML api and use any other then image is not displaying in pdf. help please

有什么方法可以获得高质量的图像pdf。如果我不使用 addHTML api 并使用任何其他 API,则图像不会以 pdf 格式显示。请帮忙

回答by Weihui Guo

It looks like that many are still using pdf.addHTML()and have the same low quality issue. pdf.addHTML()is actually deprecatednow. The new vector-supporting API, pdf.html(), works much better. See their samplefor yourself. Here is the working code using jsPDF and html2canvas 1.0.0-alpha.11:

看起来很多人仍在使用pdf.addHTML()并且存在同样的低质量问题。pdf.addHTML()现在实际上已弃用。新的矢量支持 APIpdf.html()效果更好。亲自查看他们的样本。这是使用 jsPDF 和的工作代码html2canvas 1.0.0-alpha.11

<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>
<script>
    function download() {
        let pdf = new jsPDF('l', 'pt', 'a4');
        pdf.html(document.getElementById('id'), {
            callback: function () {
                //pdf.save('test.pdf');
                window.open(pdf.output('bloburl')); // to debug
            }
        });
    }
</script>

回答by Steve Seeger

Check out this solution:

看看这个解决方案:

http://plnkr.co/edit/nNSvHL8MZcT6nNKg9CG9

http://plnkr.co/edit/nNSvHL8MZcT6nNKg9CG9

From:

从:

https://github.com/MrRio/jsPDF/issues/339

https://github.com/MrRio/jsPDF/issues/339

<html>

  <head>
    <link data-require="[email protected]" data-semver="3.2.0" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" />
    <link rel="stylesheet" href="style.css" />

    <script data-require="[email protected]" data-semver="2.0.1" src="http://code.jquery.com/jquery-2.0.1.min.js"></script>
    <script src="html2canvas.min.js"></script>
    <script src="jspdf.min.js"></script>
    <script src="script.js"></script>
  </head>

  <body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <span class="navbar-brand pull-left">Some Brand</span>
        </div>
      </div>
    </nav>
    <main class="container">
      <ol class="breadcrumb">
        <li>
          <a href="#">Home</a>
        </li>
        <li>
          <a href="#">Fake Link</a>
        </li>
        <li class="active">Fake Page thing</li>
      </ol>
      <div class="jumbotron">
        <h1>Cool Export Test Page!</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce egestas elementum justo sed placerat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Proin vehicula quam a dolor ullamcorper iaculis. In et laoreet est, commodo placerat lectus. Sed ac ullamcorper diam. Curabitur id sem leo. Proin non dictum massa. Aliquam et dui ante</p>
        <p>
          <button type="button" class="btn btn-primary btn-lg" id="button1">Export 1</button>
          <button type="button" class="btn btn-default btn-lg" id="button2">Export 2</button>
        </p>
      </div>
       <h3>Another header!</h3>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce egestas elementum justo sed placerat.</p>
      <div class="panel panel-primary">
        <div class="panel-heading">Panel Heading</div>
        <table class="table table-bordered table-striped">
          <thead>
            <tr>
              <th>Apples</th>
              <th>Bananas</th>
              <th>Carrots</th>
              <th>Donuts</th>
              <th>French Fries</th>
              <th>Grapes</th>
              <th>Ham</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>100%</td>
              <td>Lorem ipsum dolor sit</td>
              <td>0.2245</td>
              <td>.25</td>
              <td>1231235</td>
              <td>asdf</td>
              <td>11/11/12</td>
            </tr>
            <tr>
              <td>100%</td>
              <td>Lorem ipsum dolor sit</td>
              <td>0.2245</td>
              <td>.25</td>
              <td>1231235</td>
              <td>asdf</td>
              <td>11/11/12</td>
            </tr>
            <tr>
              <td>100%</td>
              <td>Lorem ipsum dolor sit</td>
              <td>0.2245</td>
              <td>.25</td>
              <td>1231235</td>
              <td>asdf</td>
              <td>11/11/12</td>
            </tr>
            <tr>
              <td>100%</td>
              <td>Lorem ipsum dolor sit</td>
              <td>0.2245</td>
              <td>.25</td>
              <td>1231235</td>
              <td>asdf</td>
              <td>11/11/12</td>
            </tr>
            <tr>
              <td>100%</td>
              <td>Lorem ipsum dolor sit</td>
              <td>0.2245</td>
              <td>.25</td>
              <td>1231235</td>
              <td>asdf</td>
              <td>11/11/12</td>
            </tr>
            <tr>
              <td>100%</td>
              <td>Lorem ipsum dolor sit</td>
              <td>0.2245</td>
              <td>.25</td>
              <td>1231235</td>
              <td>asdf</td>
              <td>11/11/12</td>
            </tr>
            <tr>
              <td>100%</td>
              <td>Lorem ipsum dolor sit</td>
              <td>0.2245</td>
              <td>.25</td>
              <td>1231235</td>
              <td>asdf</td>
              <td>11/11/12</td>
            </tr>
            <tr>
              <td>100%</td>
              <td>Lorem ipsum dolor sit</td>
              <td>0.2245</td>
              <td>.25</td>
              <td>1231235</td>
              <td>asdf</td>
              <td>11/11/12</td>
            </tr>
            <tr>
              <td>100%</td>
              <td>Lorem ipsum dolor sit</td>
              <td>0.2245</td>
              <td>.25</td>
              <td>1231235</td>
              <td>asdf</td>
              <td>11/11/12</td>
            </tr>
            <tr>
              <td>100%</td>
              <td>Lorem ipsum dolor sit</td>
              <td>0.2245</td>
              <td>.25</td>
              <td>1231235</td>
              <td>asdf</td>
              <td>11/11/12</td>
            </tr>
            <tr>
              <td>100%</td>
              <td>Lorem ipsum dolor sit</td>
              <td>0.2245</td>
              <td>.25</td>
              <td>1231235</td>
              <td>asdf</td>
              <td>11/11/12</td>
            </tr>
            <tr>
              <td>100%</td>
              <td>Lorem ipsum dolor sit</td>
              <td>0.2245</td>
              <td>.25</td>
              <td>1231235</td>
              <td>asdf</td>
              <td>11/11/12</td>
            </tr>
            <tr>
              <td>100%</td>
              <td>Lorem ipsum dolor sit</td>
              <td>0.2245</td>
              <td>.25</td>
              <td>1231235</td>
              <td>asdf</td>
              <td>11/11/12</td>
            </tr>
            <tr>
              <td>100%</td>
              <td>Lorem ipsum dolor sit</td>
              <td>0.2245</td>
              <td>.25</td>
              <td>1231235</td>
              <td>asdf</td>
              <td>11/11/12</td>
            </tr>
            <tr>
              <td>100%</td>
              <td>Lorem ipsum dolor sit</td>
              <td>0.2245</td>
              <td>.25</td>
              <td>1231235</td>
              <td>asdf</td>
              <td>11/11/12</td>
            </tr>
            <tr>
              <td>100%</td>
              <td>Lorem ipsum dolor sit</td>
              <td>0.2245</td>
              <td>.25</td>
              <td>1231235</td>
              <td>asdf</td>
              <td>11/11/12</td>
            </tr>
            <tr>
              <td>100%</td>
              <td>Lorem ipsum dolor sit</td>
              <td>0.2245</td>
              <td>.25</td>
              <td>1231235</td>
              <td>asdf</td>
              <td>11/11/12</td>
            </tr>
            <tr>
              <td>100%</td>
              <td>Lorem ipsum dolor sit</td>
              <td>0.2245</td>
              <td>.25</td>
              <td>1231235</td>
              <td>asdf</td>
              <td>11/11/12</td>
            </tr>
          </tbody>
        </table>
      </div>
      <div class="well">
        <h3>Okay this is probably enough data</h3>
        <p>Finish strong with some lorem ipsum</p>
        </div>
    </main>
    <footer>
      <div class="container">This is a footer</div>
    </footer>
  </body>

</html>

回答by Terry Truong

I found an answer from this discussion: How to scale an image (in data URI format) in JavaScript (real scaling, not using styling)and implemented it this way, works for my usecase:

我从这个讨论中找到了一个答案: How to scale an image (in data URI format) in JavaScript(真正的缩放,不使用样式)并以这种方式实现它,适用于我的用例:

    var A4_width = 595; //pixels
    var A4_height = 842; //pixels
    var ratio = 2; // scale for higher image's dpi

    var oldCanvas = document.createElement('canvas');
    oldCanvas.width = A4_width;
    oldCanvas.height = A4_height;
    var oldContext = oldCanvas.getContext('2d');
    var oldImg = new Image();
    oldImg.src = oldCanvas.toDataURL();
    oldContext.drawImage(oldImg, 0, 0, A4_width, A4_height);

    var newImg = new Image();
    newImg.onload = function () {
        var newCanvas = document.createElement('canvas');
        newCanvas.width = A4_width * ratio;
        newCanvas.height = A4_height * ratio;
        var newContext = newCanvas.getContext('2d');

        // Scale and draw the source image to the canvas
        newContext.drawImage(newImg, 0, 0, A4_width * ratio, A4_height * ratio);
        newImg.src = newCanvas.toDataURL();
        var pdfDoc = new jsPDF({
            unit: 'mm'
        });
        pdfDoc.addImage(newImg, 'png', 0, 0, 210, 297); // imageData, format, x, y, w, h
        pdfDoc.save('testFile.pdf'); //save file
        newImg.onload = undefined; // kill the func
    }
    newImg.src = oldImg.src; //set source to the old image

回答by Dhanik Lal Sahni

This issue is related to scaling. In my case i have doubled the height and width at run time in angular application. This had resolve my issue. You can try also with increasing height and weight. It will resolve the issue.

此问题与缩放有关。就我而言,我在 angular 应用程序中在运行时将高度和宽度加倍。这已经解决了我的问题。您也可以尝试增加身高和体重。它将解决问题。

import * as jsPDF from 'jspdf';
import * as html2canvas from "html2canvas";
import * as $ from 'jquery';
export class Print {
    static exportTwo(elem: any,progress:any) {
        var canvasToImage = function (canvas: any) {
            var img = new Image();
            var dataURL = canvas.toDataURL('image/png', 0.92);
            img.src = dataURL;
            return img;
        };
        var canvasShiftImage = function (oldCanvas: any, shiftAmt: any) {
            shiftAmt = parseInt(shiftAmt) || 0;
            if (!shiftAmt) { return oldCanvas; }

            var newCanvas = document.createElement('canvas');
            newCanvas.height = oldCanvas.height - shiftAmt;
            newCanvas.width = oldCanvas.width;
            var ctx = newCanvas.getContext('2d');
            ctx['imageSmoothingEnabled'] = false; /* standard */
            ctx['mozImageSmoothingEnabled'] = false; // Firefox 
            ctx['oImageSmoothingEnabled'] = false; // Opera /
            ctx['webkitImageSmoothingEnabled'] = false; // Safari /
            ctx['msImageSmoothingEnabled'] = false; // IE */
            //ctx.fillStyle = "#";
            var img = canvasToImage(oldCanvas);
            ctx.drawImage(img, 0, shiftAmt, img.width, img.height, 0, 0, img.width, img.height);

            return newCanvas;
        };


        var canvasToImageSuccess = function (canvas: any) {
            var l = {
                orientation: 'p',
                unit: 'mm',
                format: 'a4',
                compress: true,
                fontSize: 40,
                lineHeight: 1,
                autoSize: false,
                printHeaders: true
            };
            var pdf = new jsPDF(l),
                pdfInternals = pdf.internal,
                pdfPageSize = pdfInternals.pageSize,
                pdfScaleFactor = pdfInternals.scaleFactor,
                pdfPageWidth = pdfPageSize.width,
                pdfPageHeight = pdfPageSize.height,
                totalPdfHeight = 0,
                htmlPageHeight = canvas.height,
                htmlScaleFactor = canvas.width / (pdfPageWidth * pdfScaleFactor),
                safetyNet = 0;
            while (totalPdfHeight < htmlPageHeight && safetyNet < 15) {
                var newCanvas = canvasShiftImage(canvas, totalPdfHeight);
                pdf.addImage(newCanvas, 'PNG', 0, 0, pdfPageWidth, pdfPageHeight, 'NONE', 'SLOW');

                totalPdfHeight += (pdfPageHeight * pdfScaleFactor * htmlScaleFactor);

                if (totalPdfHeight < (htmlPageHeight)) {
                    pdf.addPage();
                }
                safetyNet++;
            }
            var source = $('#print')[0];
            pdf.save('invoice.pdf');
        };

        var bigCanvas = $("<div>").appendTo($('#print'));  // This will be the 2x sized canvas we're going to render
        var scaledElement = $('#print').clone()
            .css({
                'margin': '2%',
                'padding': '1%',
                'transform': 'scale(2,2)',
                'transform-origin': '0 0',
            })
            .appendTo(bigCanvas);

        var oldWidth = scaledElement.width();
        var oldHeight = scaledElement.height();

        var newWidth = oldWidth * 2;
        var newHeight = oldHeight * 2;

        bigCanvas.css({
            'width': newWidth+200,
            'height': newHeight+200,
            'margin': '2%',
            'padding': '1%',
        })

        html2canvas(bigCanvas[0]).then((canvas: any) => {
            canvasToImageSuccess(canvas);
            bigCanvas.remove();
            progress.done();
        });
    }
}

回答by Shalini

This works fine

这工作正常

          var ctx = onePageCanvas.getContext('2d');
          //set the image quality
            ctx.webkitImageSmoothingEnabled = true;
            ctx.mozImageSmoothingEnabled = true;
            ctx.imageSmoothingEnabled = true;
            ctx.imageSmoothingQuality = "high";

            ctx.drawImage(srcImg,0,0); //this gives good img quality 

            var canvasDataURL = onePageCanvas.toDataURL("image/png", 1.0); //set png image with quality

            var width         = onePageCanvas.width;
            var height        = onePageCanvas.height;

           pdf.addImage(canvasDataURL, 'PNG', 10, 10, (width*.62), (height*.62),undefined,'FAST'); //addimage to jspdf