html2pdf.js produces a blank document on iOS
I'm using html2pdf.js library to produce a dynamically generated report.
It works well on desktop but when I try to output the PDF on iOS the document is blank except for the headers and footers that I added separately.
Below is the code.
`var opt = { margin: [15, 6, 12, 6], filename: '${options.FileName}', image: { type: 'jpeg', quality: 0.98 }, html2canvas: { scale: 2 }, jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' }, pagebreak: { mode: ['avoid-all', ['p','li','h1','h3'], 'legacy'] } };
var parentPDF = function(){ var textElem = document.getElementById('printFooter'); textElem.style.display = "none";
var worker = html2pdf().set(opt).from(document.body).toContainer().toCanvas().toImg().toPdf().then(function () {
var pdfObject = worker.prop.pdf;
var number_of_pages = pdfObject.internal.getNumberOfPages();
var pdf_pages = pdfObject.internal.pages;
var myFooter = "";
for (var i = 1; i < pdf_pages.length; i += 1) {
pdfObject.setPage(i);
pdfObject.setFontSize(8);
myFooter = "Page " + i.toString() + "/" + (pdf_pages.length-1);
pdfObject.text(myFooter, 180, 289);
var textElem = document.getElementById('printFooter');
if(textElem){
var text = textElem.textContent;//TODO: get text from HTML
pdfObject.setFontSize(7);
pdfObject.text(text, pdfObject.internal.pageSize.getWidth() - 190, 289);
}
}
pdfObject.output('blob');
window.parent.PDF_CALLBACK(pdfObject.output('blob'));
});
};`
@chamaliperera512 Did you able to solve it, I'm also facing the same issue?
@chamaliperera512 @rajeshn95 hey, I faced the same problem, maybe you found any kind of solution?
@syrykh-anastasiia - No solution, I changed the pdf library to server side
@syrykh-anastasiia what is your pagebreak mode? if you are using avoid-all in pagebreak: { mode: ['avoid-all'] }, remove avoid-all and check.
@rajeshn95 - I had same problem and your solution worked for me, but only partially - if you generate a big document, it will still put an empty document. You have other twicks?
@rajeshn95 - I had same problem and your solution worked for me, but only partially - if you generate a big document, it will still put an empty document. You have other twicks?
@CrazyOvi Empty document as in? where its putting empty document?
Hi @rajeshn95. If I have more then 7 pages on iPhone, it creates the PDF with only header and footer, nothing in the page. If it has less, it creates it correctly. My code is bellow:
// optiunile definite pentru salvarea documentului var opt = { margin: [20, 10, 10, 5], // top, left, bottom, right filename: fileName, image: { type: "jpeg", quality: 0.98, }, html2canvas: { scale: 2, windowWidth: 1024, // dpi: 192, letterRendering: true, }, jsPDF: { unit: "mm", format: "a4", orientation: "landscape", }, pagebreak: { // mode: "avoid-all", // mode: ["avoid-all", "css", "legacy"], // before: ".pageInPDF", // after: ".stepInPDF", }, };
// salvarea documentului in sine var docPDF = html2pdf() .from(pdfBody) .set(opt) .toPdf() .output() .get("pdf") .then((pdf) => { var totalPages = pdf.internal.getNumberOfPages(); for (var i = 1; i <= totalPages; i++) { pdf.setPage(i); pdf.setFontSize(20); pdf.setTextColor(0);
// facem HEADAER - LOGO
pdf.addImage(require("../assets/logo.png"), "PNG", 20, 3.5, 20, 10);
// facem HEADER - TEXT
pdf.text(45, 10.5, "TASK ANALYSIS");
// facem FOOTER
pdf.setFontSize(10);
pdf.text(10, 205, "PAGE " + i + "/" + totalPages);
}
});
await docPDF
.outputPdf()
.then((pdf) => {
this.sendPDF(btoa(pdf), fileName); // function that sends the info (base64 of PDF and filename) to backend
})
.save();
I understand that the problem comes from Safari canvas limitations and creating and adding one page at a time would be the solution - could you help me?
+1
Do you have a solution for this? I have the same problem
Do you have a solution for this? I have the same problem
I will put below the way I did it. Still, I had to ask the user not to create a PDF with more then 10 pages and to pray he/she won't :)
// options for generated pdf
var opt = {
margin: [20, 5, 12.5, 5], // top, left, bottom, right - adauga cate 5 la fiecare daca e nevoie
filename: fileName,
image: {
type: "jpeg", // jpg, jpeg, bmp, png
quality: 1.0,
},
html2canvas: {
scale: 1.5,
dpi: 192,
letterRendering: true,
windowWidth: "280mm",
windowHeight: "260mm",
allowTaint: true,
},
jsPDF: {
unit: "mm",
// format: "a4",
format: [260, 280],
orientation: "landscape", // landscape sau portrait
compress: true,
},
pagebreak: {
mode: "css",
// mode: ["avoid-all", "css", "legacy"],
before: ".break-before",
after: ".break-after",
avoid: ".break-avoid",
},
};
// generating the PDF
var docPDF = html2pdf()
.from(pdfBody)
.set(opt)
.outputPdf()
.get("pdf")
.then((pdf) => {
var totalPages = pdf.internal.getNumberOfPages();
for (var i = 1; i <= totalPages; i++) {
pdf.setPage(i);
pdf.setFontSize(20);
pdf.setTextColor(0);
// add HEADAER - LOGO
pdf.addImage(require("../assets/logo.png"), "PNG", 20, 3.5, 20, 10);
// add HEADER - TEXT
pdf.text(45, 10.5, "HEADER TEXT");
// add FOOTER
pdf.setFontSize(10);
pdf.text(
pdf.internal.pageSize.getWidth() * 0.88,
pdf.internal.pageSize.getHeight() - 3.5,
"PAGE " + i + "/" + totalPages
);
}
});
// save PDF
await docPDF.outputPdf().then((pdf) => {
// send PDF info to function (my function sends the info to may backend api
this.sendPDF(btoa(pdf), fileName);
// console.log(fileName, pdf);
}).save(); // save/download the pdf
I hope this will help you. P.S: play with the options to fit your needs.
after many ways to solve this problem this config fix it on IOS
const opt = {
filename: 'filename',
image: {
type: "jpeg",
quality: 1.0,
},
html2canvas: {
scale: 1.5,
dpi: 192,
letterRendering: true,
allowTaint: true,
},
jsPDF: {
unit: "mm",
format: [260, 280],
orientation: "landscape",
compress: true,
},
}
For me the fix for iOS was simply to add compress: true. My guess is that iOS can't handle a large render.
For me the fix for iOS was simply to add
compress: true. My guess is that iOS can't handle a large render.
You put this in "options" (opt) ?
For me the fix for iOS was simply to add
compress: true. My guess is that iOS can't handle a large render.You put this in "options" (opt) ?
jsPDF - as seen in @Ahmed-Essam-WasilaDev's response https://github.com/eKoopmans/html2pdf.js/issues/397#issuecomment-1123306899
Somehow when the generated pdf is over 1 MB on iphone, it generates a pdf with blank pages
Somehow when the generated pdf is over 1 MB on iphone, it generates a pdf with blank pages
I can confirm that the pages are blank from a certain size. I have an 800kb 6-pager that renders as blank, if i remove the last two pages it works again.
Hello all. My project is in vue3 and cordova. In ios when i generate the pdf i see the pdf but i cannot do anything. i cannot go back, i cannot save it. i have to close the application and restart it. any solution?
Somehow when the generated pdf is over 1 MB on iphone, it generates a pdf with blank pages
I can confirm that the pages are blank from a certain size. I have an 800kb 6-pager that renders as blank, if i remove the last two pages it works again.
Here i could avoid this error in iOS spliting the pages of the pdf to generate one by one and merge them at the final of the process.
``
const elements = [ ]; // grab your HTML elements and paste here, i use the "id", for example. Doing this, you will create
// pdf's of these elements and merge them
let worker = html2pdf()
.set(pdfOptions)
.from(elements[0]);
if (elements.length > 1) {
worker = worker.toPdf();
elements.slice(1).forEach(async element => {
worker = worker
.get('pdf')
.then(pdf => {
pdf.addPage();
})
.from(element)
.toContainer()
.toCanvas()
.toPdf();
});
}
return worker;
``
Shnrqpdr Thank you! It works!
Hi everyone, PDF content blank after download in IOS
var content = document.querySelector('#RCH-pdf'); var opt = { margin: [-10, 0, 5, 0], filename: 'Summary Report.pdf', jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' }, pagebreak: { before: ['.audit-block', '.new-items-list', '.block-ops:nth-child(3)', '.block-fs:nth-child(3)', '.block-fs:nth-child(8)', '.block-ops:nth-child(8)', '.block-fs:nth-child(13)', '.block-ops:nth-child(13)', '.block-fs:nth-child(18)', '.block-ops:nth-child(18)', '.block-fs:nth-child(23)', '.block-ops:nth-child(23)', '.block-fs:nth-child(28)', '.block-ops:nth-child(28)', '.block-fs:nth-child(32)', '.block-ops:nth-child(32)', '.block-fs:nth-child(37)', '.block-ops:nth-child(37)', '.block-fs:nth-child(42)', '.block-ops:nth-child(42)', '.block-fs:nth-child(47)', '.block-ops:nth-child(47)', '.block-fs:nth-child(52)', '.block-ops:nth-child(52)', '.block-fs:nth-child(57)', '.block-ops:nth-child(57)', '.block-fs:nth-child(62)', '.block-ops:nth-child(62)', '.block-fs:nth-child(67)', '.block-ops:nth-child(67)'] } }
html2pdf().from(content).set(opt).save();