Add FontAwesome Icon in jsPdf - javascript

I am using jspdf.debug.js latest version.
FontAwesome icons used in a web page are not rendering in pdf.
I added a FontAwesome user icon in the page.Refer to the image.(Left one is HTML and pdf output is on right)
Below is my code snippet.
var pdf = new jsPDF('p', 'pt', 'letter');
pdf.addFont('FontAwesome', 'FontAwesome', 'normal');
pdf.setFont('FontAwesome');
pdf.canvas.height = 72 * 11;
pdf.canvas.width = 72 * 8.5;
html2pdf(document.body, pdf, function(pdf){
var iframe = document.createElement('iframe');
iframe.setAttribute('style','position:absolute;right:0; top:0; bottom:0; height:100%; width:500px');
document.body.appendChild(iframe);
iframe.src = pdf.output('datauristring');
});

jspdf does not support special symbols. Here is the gitHub issue.
See info in this answer.

I did in this way and all works with font Awesome 5...
Following this article i uploaded the fa-solid-900-normal.ttf at https://peckconsulting.s3.amazonaws.com/fontconverter/fontconverter.html
I got the js file and import it.
In Angular i did in this way
constructor() {
var callAddFont = function () {
this.addFileToVFS('fa-solid-900-normal.ttf', jsPDFfonts.fontawesome5_fa_solid_900);
this.addFont('fa-solid-900-normal.ttf', 'fa-solid-900', 'normal');
};
jsPDF.API.events.push(['addFonts', callAddFont])
}
where jsPDFfonts.fontawesome5_fa_solid_900 is the content of the file
Then during the print process for printing an icon i did in this way
pdf.setFont('fa-solid-900', 'normal');
pdf.setFontSize(10);
pdf.text('\uf6f0', 15, 15*index);
i printed directly the unicode of the icon

Related

can't load more than one image while using jsPDF on NextJS

Im trying to create a pdf based on a html, which has 3 images. The html can be seen and there is a button that downloads the html as a pdf file, but only the first image is shown on the downloaded pdf. This is the function that downloads the file (im using jsPDF library):
const savePDF = () => {
const doc = new jsPDF('p', 'pt', 'a4');
const margin = 10;
const certificate = document.querySelector('#doc');
const scale = (doc.internal.pageSize.width - margin * 2) / certificate.offsetWidth;
doc.internal.write(0, 'Tw');
doc.html(certificate, {
x: margin,
y: margin,
html2canvas: {
scale: scale
},
callback: function(doc) {
doc.output('save', {filename: 'pdfFile.pdf'});
}
})
}
Everything else is allright, the text, the tables and the first image of the doc. But for some reason the second and third image arent shown on the downloaded pdf file. I get console message: "Error loading image". All these images are on the public folder of the project, locally. Im working on NextJS.
Btw, all images are set the same way:
<Image src='/image1.png' alt='' width={500} height={500}/>

How to set font for html2pdf in jsPDF?

I need to use a Bengali font while generating my pdf. I have converted the font using fontconverter and it works fine for adding text. I mean the following things are working, i.e., I can see my Bengali Text in the generated pdf -
var doc = new jsPDF();
doc.setFont('SolaimanLipi', 'normal');
doc.text("অতীশ", 10, 60);
doc.setFont('SolaimanLipi', 'normal'); // set font
doc.setFontSize(50);
However, doc.setFont('SolaimanLipi', 'normal') is not working if use html2pdf. For instance, following code is not working.
var pdf = new jsPDF('p', 'pt', 'letter');
pdf.setFont('SolaimanLipi', 'normal');
html2pdf(document.body, pdf, function (canvas) {
var iframe = document.createElement('iframe');
iframe.setAttribute('style', 'position:absolute;right:0; top:0; bottom:0; height:100%; width:500px;font-family:SolaimanLipi;');
document.body.appendChild(iframe);
iframe.src = pdf.output('datauristring');
}
);
What is the way of setting font for html2pdf?

Ionic 4 html2canvas

