Hi all,
Following Use PDF Exporter to print content of table - #13 by PatrickMast
I'm using jsPDF to print tables for FREE with out API and it's work great, attached example of the PDF document and the code
I have an issue with tables that are more than 3 pages, I don't understand where is the limitation !!!
this is the JS code:
async function generatePDF() {
console.log("Starting PDF generation process...");
const { jsPDF } = window.jspdf;
if (!jsPDF) {
console.error("jsPDF not loaded");
return;
}
const doc = new jsPDF({
orientation: "landscape",
unit: "mm",
format: "a4",
putOnlyUsedFonts: true,
floatPrecision: 16
});
const pageHeight = doc.internal.pageSize.getHeight();
const pageWidth = doc.internal.pageSize.getWidth();
const formatDate = (dateString) => {
const d = new Date(dateString);
return ${String(d.getDate()).padStart(2, '0')}.${String(d.getMonth() + 1).padStart(2, '0')}.${String(d.getFullYear()).slice(-2)} ${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}
;
};
// Logo, Header, and Title
const addPageHeader = (pageNum) => {
doc.addImage(QSA_Logo.value, 'PNG', 8, 8, 20, 9);
const currentDate = formatDate(new Date());
doc.setFontSize(8);
doc.text(currentDate, pageWidth - 15, 15, null, null, "right");
doc.setFontSize(11);
doc.text('Document List', pageWidth / 2, 18, null, null, "center");
};
const addPageFooter = (pageNum) => {
doc.setFontSize(8);
doc.text(Page ${pageNum}
, pageWidth - 10, pageHeight - 10, null, null, "right");
doc.text("Generated by QSA-Soft https://qsa-soft.online", pageWidth / 2, pageHeight - 10, null, null, "center");
};
let currentPage = 1;
// Table Content
const visibleFields = [
{ field: "doc_category", display: "Category" },
{ field: "doc_no", display: "Number" },
{ field: "doc_ver", display: "Version" },
{ field: "doc_status", display: "Status" },
{ field: "doc_title", display: "Title" },
{ field: "open_date", display: "Open Date" },
{ field: "last_update", display: "Last update" },
{ field: "update_by", display: "Update By" },
{ field: "doc_link", display: "Word Link" },
{ field: "pd_flink", display: "PDF Link" },
{ field: "doc_rem", display: "Remarks" }
];
const tableHeaders = visibleFields.map(field => field.display);
const fieldKeys = visibleFields.map(field => field.field);
const sortedData = DOC_table.data.sort((a, b) => a.doc_category - b.doc_category);
const tableData = sortedData.map(row => {
return fieldKeys.map((field) => {
if ((field === "doc_link" && row.doc_link) || (field === "pd_flink" && row.pd_flink)) {
return "link"; // Handle links later
}
if (field === "open_date" || field === "last_update") {
return formatDate(row[field]);
}
return row[field] || "";
});
});
const columnStyles = {
doc_category: { cellWidth: 10 },
doc_no: { cellWidth: 10 },
doc_ver: { cellWidth: 25 },
doc_status: { cellWidth: 25 },
doc_title: { cellWidth: 10 },
open_date: { cellWidth: 10 },
last_update: { cellWidth: 10 },
update_by: { cellWidth: 10 },
doc_link: { cellWidth: 10 },
pd_flink: { cellWidth: 10 },
doc_rem: { cellWidth: 10 }
};
const rowStyles = {
fillColor: (rowIndex) => (rowIndex % 2 === 0 ? [220, 220, 220] : [255, 255, 255])
};
// Increase page break handling for large datasets
const maxHeight = pageHeight - 40; // Adjust this to fit content more efficiently
// Wrap the table generation inside a setTimeout to allow async handling
setTimeout(() => {
doc.autoTable({
startY: 30,
head: [tableHeaders],
body: tableData,
styles: { overflow: 'linebreak', cellPadding: 2 },
headStyles: { fontSize: 9, fillColor: [0, 102, 204] },
bodyStyles: { fontSize: 8, textColor: [10, 10, 10] },
columnStyles: columnStyles,
rowStyles: {
fillColor: (rowIndex) => rowStyles.fillColor(rowIndex)
},
margin: { top: 30, bottom: 10, left: 10, right: 10 },
maxHeight: maxHeight, // Limit the height of the table content per page
didDrawCell: function(data) {
const rowIndex = data.row.index;
const columnIndex = data.column.index;
if (fieldKeys[columnIndex] === "doc_link") {
const linkUrl = sortedData[rowIndex].doc_link;
if (linkUrl) {
doc.link(data.cell.x, data.cell.y, data.cell.width, data.cell.height, { url: linkUrl });
}
}
if (fieldKeys[columnIndex] === "pd_flink") {
const linkUrl = sortedData[rowIndex].pd_flink;
if (linkUrl) {
doc.link(data.cell.x, data.cell.y, data.cell.width, data.cell.height, { url: linkUrl });
}
}
},
didDrawPage: function(data) {
addPageHeader(currentPage);
addPageFooter(currentPage);
currentPage++;
}
});
const mainImage = SignatureBackground.value;
if (mainImage) {
const imgX = 20;
const imgY = pageHeight - 40;
const imgWidth = 40;
const imgHeight = 15;
doc.addImage(mainImage, 'PNG', imgX, imgY, imgWidth, imgHeight);
const name = G_GetUser_info.data.full_name[0];
doc.setFontSize(9);
doc.setFont("times", "italic");
doc.setTextColor(50, 50, 50);
doc.text(name, imgX + 8, imgY + 8);
doc.setFontSize(9);
doc.setTextColor(69, 69, 69);
doc.text(formatDate(new Date()), imgX + 18, imgY + 14, null, null, "center");
}
doc.save('Document List.pdf');
console.log("PDF generated successfully!");
}, 500); // Delay of 100ms, adjust as needed
}
// Call the function to generate the PDF
generatePDF();