基于XSLT从JSON生成PDF:实现表头表尾全局显示与表格分页(每页5行)
Got it, let's tackle this table pagination requirement for your JSON-to-PDF generator. I'll walk you through a practical implementation using a common frontend stack (jsPDF + autoTable) — the core logic translates easily to backend libraries like iText or PyFPDF too.
Core Logic Overview
First, let's break down what we need to do:
- Split your JSON dataset into chunks of 5 rows each (since we want max 5 rows per page)
- For each chunk, create a new PDF page (except the first one)
- On every single page, render the fixed header, the current chunk of table rows, and the fixed footer
Step 1: Set Up Dependencies (for jsPDF + autoTable)
If you're not already using these libraries, include them first:
import jsPDF from 'jspdf'; import 'jspdf-autotable';
Step 2: Full Implementation Code
Here's a complete, working example tailored to your requirements:
// Replace this with your actual JSON data const jsonData = [ { id: 1, product: "Laptop", price: "$999", stock: 12 }, { id: 2, product: "Mouse", price: "$25", stock: 45 }, { id: 3, product: "Keyboard", price: "$50", stock: 28 }, { id: 4, product: "Monitor", price: "$299", stock: 18 }, { id: 5, product: "Headphones", price: "$149", stock: 32 }, { id: 6, product: "Webcam", price: "$79", stock: 21 }, { id: 7, product: "Charger", price: "$35", stock: 56 }, ]; // Initialize PDF document const doc = new jsPDF('p', 'mm', 'A4'); const pageWidth = doc.internal.pageSize.getWidth(); const rowLimit = 5; // Max rows per page const dataChunks = []; // Split JSON data into 5-row chunks for (let i = 0; i < jsonData.length; i += rowLimit) { dataChunks.push(jsonData.slice(i, i + rowLimit)); } // Helper: Render fixed header on every page const renderHeader = () => { doc.setFontSize(16); doc.text("Product Inventory Report", pageWidth / 2, 10, { align: 'center' }); doc.setFontSize(12); // Add a horizontal line to separate header from table doc.line(10, 15, pageWidth - 10, 15); }; // Helper: Render fixed footer with page numbers const renderFooter = (currentPage, totalPages) => { doc.setFontSize(10); doc.text(`Page ${currentPage} of ${totalPages}`, pageWidth / 2, doc.internal.pageSize.getHeight() - 10, { align: 'center' }); doc.text("Generated on: " + new Date().toLocaleDateString(), 10, doc.internal.pageSize.getHeight() - 10); }; // Render each page with header, table chunk, and footer dataChunks.forEach((chunk, index) => { // Add new page if we're beyond the first chunk if (index !== 0) { doc.addPage(); } // Render header first renderHeader(); // Render table with current 5-row chunk doc.autoTable({ startY: 20, // Position table below header head: [['ID', 'Product', 'Price', 'Stock']], // Table column headers body: chunk.map(row => [row.id, row.product, row.price, row.stock]), theme: 'striped', styles: { fontSize: 11 }, headStyles: { fillColor: '#2c3e50', textColor: '#fff' } }); // Render footer last renderFooter(index + 1, dataChunks.length); }); // Save the final PDF doc.save('paginated-inventory-report.pdf');
Key Details to Understand
- Data Chunking: The loop splits your JSON array into smaller groups of 5 items — this guarantees we never exceed the row limit per page.
- Persistent Header/Footer: The
renderHeader()andrenderFooter()functions are called on every page, so they appear consistently across all pages. - Positioning: The
startYparameter inautoTableensures the table starts below the header, while the footer usesdoc.internal.pageSize.getHeight()to stick to the bottom of each page. - Dynamic Page Numbers: The footer shows the current page and total page count, calculated from the number of data chunks.
For Backend Libraries (e.g., iText, PyFPDF)
The logic stays the same:
- Calculate total pages by dividing total rows by 5 (round up if there's a remainder)
- For each page, fetch the corresponding row subset (rows 1-5, 6-10, etc.)
- Render the fixed header, subset table rows, and fixed footer on each page
- Use the library's page break method to move to the next page after each chunk
This approach ensures your tables paginate cleanly while keeping headers and footers on every page, exactly as you requested!
内容的提问来源于stack exchange,提问作者Karthikeyan
相关产品推荐
相关产品推荐

