Image gets cut off when using jspdf.html() method, any solution? - javascript

I'm using jspdf to generate pdf from dom locally, code like:
var jsPDF = window.jspdf.jsPDF;
var pdf = new jsPDF('p', 'pt', 'a4', true);
pdf.html(document.body, {
autoPaging: true,
margin: [12, 8, 15, 8],
callback: function (pdf) {
pdf.save("1.pdf");
}
});
It works but the images gets cut off to different page.(My dom includes lots ofimg tag)
And if I print pdf from html directly I can use something like -webkit-column-break-inside: avoid;page-break-inside: avoid;break-inside: avoid; to avoid images getting cut off, but it didn't work in jspdf.html, any solution here?

Related

The "jspdf" library, when inserting the same image, loads it into the browser again each time. How to fix it?

Using the jspdf library, I am creating a pdf file. It has headers. Site logo in headers. I noticed that for each sheet of the pdf file, the library reloads the logo (logo requests are visible in the Network tab). This slows down the formation of the pdf file. And in general, not very good, the picture is the same, why upload it several times.
Is it possible to make the image load not for each sheet of the pdf file, but once for the entire pdf file?
Here is the code to insert the image:
let doc = new jsPDF('p', 'pt');
...
let pageCount = doc.internal.getNumberOfPages();
...
let logoImg = new Image();
logoImg.src = logoImgPath;
...
for (let i = 1; i <= pageCount; i++) {
// This line inserts an image into a pdf sheet. In the Network tab in the browser, I noticed that the picture is loaded for each sheet. Is there any way to make that the image is loaded only once - for the entire pdf file?
doc.addImage(logoImg, 'png', 10, 10, 100, 80);
}

JSPDF: Weird PDF Format

I am using jsPDF to convert html into PDF file.
This is what it looks like from the browser:
This is the PDF file:
Here is my code:
const doc = new jsPDF();
doc.html(document.getElementById('print-content')!, {
callback: function (doc) {
doc.save(activeSales?.ID + '.pdf');
},
});
How to make it responsive when generating the pdf?
I want to generate it in A4 width.
i know this is too late, but I faced the same issue before.
You can use another library called jsPDF-AutoTable which will make it easier for you to work with tables.
Here's the doc : https://github.com/simonbengtsson/jsPDF-AutoTable

addImage error (Cannot read property 'addImage' of undefined) in jsPDF

I am developing an elearning course with the possibility of downloading certificate after successful completion of the course. I am using jsPDF and everything works OK, I am able to copy the variable from the course to pdf, I am able to save the pdf, but I ran into problem when I try to add a background image.
I am not an expert in JavaScript, so I am following the documentation properly. I am able to load the scripts into html, the javascript code works perfectly except the addimage function, it always gives the "Cannot read property 'addImage' of undefined" and crashes the script.
This is the javascript I am using:
var player = parent.GetPlayer();
var doc = new jsPDF('p', 'mm', 'a4');
var certif = player.GetVar("cert");
if (certif == 1) {
parent.backgroundimage ();
}
var namename = player.GetVar("input1");
doc.setFontSize(18);
doc.setTextColor(0,0,0);
doc.setFontStyle("bold");
doc.text(17, 55, namename);
doc.save('Certificate.pdf');
Here is separate javascript (image.js) for the backgroundimage function which I saved separately because Articulate Storyline does not directly support Base64.
function backgroundimage() {
var imgData = 'data:image/jpeg;base64,... string with over 120.000 characters'
doc.addImage(imgData, 'JPEG', 0, 0, 210, 223)
}
And here are the scripts I am including in the head of the html:
<script src="https://unpkg.com/jspdf#latest/dist/jspdf.min.js" type="text/javascript"></script>
<script src="https://unpkg.com/jspdf#1.5.3/dist/jspdf.debug.js" type="text/javascript"></script>
<script src="image.js" type="text/javascript"></script>
Everything seems to work OK, I can create, save the pdf, position the text, I can call the function "backgroundimage" (tested it with console.log) I only get an error when I include the doc.addimage. I have tested with the addimage.js included in jspdf but without result. I used downloaded javascripts, and I have tried with jspdf.js only, probably all the possibilities I could think of, but no result.

how to add page break using jspdf and html2canvas

I know this has been asked before but I can't seem to find the answer, how to add page break, my page cut if convert to pdf ..??
html2canvas(document.getElementById("content")).then(function (canvas) {
var img = canvas.toDataURL("image/png");
var doc = new jsPDF({
orientation: "landscape",
format: "a4",
});
doc.addImage(img, "JPEG", 1, 5);
doc.save("testCanvas.pdf");
});
For PDF conversion, use this library instead, it supports break pages :
https://github.com/eKoopmans/html2pdf

Is it possible to use custom Google web fonts with jsPDF

