import { PDFDocument, PDFPage } from "pdf-lib"; import { drawTable, DrawTableError, DrawTableOptions, CellContent } from "./index"; interface TableData { rows: CellContent[][]; options?: DrawTableOptions; } interface DrawTableWithOverflowOptions { allowCreateNewPageOnOverflow?: boolean; startYOnNewPage?: number; getNextPage?: (currentPage: PDFPage, pdfDoc: PDFDocument) => PDFPage; maxPages?: number; } export async function drawTableWithOverflow( pdfDoc: PDFDocument, page: PDFPage, tableData: TableData, startX: number, startY: number, overflowOptions: DrawTableWithOverflowOptions = {} ) { let currentPage = page; let currentY = startY; const maxPages = overflowOptions.maxPages || 5; let pageNumber = 1; const allowNewPage = overflowOptions.allowCreateNewPageOnOverflow !== false; let headers: CellContent[] = []; let isFirstPage = true; if (tableData.options?.header?.hasHeaderRow && tableData.rows.length > 0) { headers = tableData.rows.shift() as CellContent[]; } const drawRows = async (rows: CellContent[][]) => { if (pageNumber > maxPages) { console.log("Maximum page limit reached."); return; } try { await drawTable( pdfDoc, currentPage, isFirstPage && headers.length > 0 ? [headers, ...rows] : rows, startX, currentY, tableData.options || {} ); } catch (error) { if (error instanceof DrawTableError && error.code === "ERR_TABLE_HEIGHT_OVERFLOW") { if (!allowNewPage || pageNumber >= maxPages) { console.log("Page limit reached or new pages not allowed."); return; } pageNumber++; currentPage = getNextPageForOverflow(pdfDoc, currentPage, overflowOptions); currentY = overflowOptions.startYOnNewPage ?? 0; isFirstPage = false; // Adjust the rows for the next page, reattempt drawing const remainingRows = calculateRemainingRows(rows, error, startY); await drawRows(remainingRows); } else { console.error("Unhandled error in drawRows:", error); throw error; } } }; await drawRows(tableData.rows); } function calculateRemainingRows( rows: CellContent[][], error: DrawTableError, startY: number ): CellContent[][] { if (!error.dimensions || !error.rowHeights) { console.error("Error dimensions or row heights are missing."); return []; } const availableSpace = error.dimensions.height! - Math.abs(startY+50); let cumulativeHeight = 0; let rowIndex = 0; for (let height of error.rowHeights) { cumulativeHeight += height; if (cumulativeHeight > availableSpace ) { break; } rowIndex++; } return rows.slice(rowIndex); } function getNextPageForOverflow( pdfDoc: PDFDocument, currentPage: PDFPage, overflowOptions: DrawTableWithOverflowOptions ): PDFPage { return overflowOptions.getNextPage ? overflowOptions.getNextPage(currentPage, pdfDoc) : pdfDoc.addPage(); }