Reputation: 105
Using html2canvas and JsPDF for converting HTML to pdf and using the below code for generating the code this code will give convert the complete HTML of the div to a single image and will show in the pdf as a single page.
import * as jsPDF from 'jspdf';
import html2canvas from 'html2canvas';
htmltoPDF()
{
// parentdiv is the html element which has to be converted to PDF
html2canvas(document.querySelector("#parentdiv")).then(canvas => {
var pdf = new jsPDF('p', 'pt', [canvas.width, canvas.height]);
var imgData = canvas.toDataURL("image/jpeg", 1.0);
pdf.addImage(imgData,0,0,canvas.width, canvas.height);
pdf.save('converteddoc.pdf');
});
}
For split the code i used below code which split the pages into the multiple pages but not spliting the space correctly because my pdf has small images attached pdf.
var imgWidth = 210;
var pageHeight = 295;
var imgHeight = canvas.height * imgWidth / canvas.width;
var heightLeft = imgHeight;
enter code here
var doc = new jsPDF('p', 'mm');
var position = 0;
doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
while (heightLeft >= 0) {
position = heightLeft - imgHeight;
doc.addPage();
doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
}
doc.save( 'file.pdf');
Is there any approach to split the page according to the static height which split the image from a particular position?
Upvotes: 4
Views: 11142
Reputation: 97
html2canvas(divToPrint, {
width: 2480,
height: 3508
}).then((canvas) => {
})
// Capture the specified HTML element as a canvas
html2canvas(divToPrint, {
width: 2480, // Set the width of the canvas
height: 3508 // Set the height of the canvas
}).then((canvas) => {
// Define dimensions for the image and PDF pages
let imgWidth = 400; // Width of the image in the PDF
let pageHeight = 480; // Height of each PDF page
let imgHeight = ((canvas.height * imgWidth) / 2454) * 1.24; // Calculate the image height to maintain aspect ratio and apply scaling
var heightLeft = imgHeight; // Initialize the remaining height to the image height
// Convert the canvas to a PNG image data URL
const imgData = canvas.toDataURL("image/png");
// Create a new jsPDF instance with specified options
const pdf = new jsPDF({
orientation: "p", // Portrait orientation
unit: "mm", // Units in millimeters
format: [400, 480], // Custom page size
});
let position = 0; // Initial position for the image on the PDF page
// Set the background color for the first page
pdf.setFillColor(248);
pdf.rect(0, 0, 400, 480, "F");
// Add a header image to the first page
pdf.addImage(Header, "JPEG", 0, 0, 400, 400);
// Add text to the first page
pdf.setFontSize(35);
pdf.text('SMRF 360', 10, 420);
pdf.setFontSize(15);
pdf.text('Feedback report', 10, 433);
pdf.text('March 2021', 10, 440);
// Add a new page and place the captured image on it
pdf.addPage();
pdf.addImage(imgData, "PNG", 0, position, imgWidth, imgHeight);
heightLeft -= pageHeight; // Decrease the remaining height by the page height
// Loop to add remaining pages if the content exceeds one page
while (heightLeft >= 0) {
position = heightLeft - imgHeight; // Calculate the position for the next image
pdf.addPage(); // Add a new page
pdf.addImage(imgData, "PNG", 0, position, imgWidth, imgHeight); // Add the image to the new page
heightLeft -= pageHeight; // Decrease the remaining height by the page height
}
// Save the generated PDF as "Result.pdf"
pdf.save("Result.pdf");
});
Upvotes: 6
Reputation: 121
First set doc instance to accept unit as 'pt'. Post this the next step would be to check if image is greater than page size, if so, image will span over multiple pages, as we have docHeight with us, we would be able to get part of the image that would be contained in current page. Now, repeat this for next page (remaining image is say larger again for next page). Code would like below (Here, I wanted image to only occupy 0.8 of page width, height is adjusted accordingly):
//Read Canvas to be exported
const appRolesElement = document.getElementById('app-roles-element');
const appRolesCanvas = await html2canvas(appRolesElement, { onclone: function (document) {
//Different style requirement for export
document.querySelectorAll('.right-wrapper').forEach(el => {
el.style.marginLeft = '0px';
})
}});
const doc = new jsPDF({
compress: true,
orientation: 'p',
unit: 'pt',
format: 'a4'
});
var docWidth = doc.internal.pageSize.getWidth();
var docHeight = doc.internal.pageSize.getHeight();
let heightInPlace = 0;
let appRolesImageDisplayHeight = getDisplayHeight(appRolesCanvas.height, appRolesCanvas.width, docWidth*0.8);
let appRolesIterationCounter = 0;
let appRolesSourceClipStartY = 0;
//Keep checking if a new page is required
while(appRolesImageDisplayHeight > 0) {
if(appRolesIterationCounter > 0) {
doc.addPage();
heightInPlace = 10;
}
++appRolesIterationCounter;
const remainingHeightInPage = docHeight - heightInPlace;
const sourceHeightToBeDisplayed = getSourceHeight(remainingHeightInPage, appRolesCanvas.width, docWidth);
const clippedImage = await convertURIToImageData(appRolesImage, appRolesCanvas.width, sourceHeightToBeDisplayed, appRolesSourceClipStartY);
doc.addImage(clippedImage, 'JPEG', 10, heightInPlace, docWidth * 0.8, remainingHeightInPage * 0.8);
heightInPlace += (remainingHeightInPage * 0.8) + 5;
appRolesImageDisplayHeight = appRolesImageDisplayHeight - remainingHeightInPage;
appRolesSourceClipStartY += sourceHeightToBeDisplayed;
}
doc.save("export.pdf");
const getDisplayHeight = (sourceHeight, sourceWidth, displayWidth) => {
return (displayWidth/sourceWidth)*sourceHeight;
};
const getSourceHeight = (displayHeight, sourceWidth, displayWidth) => {
return displayHeight*(sourceWidth/displayWidth);
}
Additionally, please use attribute data-html2canvas-ignore for ignoring contents from exports.
Upvotes: 0