I'm using jsPDF (https://parall.ax/products/jspdf, https://github.com/MrRio/jsPDF) to produce dynamic PDFs in a web application.
It works well, but I'd like to figure out whether it's possible to use Google web fonts in the resulting PDF.
I've found a variety of links that are related to this question (including other questions on SO), but most are out of date, and nothing looks definitive, so I'm hoping someone clarify whether/how this would work.
Here's what I've tried so far, with no success:
First, load the font, and cache it as a base64-encoded string:
var arimoBase64;
var request = new XMLHttpRequest()
request.open('GET', './fonts/Arimo-Regular.ttf');
request.responseType = 'blob';
request.onload = function() {
var reader = new FileReader();
reader.onloadend = function() {
arimoBase64 = this.result.split(',')[1];
}
reader.readAsDataURL(this.response);
};
request.send()
Next, create the pdf doc:
doc = new jsPDF({
orientation: "landscape",
unit: "pt",
format: "letter"
});
doc.addFileToVFS("Arimo-Regular.ttf", arimoBase64);
doc.addFont("Arimo-Regular.ttf", "Arimo Regular", "normal");
doc.setFont("Arimo Regular", "normal");
doc.text("Hello, World!", 100, 100);
doc.save("customFontTest");
When the PDF is saved - if I view it in my browser - I can see the custom font. However - if I view it using Adobe Reader or the Mac Preview app - the fonts are not visible.
I assume that's because the font is rendered in the browser using the browser's font cache, but the font is not actually embedded in the PDF, which is why it's not visible using Adobe Reader.
So - is there a way to accomplish what I'm trying to do?
OK - I finally figured it out, and have gotten it to work. In case this is useful for anyone else - here is the solution I'm using...
First - you need two libraries:
jsPDF: https://github.com/MrRio/jsPDF
jsPDF-CustomFonts-support: https://github.com/sphilee/jsPDF-CustomFonts-support
Next - the second library requires that you provide it with at least one custom font in a file named default_vfs.js.
That file should look like this:
(function (jsPDFAPI) {
"use strict";
jsPDFAPI.addFileToVFS("[Your font's name]","[Base64-encoded string of your font]");
})(jsPDF.API);
I'm using two custom fonts - Arimo-Regular.ttf and Arimo-Bold.ttf - both from Google Fonts. So, my default_vfs.js file looks like this:
(function (jsPDFAPI) {
"use strict";
jsPDFAPI.addFileToVFS("Arimo-Regular.ttf","[Base64-encoded string of your font]");
jsPDFAPI.addFileToVFS("Arimo-Bold.ttf","[Base64-encoded string of your font]");
})(jsPDF.API);
There's a bunch of ways to get the Base64-encoded string for your font, but I used this: https://www.giftofspeed.com/base64-encoder/.
It lets you upload a font .ttf file, and it'll give you the Base64 string that you can paste into default_vfs.js.
You can see what the actual file looks like, with my fonts, here: https://cdn.rawgit.com/stuehler/jsPDF-CustomFonts-support/master/dist/default_vfs.js
So, once your fonts are stored in that file, your HTML should look like this:
<script src="js/jspdf.min.js"></script>
<script src="js/jspdf.customfonts.min.js"></script>
<script src="js/default_vfs.js"></script>
Finally, your JavaScript code looks something like this:
const doc = new jsPDF({
unit: 'pt'
});
doc.addFont("Arimo-Regular.ttf", "Arimo", "normal");
doc.addFont("Arimo-Bold.ttf", "Arimo", "bold");
doc.setFont("Arimo");
doc.setFontType("normal");
doc.setFontSize(28);
doc.text("Hello, World!", 100, 100);
doc.setFontType("bold");
doc.text("Hello, BOLD World!", 100, 150);
doc.save("customFonts.pdf");
This is probably obvious to most, but in that addFont() method, the three parameters are:
The font's name you used in the addFileToVFS() function in the default_vfs.js file
The font's name you use in the setFont() function in your JavaScript
The font's style you use in the setFontType() function in your JavaScript
You can see this working here: https://codepen.io/stuehler/pen/pZMdKo
Hope this works as well for you as it did for me.
I recently ran into this same issue, but it looks like the jsPDF-CustomFonts-support repo was rolled into MrRio's jsPDF repository, so you no longer need it to get this working.
I happen to be using it in a React App and did the following:
npm install jspdf
Create a new file fonts/index.js (Note: You can download the Google Font as a .ttf and turn it into the Base64 encoded string using the tool in mattstuehler's answer)
export const PlexFont = "[BASE64 Encoded String here]";
Import that file where you need it:
import jsPDF from 'jspdf';
import { PlexFont } from '../fonts';
// Other Reacty things...
exportPDF = () => {
const doc = new jsPDF();
doc.addFileToVFS('IBMPlexSans-Bold.ttf', PlexBold);
doc.addFont('IBMPlexSans-Bold.ttf', 'PlexBold', 'normal')
doc.setFont('PlexBold');
doc.text("Some Text with Google Fonts", 0, 0);
// Save PDF...
}
// ...
Just wanted to add an updated answer - for version 1.5.3:
Convert the font file to base64 = https://www.giftofspeed.com/base64-encoder/
const yanone = "AAWW...DSES"; // base64 string
doc.addFileToVFS('YanoneKaffeesatz-Medium.ttf', yanone);
doc.addFont('YanoneKaffeesatz-Medium.ttf', 'YanoneKaffeesatz', 'normal');
doc.setFont('YanoneKaffeesatz');

Categories