I am trying to export some tables to pdf in my application. The export functionality works. However, if table data has some long text in it, it overflows into the other rows when it is exported. I have word-break:break-word for that data, but it is being ignored when exporting to PDF. I also have letterRendering set to true. Here is my function:
var data = document.getElementById('table');
html2canvas(data).then(canvas => {
// Few necessary setting options
var imgWidth = 208;
var pageHeight = 295;
var imgHeight = canvas.height * imgWidth / canvas.width;
var heightLeft = imgHeight;
const contentDataURL = canvas.toDataURL('image/png')
let pdf = new jspdf('p', 'mm', 'a4');
var position = 0;
pdf.addImage(contentDataURL, 'PNG', 0, position, imgWidth, imgHeight)
pdf.save('table.pdf');
letterRendering: true;
});
Here is an image of part of the exported table that is showing the problem:
It looks fine on the webpage itself:
How should I modify my function to prevent this overflow from happening?
OK, so, I changed work-break:break-word to word-break:break-all and it is working perfectly now. Happy Coding!
Related
I am using jsPDF library for downloading a multiple page PDF which creates from an HTML div. I want the PDF in A4 size.
I am facing below issues,
Only first page seems to be in A4 size, other pages not in A4 size(wider pages).
Even the first page seems to be in A4 size; it does not fit in the container(contents from right side cuts away from the container).
And the contents which is expected be appear in second page are not in the PDF generated.
Below is the JS code.
var HTML_Width = $("#cdpage").width();
var HTML_Height = $("#cdpage").height();
var top_left_margin = 15;
var PDF_Width = HTML_Width+(top_left_margin*2);
var PDF_Height = (PDF_Width*1.5)+(top_left_margin*2);
var canvas_image_width = HTML_Width;
var canvas_image_height = HTML_Height;
var totalPDFPages = Math.ceil(HTML_Height/PDF_Height)-1;
html2canvas($("#cdpage")[0],{allowTaint:true}).then(function(canvas) {
canvas.getContext('2d');
var imgData = canvas.toDataURL("image/jpeg", 1.0);
var pdf = new jsPDF("p", "pt", "a4");
pdf.addImage(imgData, 'JPG', top_left_margin, top_left_margin,canvas_image_width,canvas_image_height);
for (var i = 1; i <= totalPDFPages; i++) {
pdf.addPage(PDF_Width, PDF_Height);
pdf.addImage(imgData, 'JPG', top_left_margin, -(PDF_Height*i)+(top_left_margin*4),canvas_image_width,canvas_image_height);
}
pdf.save("HTML-Document.pdf");
}
And i know that the code snippet var pdf = new jsPDF("p", "pt", "a4"); is for setting A4 size, but its not working.
Below is the HTML DIV from which the pdf is generated.
<div id="cdpage">
<div id="cdpage1"></div>
<div id="cdpage4"></div>
<div id="cdpage5"></div>
</div>
try to use particular size of a4
var pdf = new jsPDF('p','mm',[297, 210]);
also see this page
How to set image to fit width of the page using jsPDF?
In
pdf.addImage(pdfEle.pageData, 'JPEG', 0, posYInCurrentPage, pdfW, imgHeight)
"posYInCurrentPage" you should set it as fol:-
the first element in current page, posYInCurrentPage = 0
the second element in current page, posYInCurrentPage = first element Height
I need to export few parts of the page to few different pages in pdf. When I use method save() outside html2canvas() func it returns empty pages, If I add it one of canvas functions it will return the content of this canvas.
const pdf = new jspdf('p', 'mm', 'a4'); // A4 size page of PDF
let data = document.querySelector('.first-page');
html2canvas(data).then(canvas => {
const imgWidth = 208;
const imgHeight = canvas.height * imgWidth / canvas.width;
const contentDataURL = canvas.toDataURL('image/png');
const position = 0;
pdf.addImage(contentDataURL, 'PNG', 0, position, imgWidth, imgHeight);
});
pdf.addPage();
data = document.querySelector('.second-page');
html2canvas(data).then(canvas => {
const imgWidth = 208;
const imgHeight = canvas.height * imgWidth / canvas.width;
const contentDataURL = canvas.toDataURL('image/png');
const position = 0;
pdf.addImage(contentDataURL, 'PNG', 0, position, imgWidth, imgHeight);
});
pdf.save('dashboard.pdf'); // Generated PDF
html
<div class="adscale-table">
<div class="first-page">
<dashboard-platforms id="platforms-section"></dashboard-platforms>
</div>
<div class="d-flex flex-column second-page">
<div class="d-flex mb-4">
<dashboard-performance-by-device id="performance-by-device-section" class="col-xl-6"></dashboard-performance-by-device>
<dashboard-performance-by-location id="performance-by-location-section" class="col-xl-6"></dashboard-performance-by-location>
</div>
<div class="d-flex">
<dashboard-bar-widget *ngIf="gendersData; else loader" class="col-xl-6" id="performance-gender-section"
title="Performance by Gender" [height]="300" [currency]="customerCurrency"
[metricSettings]="metricsSettings" [allData]="gendersData">
</dashboard-bar-widget>
<dashboard-bar-widget *ngIf="agesData; else loader" class="col-xl-6" id="performance-age-section"
title="Performance by Age" [height]="300" [currency]="customerCurrency"
[metricSettings]="metricsSettings" [allData]="agesData">
</dashboard-bar-widget>
</div>
</div>
</div>
if I put save() inside "html2canvas(data).then(canvas => {...})" function, I will get two pdf files with images of specified part of the page. How can I get these two parts in one pdf ?
I think this could be the solution and also a cleaner code:
async function printDocument() {
const pdf = new jspdf('p', 'mm', 'a4'); // A4 size page of PDF
const imgWidth = 208;
const position = 0;
let page1 = document.querySelector('.first-page');
let page1 = document.querySelector('.second-page');
const [imgPage1, imgPage2] = await Promise.all([html2canvas(page1), html2canvas(page2)]);
// Process first image
let imgHeight = imgPage1.height * imgWidth / imgPage1.width;
let contentDataURL = imgPage1.toDataURL('image/png');
pdf.addImage(contentDataURL, 'PNG', 0, position, imgWidth, imgHeight);
pdf.addPage();
// Process second image
imgHeight = imgPage2.height * imgWidth / imgPage2.width;
contentDataURL = imgPage2.toDataURL('image/png');
pdf.addImage(contentDataURL, 'PNG', 0, position, imgWidth, imgHeight);
pdf.save('dashboard.pdf'); // Generated PDF
}
EDIT:
I also noticed that you're using mm units for the PDF document if that works for you it's ok but I had a recent experience adding images to a PDF document and 'px' units served for my purpose slightly better. Anyway if that works it's ok.
EDIT 2:
There is another answer explaining better what's the problem and why when you put pdf.save('dashboard.pdf') method inside html2canvas it works. Here is the link Getting image on page 1 of 2 page pdf
I want to export my HTML page into pdf using angular 6.
I have written following code to convert into pdf
let dataPdf = document.getElementById('contentToPrint');
const pdf = new jspdf('p', 'pt', 'a4');
pdf.addHTML(document.getElementById('contentToPrint'),()=>{
pdf.save('web.pdf');
});
Getting Following Error:
core.js:12301 ERROR Error: Supplied Data is not a valid base64-String jsPDF.convertStringToImageData
at Object.x.convertStringToImageData (jspdf.min.js:50)
at Object.x.addImage (jspdf.min.js:50)
at Object.<anonymous> (jspdf.min.js:188)
at Object.options.complete (html2canvas.js:2711)
at start (html2canvas.js:2215)
at Object._html2canvas.Preload (html2canvas.js:2488)
at html2canvas.js:2719
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
at Object.onInvokeTask (core.js:13842)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420)
You need to convert your image to base64.
If your images are static you can convert them here:
https://www.base64-image.de/
If images are dynamic:
Converting an image to base64 in angular 2
After image conversion to base64 string, you can pass that to jsPDf as:
pdf.addHTML('your base64 string);
I'm facing a similar problem.
It looks like you need convert your DOM element into a PNG. Once you have it, you have to convert it to base64 string and add it with pdf.addImage()
You can use html2canvas to convert DOM elements into images.
EDIT
let dataPdf = document.getElementById('contentToPrint');
const pdf = new jspdf('p', 'pt', 'a4');
html2canvas(dataPdf).then((canvas) => {
let img = canvas.toDataURL('image/png');
pdf.addImage(img, 'png', 40, 90, 515, 600); //sizings here
pdf.save('web.pdf');
}
You can do something like this
import html2canvas from 'html2canvas';
var data = document.getElementById('ELEMENT_ID');
html2canvas(data).then(canvas => {
var imgWidth = 208;
var pageHeight = 295;
var imgHeight = canvas.height * imgWidth / canvas.width;
var heightLeft = imgHeight;
const contentDataURL = canvas.toDataURL('image/png')
let pdf = new jspdf('p', 'mm', 'a4'); // A4 size page of PDF
var position = 0;
pdf.addImage(contentDataURL, 'PNG', 0, position, imgWidth, imgHeight)
//save file with specific name
pdf.save("Wallet.pdf");
});
I have multiple images of different size(height & width) that need to be converted to PDF using jspdf, but I have trouble to use addPage() function to do that.
Is it possible to export images with different page sizes to a single pdf?
I was actually able to add multiple pages with different image sizes using addPage([imgWidth, imgHeight]) except the first page, which is defined by new jsPDF('l', 'pt', 'a4').
The blank first page can be deleted using .deletePage(1). You can also add some text to the first page if you will.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.debug.js"
integrity="sha384-NaWTHo/8YCBYJ59830LTz/P4aQZK1sS0SneOgAvhsIl3zBu8r9RevNg5lHCHAuQ/"
crossorigin="anonymous"></script>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
<script>
function exportPdf(urls) {
let pdf = new jsPDF('l', 'pt', 'a4');
pdf.text(20, 20, 'Some text here');
for (let i = 0; i < urls.length; i++) {
let img = new Image();
img.src = urls[i];
img.onload = function () {
const imgWidth = this.width;
const imgHeight = this.height;
const imgRatio = imgWidth / imgHeight;
if (i >= 0) {
if (imgRatio > 0) {
pdf.addPage([imgWidth, imgHeight]);
}
else {
pdf.addPage([imgWidth, imgHeight], 'p');
}
}
pdf.setPage(i + 2);
pdf.addImage(img, 'JPEG', 0, 0, imgWidth, imgHeight, null, 'NONE');
if (i == urls.length - 1) {
pdf.save('Photos.pdf');
}
}
}
}
</script>
A better, but more complicated, way is to use fixed page format and calculate the image size and aspect ratio and then set the parameters (and rotate the image if needed) accordingly so that the image can fit the paper, i.e., a4 in this case. It can be either pdf.addImage(img, 'JPEG', adjustedX, adjustedY, adjustedWidth, adjustedHeight, null, 'NONE'); or pdf.addImage(img, 'JPEG', adjustedX, adjustedY, adjustedWidth, adjustedHeight, null, -90);
For a code sample, see my answer to this question.
I'm using jsPdf and html2pdf to convert html to a pdf file.
I can convert the html fine and download the file but if the html is too big to fit onto a single page, it does not create the other page(s), how do I do this?
code is:
var pdf = new jsPDF('l', 'pt', 'a4');
pdf.canvas.height = 72 * 11;
pdf.canvas.width = 72 * 8.5;
html2pdf(document.getElementById(id), pdf, function(pdf){
pdf.save('file.pdf');
});
Another Solution.
var pdf = new jsPDF('p', 'pt', 'a4');
var options = {
pagesplit: true
};
pdf.addHTML($(".pdf-wrapper"), options, function()
{
pdf.save("test.pdf");
});
Source : jsPDF multi page PDF with HTML renderrer
another answer : jsPDF multi page PDF with HTML renderrer
If above answer does not work i have done it like this :
download and include in order :
Jquery
html2canvas
jspdf
google them they are easy to find. then have your printable code in a div wrapper report. and call the function with print button.
for example (In jsfiddle code will not work because it does not allow external code from non cdn sites but it will work on server)
$(document).ready(function() {
var form = $('#report');
var cache_width = form.width();
var a4 = [595.28, 841.89];
$('#create_pdf').on('click', function() {
$('body').scrollTop(0);
createPDF();
});
//create pdf
function createPDF() {
getCanvas().then(function(canvas) {
var imgWidth = 200;
var pageHeight = 290;
var imgHeight = canvas.height * imgWidth / canvas.width;
var heightLeft = imgHeight;
var doc = new jsPDF('p', 'mm');
var position = 0;
var img = canvas.toDataURL("image/jpeg");
doc.addImage(img, 'JPEG', 0, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
while (heightLeft >= 0) {
position = heightLeft - imgHeight;
doc.addPage();
doc.addImage(img, 'JPEG', 0, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
}
doc.save('Report.pdf');
form.width(cache_width);
});
}
// create canvas object
function getCanvas() {
form.width((a4[0] * 1.33333) - 80).css('max-width', 'none');
return html2canvas(form, {
imageTimeout: 2000,
removeContainer: false
});
}
});
https://jsfiddle.net/vnfts73o/1