Jspdf: Convert html to pdf: utf-8 works only with text, but not html (unicode/cyrillic not working)

Created on 18 Oct 2020  Β·  17Comments  Β·  Source: MrRio/jsPDF

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?

Bug

Most helpful comment

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.

All 17 comments

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.

  1. 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.
  1. 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:
QQζˆͺε›Ύ20210120095315
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> :
    html <!-- 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:
    css 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 to Cairo since the CSS font name is Cairo.
    js // 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 the body tag:
    html <body style="font-family: 'Cairo', sans-serif !important;">
  • Below is the rest of the code:
    ````js

````

Now I have a working solution with English and Turkish :
image

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:
image

The correct html page looks like below:
image

I also tried with adding doc.addLanguage("ar") but it didn't help.

my solution to this problem:
1) 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 )
2) add font to project :
image
3) import this font:
image
4) add font to pdf doc.:
image

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yankeeBrit picture yankeeBrit  Β·  3Comments

Pinank picture Pinank  Β·  3Comments

arulmb0136 picture arulmb0136  Β·  4Comments

NoFootDancer picture NoFootDancer  Β·  3Comments

BarathArivazhagan picture BarathArivazhagan  Β·  4Comments