web-dev-qa-db-ja.com

jsPDF addHTML低品質の画像をPDFにエクスポートする

過去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');
        });
    });

これは、テキストがぼやけて表示されているぼかし画像pdfを生成しています。私はたくさん検索していくつかのリンクを見つけました(以下に共有)が、回答が得られませんでした。

html2canvas-generates-blurry-images

addHTML画像品質

jspdfとaddHTML /ぼやけたフォント

高品質の画像pdfを取得する方法はありますか。 addHTML APIを使用せず、他のAPIを使用すると、画像がPDFで表示されません。助けてください

14

まだ多くの人がpdf.addHTML()を使用しており、同じ低品質の問題を抱えているようです。 pdf.addHTML()は実際には 非推奨 になりました。新しいベクトルをサポートするAPIであるpdf.html()は、より適切に機能します。 sample をご覧ください。 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>
1
Weihui Guo

私はこのディスカッションから答えを見つけました: JavaScriptで画像を(データURI形式で)スケーリングする方法(実際のスケーリング、スタイリングを使用しない) をこのように実装すると、私のユースケースで機能します:

    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
0
Terry Truong

このソリューションをチェックしてください:

http://plnkr.co/edit/nNSvHL8MZcT6nNKg9CG9

から:

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>$1.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>$1.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>$1.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>$1.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>$1.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>$1.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>$1.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>$1.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>$1.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>$1.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>$1.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>$1.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>$1.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>$1.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>$1.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>$1.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>$1.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>$1.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>
0
Steve Seeger

この問題はスケーリングに関連しています。私の場合、angularアプリケーションで実行時に高さと幅を2倍にしました。これで問題が解決しました。高さと重量を増やして試すこともできます。問題は解決します。

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();
        });
    }
}
0