jsPDF
jsPDF copied to clipboard
Convert html to pdf: utf-8 works only with text, but not html (unicode/cyrillic not working)
I'm opening this issue again.
I need to convert html to pdf with jsPDF. It contains UTF-8 symbols (cyrillic). I used fontconverter to generate js-file for my custom font as written here: https://github.com/MrRio/jsPDF
So now example with text works like a charm (from https://github.com/MrRio/jsPDF/blob/master/examples/js/russian.js)
var pdf = new jsPDF('p', 'pt', 'letter');
doc.setFont('PTSans');
doc.setFontSize(10);
doc.text("А ну чики брики и в дамки!", 10, 10);
And example with html ignores my custom font and exports incorrect symbols.
var pdf = new jsPDF('p', 'pt', 'letter');
doc.setFont('PTSans');
doc.setFontSize(10);
pdf.html( "<html>А ну чики брики и в дамки!</html>", { callback: 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');
}
});
What I need to do to export html to pdf with unicode symbols?
Please try setting the font name also in the html markup. E.g.
<html style="font-family: PTSans;">А ну чики брики и в дамки!</html>
not working `createCert() {
this.doc.addFileToVFS("MyFont.ttf", myFont);
this.doc.addFont("MyFont.ttf", "MyFont", "normal");
this.doc.setFont("MyFont");
const html = "<html style=\"font-family: 'MyFont';\">А ну чики брики и в дамки!</html>"
this.doc.html(html, {
callback: (doc) => {
doc.save("a4.pdf");
},
x: 10,
y: 10
});
}`
Then I guess it's a bug...
@HackbrettXXX the same with Polish signs :( Is there any chance for a quick fix of this problem?
I'm tring to create pdf in this way:
window.jsPDF = window.jspdf.jsPDF
var doc = new jsPDF('p', 'px', 'a4');
var elementToPrint = document.getElementById('printPDFtest');
doc.html(elementToPrint, {
html2canvas: {
scale: 0.45
},
callback: function (doc) {
doc.save();
}
});
@HackbrettXXX the same with Polish signs :( Is there any chance for a quick fix of this problem?
I'm tring to create pdf in this way:
window.jsPDF = window.jspdf.jsPDF var doc = new jsPDF('p', 'px', 'a4'); var elementToPrint = document.getElementById('printPDFtest'); doc.html(elementToPrint, { html2canvas: { scale: 0.45 }, callback: function (doc) { doc.save(); } });
It works?
@potapovnikita as I mentioned - there is a problem. I just showed part of my code in case I made a mistake somewhere :)
@potapovnikita
I'm opening this issue again.
I need to convert html to pdf with jsPDF. It contains UTF-8 symbols (cyrillic). I used fontconverter to generate js-file for my custom font as written here: https://github.com/MrRio/jsPDF
So now example with text works like a charm (from https://github.com/MrRio/jsPDF/blob/master/examples/js/russian.js)
var pdf = new jsPDF('p', 'pt', 'letter'); doc.setFont('PTSans'); doc.setFontSize(10); doc.text("А ну чики брики и в дамки!", 10, 10);
And example with html ignores my custom font and exports incorrect symbols.
var pdf = new jsPDF('p', 'pt', 'letter'); doc.setFont('PTSans'); doc.setFontSize(10); pdf.html( "<html>А ну чики брики и в дамки!</html>", { callback: 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'); } });
What I need to do to export html to pdf with unicode symbols?
I would like to mention two things here.
-
setting font as doc.setFont('PTSans') won't work for the HTML. for accessing fonts in the HTML you have to pass it as an inline style with font-family.
-
I have observed that the .html API of jsPdf does not support directly, takes the main element of the body, and renders it. ( Correct me if I'm wrong but I have observed it many times.)
so, after spending almost my entire day on it, I have figure out the below solution which helps me to get those bullets on my pdf.
after adding custom fonts just like explained below article you have to import your font files into your component and just style your HTML like this. https://www.devlinpeck.com/tutorials/jspdf-custom-font#:~:text=Adding%20Custom%20Fonts%20to%20jsPDF,of%20your%20desired%20font%20file.&text=Once%20you%20have%20your%20.,to%20this%20jsPDF%20Font%20Converter.
`import '../../../Lato-Regular-normal';
const htmlToConvert =
doc.html(htmlToConvert,{ callback:function{ doc.save() } })`
Hope that it will help some one.
Then I guess it's a bug...
So, I guess it's not a bug but a lack of clarity for the use case.
In my case, using the version 2.1, setting the font style on the html element like so: <html style="font-family: PTSans;">А ну чики брики и в дамки!</html>
and importing the fonts according to https://www.devlinpeck.com/tutorials/jspdf-custom-font#:~:text=Adding%20Custom%20Fonts%20to%20jsPDF,of%20your%20desired%20font%20file.&text=Once%20you%20have%20your%20.,to%20this%20jsPDF%20Font%20Converter. worked for me when using an html element reference instead of using a raw html string.
@potapovnikita which jsPDF version do you use? If it's not the current one please update.
@Rui-Jesus If this only works if the markup is passed as element, this might be an encoding issue of the file that contains the html markup?
In my case, using the version 2.1, setting the font style on the html element like so:
<html style="font-family: PTSans;">А ну чики брики и в дамки!</html>
and importing the fonts according to https://www.devlinpeck.com/tutorials/jspdf-custom-font#:~:text=Adding%20Custom%20Fonts%20to%20jsPDF,of%20your%20desired%20font%20file.&text=Once%20you%20have%20your%20.,to%20this%20jsPDF%20Font%20Converter. worked for me when using an html element reference instead of using a raw html string.
It works, and it works wonderfully, thank you <3
@HackbrettXXX I did not test passing a file with the html markup, I had it stored in memory, the html markup. To be honest I didn't look too much into the issue since the solution I provided works perfectly for me.
In my case, using the version 2.1, setting the font style on the html element like so:
<html style="font-family: PTSans;">А ну чики брики и в дамки!</html>
and importing the fonts according to https://www.devlinpeck.com/tutorials/jspdf-custom-font#:~:text=Adding%20Custom%20Fonts%20to%20jsPDF,of%20your%20desired%20font%20file.&text=Once%20you%20have%20your%20.,to%20this%20jsPDF%20Font%20Converter. worked for me when using an html element reference instead of using a raw html string.
Thank you. He inspired me.
I use html
method, but the tag on the page does not show the Chinese I want, but after reading your reply, I added font family to the tag on the page, and it can be used.
This is the end result:
This is code:
const htmlStr: HTMLElement = document.querySelector('.main') || document.body;
doc.html(htmlStr, {
callback(isPdf) {
// add the font to jsPDF
doc.addFileToVFS('fzjt.ttf', MyFont); // addfont
doc.addFont('fzjt.ttf', 'MyFont', 'normal');
doc.setFont('MyFont');
isPdf.text('又是中文', 10, 10);
isPdf.save();
},
});
.main
background #ffffff
width 90%
font-family 'MyFont'
It's amazing 🎉
I have a same problem. utf-8 characters not working with html method.
window.jsPDF = window.jspdf.jsPDF; $("#downPDF").on("click", function() { var doc = new jsPDF({ orientation: "landscape" }); var source = document.getElementById("pdfCard"); doc.setFont("Roboto-Regular"); doc.html(source, { callback: function(doc) { doc.save(); }, x: 2, y: 2, html2canvas: { scale: 0.25, }, }); })
if I try only generate:
doc.text("ľščťžžýáíúô", 10, 10); doc.save();
it's working
I am building a web app with three cultures "en", "tr", "ar"
. I followed the process as mentioned by @Rui-Jesus, but it didn't work!
In my case, using the version 2.1, setting the font style on the html element like so:
<html style="font-family: PTSans;">А ну чики брики и в дамки!</html>
and importing the fonts according to https://www.devlinpeck.com/tutorials/jspdf-custom-font#:~:text=Adding%20Custom%20Fonts%20to%20jsPDF,of%20your%20desired%20font%20file.&text=Once%20you%20have%20your%20.,to%20this%20jsPDF%20Font%20Converter. worked for me when using an html element reference instead of using a raw html string.
Then I did few modifications to make it work with specific font (the same process didn't work with all fonts)
- Download font from google fonts, in my case I used Cairo (Regular 400) because it supports all my cultures.
- Put the font link inside
<header>
:
<!-- GoogleFonts: Cairo -->
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Cairo&display=swap" rel="stylesheet">
- Use CSS rules in CSS file:
body {
font-family: 'Cairo', sans-serif !important;
}
-
Convert the font as mentioned in the tutorial. But I changed the module format to
UMD
. - The downloaded file uses the font name as
Cairo-Regular
, and that was the problem. I changed it toCairo
since the CSS font name isCairo
.
// this.addFont('Cairo-Regular-normal.ttf', 'Cairo-Regular', 'normal');
this.addFont('Cairo-Regular-normal.ttf', 'Cairo', 'normal');
- Adding the style to
html
didn't work, but it worked when added style to thebody
tag:
<body style="font-family: 'Cairo', sans-serif !important;">
- Below is the rest of the code:
<!-- jsPDF -->
<script src="~/lib/jspdf/dist/jspdf.umd.min.js"></script>
<script src="~/js/html2canvas.min.js"></script>
<script src="~/lib/dompurify/dist/purify.min.js"></script>
<script src="~/js/Cairo-Regular-normal.js"></script>
<script>
$(function () {
setTimeout(function () {
window.jsPDF = window.jspdf.jsPDF;
// Default export is a4 paper, portrait, using millimeters for units
const doc = new jsPDF('p', 'pt', 'a4');
doc.html(document.body, {
html2canvas: {
scale: 0.5,
scrollY:0
},
x: 0,
y: 0,
callback: function (doc) {
window.open(doc.output('bloburl'));
}
});
}, 1000);
});
</script>
Now I have a working solution with English and Turkish :
But it is not fully supporting Arabic. Some letters are missing, and if I have multiple languages the latin letters are rendred over each other as seen in the below image:
The correct html page looks like below:
I also tried with adding doc.addLanguage("ar")
but it didn't help.
my solution to this problem:
- create custom font ( use this : https://www.devlinpeck.com/tutorials/jspdf-custom-font#:~:text=Adding%20Custom%20Fonts%20to%20jsPDF,of%20your%20desired%20font%20file.&text=Once%20you%20have%20your%20.,to%20this%20jsPDF%20Font%20Converter )
- add font to project :
- import this font:
- add font to pdf doc.:
I have the same problem. I'm surprised there is no good solution. How this library got so many likes? Everything is so hard to solve in there.
so it is my code but not supporting fornAwesome and cyrylic.
import './RobotoBlackNormal';
...
var doc = new jsPDF('p', 'pt', 'a4');
// doc.addFont("test/reference/PTSans.ttf", "PTSans", "normal");
doc.addFont('https://use.fontawesome.com/releases/v5.3.1/webfonts/fa-regular-400.ttf', 'FontAwesome', 'normal');
doc.addFont('Roboto-Regular.ttf', 'Roboto-Regular', 'normal');
doc.addFont('Roboto-Black.ttf', 'Roboto-Black', 'normal');
doc.addFont('Roboto-Bold.ttf', 'Roboto-Bold', 'normal');
doc.addFont('Roboto-Medium.ttf', 'Roboto-Medium', 'normal');
doc.setFont('Font Awesome 5 Free');
doc.setFont('Roboto-Regular');
doc.setFont('Roboto-Black');
doc.setFont('Roboto-Bold');
doc.setFont('Roboto-Medium');
doc.html(ref.current.querySelector('#response-list'), {
callback: function (doc) {
doc.save();
}});
just cyrylic text correct displaying but by document element not supported
var doc = new jsPDF('p', 'pt', 'a4');
// doc.addFont("test/reference/PTSans.ttf", "PTSans", "normal");
doc.addFont('https://use.fontawesome.com/releases/v5.3.1/webfonts/fa-regular-400.ttf', 'FontAwesome', 'normal');
// doc.addFont('Roboto-Regular.ttf', 'Roboto-Regular', 'normal');
// doc.addFont('Roboto-Black.ttf', 'Roboto-Black', 'normal');
// doc.addFont('Roboto-Bold.ttf', 'Roboto-Bold', 'normal');
// doc.addFont('Roboto-Medium.ttf', 'Roboto-Medium', 'normal');
doc.setFont('Font Awesome 5 Free');
doc.setFont('Roboto-Regular');
// doc.setFont('Roboto-Black');
// doc.setFont('Roboto-Bold');
// doc.setFont('Roboto-Medium');
doc.text("А ну чики брики и в дамки!", 10, 10);
// doc.html('<html style="font-family: Roboto;">' + ref.current.querySelector('#response-list').innerHTML + '</html>>',
// {
// callback: function (doc) {
// doc.save();
// }});
doc.save('ho-ho-ho.pdf');
also I can't set HTML as just string to doc.html():
console.log('doc', ref.current.querySelector('#response-list'))
var doc = new jsPDF('p', 'pt', 'a4');
// doc.addFont("test/reference/PTSans.ttf", "PTSans", "normal");
doc.addFont('https://use.fontawesome.com/releases/v5.3.1/webfonts/fa-regular-400.ttf', 'FontAwesome', 'normal');
// doc.addFont('Roboto-Regular.ttf', 'Roboto-Regular', 'normal');
// doc.addFont('Roboto-Black.ttf', 'Roboto-Black', 'normal');
// doc.addFont('Roboto-Bold.ttf', 'Roboto-Bold', 'normal');
// doc.addFont('Roboto-Medium.ttf', 'Roboto-Medium', 'normal');
doc.setFont('Font Awesome 5 Free');
// doc.setFont('Roboto-Black');
// doc.setFont('Roboto-Bold');
// doc.setFont('Roboto-Medium');
// doc.text("А ну чики брики и в дамки!", 10, 10);
// doc.html(ref.current.querySelector('#response-list'),
doc.html("<html style='font-family: Roboto;'>А ну чики брики и в дамки!</html>",
{
callback: function (doc) {
doc.setFont('Roboto-Regular');
doc.setFont('Roboto-Bold');
doc.save();
}});
any progress on this issue?
Well, dear friends, perhaps I have found the Main Evil. To display .html with a specific font as of October 05, 2021, it is enough to specify the font as a style for the html element, and it will be applied to all the text inside it. It is important to use the correct fonts, which have the layout of your alphabet, Cyrillic, Polish, etc. This is my experience of 2 days searching for an answer to my problem. Hope this helps someone not to waste time. Alternatively, write the same set of fonts that is used on your site using the .addFont
& .setFont
method. That is, the text in your html has exactly the same font set as you specify with the .addFont
& .setFont
methods. Otherwise, the font will be displayed incorrectly. All the best, be attentive and quick
@NeonDB not working for me. I'm using Roboto font on page. And this initialization is not working:
var doc = new jsPDF({ orientation: "landscape" }); var source = document.getElementById("pdfCard"); doc.addFont("src/Roboto-Regular.ttf", "Roboto-Regular", "normal"); doc.setFont("Roboto-Regular"); doc.html(source, { callback: function (doc) { doc.save(); }, x: 2, y: 2, html2canvas: { scale: 0.25, }, });
@NeonDB не работает на меня. Я использую шрифт Roboto на странице. И эта инициализация не работает:
var doc = new jsPDF({ orientation: "landscape" }); var source = document.getElementById("pdfCard"); doc.addFont("src/Roboto-Regular.ttf", "Roboto-Regular", "normal"); doc.setFont("Roboto-Regular"); doc.html(source, { callback: function (doc) { doc.save(); }, x: 2, y: 2, html2canvas: { scale: 0.25, }, });
This cannot work, since the html markup source is passed as the first property to the .html method. You are not explicitly specifying which part of the html code you are going to use, be it body, div.container_kek, etc. Fix that and this piece of code should work correctly. I also recommend getting rid of "var" by replacing it with "let", it's prettier :) If you are using the same font on the page, you may not need to use the .addFont & .setFont methods. Importantly, different styles, such as Bold, Italic are also a type of font, and they also need to be specified. I forgot an important point, this is adding a font to the jsPDF API, for this use this link, https://rawgit.com/MrRio/jsPDF/master/fontconverter/fontconverter.html load your font in the .ttf format into it and paste the resulting code into yours.
@NeonDB what do you mean by "not explicitly specifying"
there is a variable "source" which is specifying "div" in html code. Here is part of it:
<div class="modal-body" id="pdfCard" style="font-family: Roboto, sans-serif !important;"> <!-- first row --> <div class="row"> <div class="col-lg-12 d-flex align-items-center justify-content-center"> <span class="h4" style="font-family: Roboto, sans-serif !important;">ľščťžýáéúäô</span> </div> </div>
this is what i see on webpage:
and this is how i see it on generated PDF:
jsPDF can't generate characters: ľ č ť
i have converted Robot font and attach to code `
`
https://github.com/parallax/jsPDF/issues/2968#issuecomment-796507870
my solution to this problem:
- create custom font ( use this : https://www.devlinpeck.com/tutorials/jspdf-custom-font#:~:text=Adding%20Custom%20Fonts%20to%20jsPDF,of%20your%20desired%20font%20file.&text=Once%20you%20have%20your%20.,to%20this%20jsPDF%20Font%20Converter )
- add font to project :
![]()
- import this font:
![]()
- add font to pdf doc.:
![]()
thank you so much this solution works wry well!
My solution is:
- Convert file font .ttf to base64 string.
- Add font to doc:
const doc = new jsPDF({
orientation: "portrait",
format: "a4",
unit: "px",
hotfixes: ["px_scaling"],
});
doc.addFileToVFS("Roboto.ttf", RobotoStringBase64);
doc.addFont("Roboto.ttf", "Roboto", "normal");
doc.setFont("Roboto");
- Render HTML string PDF:
await doc.html(
`<html>
<body >
<div style="width: 210mm;">${element.innerHTML}</div>
</body>
</html>`,
{
callback(doc) {
window.open(URL.createObjectURL(doc.output("blob")));
},
margin: [30, 15, 30, 15],
},
)
In my case, using the version 2.1, setting the font style on the html element like so:
<html style="font-family: PTSans;">А ну чики брики и в дамки!</html>
and importing the fonts according to https://www.devlinpeck.com/tutorials/jspdf-custom-font#:~:text=Adding%20Custom%20Fonts%20to%20jsPDF,of%20your%20desired%20font%20file.&text=Once%20you%20have%20your%20.,to%20this%20jsPDF%20Font%20Converter. worked for me when using an html element reference instead of using a raw html string.
Thanks it work for me!
It works for me, if use div tag instead html
<div style="font-family: PTSans;">А ну чики брики и в дамки!</div>
I've tried this and it worked, except the text rendered was a bit overlapped.