過去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
高品質の画像pdfを取得する方法はありますか。 addHTML APIを使用せず、他のAPIを使用すると、画像がPDFで表示されません。助けてください
まだ多くの人が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>
私はこのディスカッションから答えを見つけました: 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
このソリューションをチェックしてください:
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>
この問題はスケーリングに関連しています。私の場合、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();
});
}
}