I am using html2canvas and jsPDF for PDF generation. The downloaded PDF should look like the preview of the document, but I am facing issues with the table layout. Specifically, the text in the table columns is not wrapping properly, causing the content to get cut off, and I'm unable to see the full text in those columns. I have attached an image of the table for reference. How can I resolve this issue to ensure the text wraps correctly within the columns?
check image here
Here is the code:
export const downloadComponentAsPDF = async (elementId, fileName) => {
const contentArea = document.getElementById(elementId);
if (contentArea) {
try {
const pdf = new jsPDF({
orientation: 'portrait',
unit: 'pt',
format: 'a4',
});
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = pdf.internal.pageSize.getHeight();
const margin = 20;
const elementMargin = 10;
let positionY = margin;
let currentPageHeight = pdfHeight - 2 * margin;
// Group sections into rows based on layout
const rows = [];
let currentRow = [];
let currentRowWidth = 0;
const sections = Array.from(
contentArea.querySelectorAll('.section, .non-section'),
);
sections.forEach(section => {
const sectionWidth = parseInt(
section.getAttribute('data-width') || '12',
);
if (currentRowWidth + sectionWidth > 12) {
rows.push(currentRow);
currentRow = [];
currentRowWidth = 0;
}
currentRow.push(section);
currentRowWidth += sectionWidth;
});
if (currentRow.length > 0) {
rows.push(currentRow);
}
// Process each row and its sections in order
for (const row of rows) {
let rowHeight = 0;
const rowSections = [];
// Render sections in the current row
for (const section of row) {
const sectionWidth = parseInt(
section.getAttribute('data-width') || '12',
);
const sectionCanvas = await html2canvas(section, {
scale: 4,
useCORS: true,
});
const imgData = sectionCanvas.toDataURL('image/png');
const imgWidth = sectionCanvas.width;
const imgHeight = sectionCanvas.height;
const pdfImgWidth = (sectionWidth / 12) * (pdfWidth - 2 * margin);
const pdfImgHeight = (pdfImgWidth * imgHeight) / imgWidth;
rowHeight = Math.max(rowHeight, pdfImgHeight);
rowSections.push({
imgData,
pdfImgWidth,
pdfImgHeight,
sectionWidth,
});
}
// If row height exceeds current page height, create a new page
if (positionY + rowHeight > currentPageHeight) {
pdf.addPage();
positionY = margin;
currentPageHeight = pdfHeight - 2 * margin;
}
// Render the row in the PDF
let positionX = margin;
for (const rowSection of rowSections) {
pdf.addImage(
rowSection.imgData,
'PNG',
positionX,
positionY,
rowSection.pdfImgWidth,
rowHeight,
);
positionX += rowSection.pdfImgWidth + elementMargin;
}
positionY += rowHeight + elementMargin;
currentPageHeight -= rowHeight + elementMargin;
}
pdf.save(`${fileName}.pdf`);
} catch (error) {
console.error('Error generating PDF:', error);
}
}
};
Here’s the image showing how the table columns should look in the expected result.
Check image here