I want do combine different orientation pdfs as one for printing stuff.
So I wonder if I could use jspdf to do it. Thanks.
Here is part of my code for generate one pdf:
let pageHeight = contentWidth / a4WidthPt * a4HeightPt;
let leftHeight = contentHeight;
let imgWidth = isLandscape ? 841.89 : 595.28;
let imgHeight = a4WidthPt / contentWidth * contentHeight;
var position = 0;
let pdf = new jsPDF(isLandscape ? 'l' : '', 'pt', 'a4');
if (leftHeight < pageHeight) {
pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight);
} else {
while (leftHeight > 0) {
pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight);
leftHeight -= pageHeight;
position -= a4HeightPt;
if (leftHeight > 0) {
pdf.addPage();
}
}
}
I found a api addPage(format?: string | number[], orientation?: 'p'|'portrait'|'l'|'landscape'): jsPDF;, maybe I could put different orientation page in one pdf.
I tried this api, it works fine with the orientation argument.
addPage(format?: string | number[], orientation?: 'p'|'portrait'|'l'|'landscape'): jsPDF;
Related
I am trying to iterate through all the widgets (Charts/tables etc) that is currently being contained within a div to be generated as a png by utilizing domtoimage.toPng() however, it is only able to return me the PNG result of the first widget and not the following widgets. The following widgets will only display a empty png.
Image returned as follows
After some debugging,
I think domtoimage.toPng() is only able to return me the appropriate image of the HTML element when the HTML div element has the attributes of gs-x = 0 and gs-y = 0 which renders it as the first div in the div stack
Question
What is actually going on? Why cant all the widgets as represented by their divs that I am iterating through be converted into an actual png that I can use?
Code
async function convertToPng(doc,page,doc_width,doc_height,doc_wh_ratio) {
// window.html2canvas = html2canvas;
// Go to next page
doc.addPage();
let chartNodes = page.childNodes;
var previousImgWidth = null;
var previousImgHeight = null;
for(let i =0; i < chartNodes.length; i++){
console.log(chartNodes[i]);
console.log(chartNodes[i].firstChild.firstChild);
if(chartNodes[i].firstChild.firstChild.tagName == 'TABLE'){
if(i > 0){
doc.addPage();
}
(doc.autoTable({ html: chartNodes[i].firstChild.firstChild }));
}
else{
console.log("CONVERT TO PNG CHECK RESULT FALSE XXXX");
let options = { "cacheBust":true }
let dataUrl = await domtoimage.toPng(chartNodes[i]);
console.log('~~~~~~~~~');
console.log(dataUrl);
console.log('~~~~~~~~~');
let img = new Image();
dataUrl = await loadImage(dataUrl);
img.src = dataUrl;
console.log(doc_width);
console.log(img.width);
console.log(img.height);
// doc.addImage(dataUrl, 'PNG', 2, 2, img.width, img.height); // Set height as limiting dimension
console.log(dataUrl);
console.log("imgOnLoad event entered");
doc.addImage(dataUrl, 'PNG', previousImgWidth + 2,2, 0, (img.height * (25.4 / 96) - 4)); // Set height as limiting dimension
previousImgWidth = (img.width * (25.4 / 96) - 4);
//Has to start a new line if width no longer has space
if(previousImgWidth +(img.height * (25.4 / 96) - 4) >doc_width ){
previousImgHeight = (img.height * (25.4 / 96) - 4) +2;
}
}
}
console.log("Convert to png function has ended");
}
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 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
I'm trying to calculate the width of a sprite using the image width, but the number always comes out as 0, why is that?
function SpriteSheet(image, numFramesX, numFramesY, totalFrames) {
this.image = image;
this.numFramesX = numFramesX;
this.numFramesY = numFramesY;
this.totalFrames = totalFrames;
this.spriteWidth = this.image.width / this.numFramesX;
this.spriteHeight = this.image.height / this.numFramesY;
}
image.onload = function() {
console.log('Image has been loaded');
}
image.src = 'dance.png';
spritesheet = new SpriteSheet(image, 8, 10, 80);
spritesheet.spriteWidth and spritesheet.spriteHeight always yields 0. I cornered the problem to 'this.image.width' since it works if I put in the width of the image manually.
this.spriteWidth = 880 / this.numFramesX;
instead of
this.spriteWidth = this.image.width / this.numFramesX;
It also works if I calculate it using the object in the console:
spritesheet.image.width / spritesheet.numFramesX
yields 110
jsfiddle
How about that?
window.onload = function () {
console.log('Image has been loaded');
image.src = 'dance.png';
spritesheet = new SpriteSheet(image, 8, 10, 80);
}