I'm trying to capture HTML to image in an Ionic 4 app.
I tried using html2canvas, however, it doesn't work and shows this output in the console:
This is my code:
var element = document.getElementById('capture');
html2canvas(element).then(canvas => {
var imgData = canvas.toDataURL("image/png");
this.socialSharing.share(null, null, imgData);
});
I'm having the same issue. I managed to "fix" it by putting my code out of the <ion-content> tag. My guess is that html2canvas doesn't render shadow DOM elements (which is the case of <ion-content>, as of Ionic 4).
For instance this outputs an empty canvas:
<ion-content>
<div id="capture">
<h1>Test</h1>
</div>
</ion-content>
But the following works:
<div id="capture">
<h1>Test</h1>
</div>
This is not really a solution, but it's good enough for my use...
I was trying this component too but it does not work. The solution I found was to use the dom-to-image library. I attached an example of what I did. You just have to put the file extension you want to convert.
https://www.npmjs.com/package/jspdf
https://www.npmjs.com/package/dom-to-image
import * as jsPDF from 'jspdf';
import domtoimage from 'dom-to-image';
exportPdf(){
const div = document.getElementById('pdf');
const options = { background: 'white', height: 845, width: 595 };
domtoimage.toPng(div, options).then((dataUrl) => {
//Initialize JSPDF
const doc = new jsPDF('p', 'mm', 'a4');
//Add image Url to PDF
doc.addImage(dataUrl, 'PNG', 0, 0, 210, 340);
doc.save('pdfDocument.pdf');
}
}
The latest html2canvas supports shadow dom, like https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js

trying to modify the js function so that it gives the same output as it was when called the other js function

I am exporting the content on the webpage to the PDF file, for this i have used jsPDF API and i could able to get it work but now i want to use html2PDF as it resolves few issues which were faced when using jsPDF API.
I have written the function $scope.exportUsingJSPDF which is called when the button Export Using JSPDF is clicked. Similarly i want to implement the function $scope.exportUsingHTML2PDF which uses html2PDF API but could not succeed. Any inputs on how to modify $scope.exportUsingHTML2PDF so that it iterates the divs and shows the div content as shown when invoked using $scope.exportUsingJSPDF by clicking Export using JSPDF API.
Complete online example: https://plnkr.co/edit/454HUFF3rmLlkXLCQkbx?p=preview
js code:
//trying to implement the below function same as $scope.exportUsingJSPDF, so
// that when user click on Export using HTML2PDF button, it exports the content to the PDF and generaes the PDF.
$scope.exportUsingHTML2PDF = function(){
var pdf = new jsPDF('l', 'pt', 'a4');
var pdfName = 'test.pdf';
pdf.canvas.height = 72 * 11;
pdf.canvas.width = 72 * 8.5;
html2pdf(document.getElementByClassName("myDivClass"), pdf, function(pdf){
pdf.save(pdfName);
});
}
$scope.exportUsingJSPDF = function() {
var pdf = new jsPDF('p','pt','a4');
var pdfName = 'test.pdf';
var options = { pagesplit: true};
var $divs = $('.myDivClass') //jQuery object of all the myDivClass divs
var numRecursionsNeeded = $divs.length -1; //the number of times we need to call addHtml (once per div)
var currentRecursion=0;
//Found a trick for using addHtml more than once per pdf. Call addHtml in the callback function of addHtml recursively.
function recursiveAddHtmlAndSave(currentRecursion, totalRecursions){
//Once we have done all the divs save the pdf
if(currentRecursion==totalRecursions){
pdf.save(pdfName);
}else{
currentRecursion++;
pdf.addPage();
//$('.myDivClass')[currentRecursion] selects one of the divs out of the jquery collection as a html element
//addHtml requires an html element. Not a string like fromHtml.
pdf.fromHTML($('.myDivClass')[currentRecursion], 15, 20, options, function(){
console.log(currentRecursion);
recursiveAddHtmlAndSave(currentRecursion, totalRecursions)
});
}
}
pdf.fromHTML($('.myDivClass')[currentRecursion], 15, 20, options, function(){
recursiveAddHtmlAndSave(currentRecursion, numRecursionsNeeded);
});
}
PS: I was trying to modify $scope.exportUsingHTML2PDF so that it gives the same output as generated when clicked on "Export using JSPDF" button which calls the function $scope.exportUsingJSPDF.
The problem lies with your function using exportUsingHTML2PDF, the error is that you need to pass in the html to the function of html2PDF. Manage the page css on the basis of your need.
EDIT: You have wrong library. Please check html2pdf.js library within the plunker
Working plunker: html2pdf
$scope.exportUsingHTML2PDF = function() {
var element = document.getElementById('element-to-print');
html2pdf(element, {
margin: 1,
filename: 'myfile.pdf',
image: {
type: 'jpeg',
quality: 0.98
},
html2canvas: {
dpi: 192,
letterRendering: true
},
jsPDF: {
unit: 'in',
format: 'letter',
orientation: 'portrait'
}
});
}
With JSPDF and HTML2PDF, you have to get used to two fundamentally different coding styles:
JSPDF: imperative (javascript statements)
HTML2PDF: declarative (directives embedded in HTML)
So for page breaks:
JSPDF: pdf.addPage();
HTML2PDF: <div class="html2pdf__page-break"></div>
That should work, however HTML2PDF is buggy and gives a "Supplied data is not a JPEG" error when <div class="html2pdf__page-break"></div> is included (at least it does so for me, in Plunkr), despite being totally what the documentation tells us to do.
I haven't got time to debug it. You'll need to do some research. Someone will have posted a solution somewhere on the web.

Using jspdf to save html page as pdf, saved pdf contains incomplete page content if browser is zoomed, Why?

I am using jspdf and html2canvas combination to save html page as pdf. A pdf copy of current page is saved the moment you click a button. The problem is, if you zoom in the page, and then click the button, the saved pdf contains incomplete portion of the current page. Most of the part not visible on page due to zooming, gets cut off in the saved pdf page. What is the solution?
Below is the js code being invoked upon click of save button-
var pdf = new jsPDF('l', 'pt', 'a4');
var source = $('#someId')[0];
var options = {
background : '#eee'
};
pdf.addHTML(source, options, function(){
pdf.save('abcd.pdf');
});
EDIT
Taking idea from Saurabh's approach, I tried quite a similar thing, but without writing code for any extra div element. Before saving to pdf I made the screen size of a fixed width, and after printing I brought back the width back to default normal. It is working fine for, if it fails, we can always fix the height of the screen too, so that it appears fine in generated pdf despite zooming. Below is the code used by me:-
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';
});
Here is how I managed to get the full page pdf while the page is zoomed in using jsPDF's new .html() method. First, I force the page zoom level back to 100% before converting it to pdf. It's important to reset the scale in html2canvas option after that, otherwise it'll returns a blank page.
<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>
Update: A better way is to adjust the html2canvas.scale according to the scale factor.
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'));
}
});
}
I was going through the same problem,
To do this what I did is I made a copy of printing div and while clicking print button I attached div copy to my dom with margin-top:500px
After I got its image then I hide this copy of the div, and set margin-top:0px
I hope this will work for you.

Categories

Resources