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');
});
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');
});
Share
Improve this question
edited Jun 13, 2017 at 5:44
BalaajiChander
1393 silver badges21 bronze badges
asked Jun 13, 2017 at 5:30
Neeraj BhattNeeraj Bhatt
1112 silver badges10 bronze badges
3 Answers
Reset to default 3I 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./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
jspdf does not support special symbols. Here is the gitHub issue. See info in this answer.
This does not answer the question directly, but it's a nice workaround if you use the pdf.html()
(docs) method. An added bonus with this approach is you don't have to bloat your PDF size with a ton of icons.
You can render the material icon (or any other icon) as in image instead, and it will render correctly in the PDF when generated via pdf.html()
.
Below is a simple example:
const canvas = document.createElement('canvas');
const ctx = canvas?.getContext('2d');
if (ctx) {
ctx.font = '24px "Material Icons"';
ctx.fillText('visibility', 0, 24);
}
const img = new Image();
img.src = canvas?.toDataURL();
const div = document.getElementById('target');
div?.appendChild(img);
<div id="target"></div>
The result in my html:
The result in my generated PDF:
I'm in Angular, so I created a directive that makes the process very simple.
import {
Directive,
AfterViewInit,
Renderer2,
ElementRef,
Input,
} from '@angular/core';
@Directive({
standalone: true,
selector: '[toImage]',
})
export class ToImageDirective implements AfterViewInit {
@Input() icon = '';
@Input() size = 24;
constructor(
private _el: ElementRef<HTMLElement>,
private _renderer: Renderer2
) {}
ngAfterViewInit(): void {
const canvas = this._renderer.createElement('canvas');
canvas.width = this.size;
canvas.height = this.size;
this._el.nativeElement.style.display = 'inline-block';
this._el.nativeElement.style.width = `${this.size}px`;
this._el.nativeElement.style.height = `${this.size}px`;
const ctx = canvas?.getContext('2d');
if (ctx) {
ctx.font = `${this.size}px "Material Icons"`;
ctx.fillText(this.icon, 0, this.size);
}
const img = new Image();
img.src = canvas?.toDataURL();
this._renderer.appendChild(this._el.nativeElement, img);
}
}
Remember to import in your module / standalone ponent, then use it like so:
<span [icon]="'visibility'" toImage></span>