基于PHP、JS、MySQL的500名员工批量工资单PDF生成需求
Hey there! Since you already have the single-payroll PDF generation working, scaling this to 500 employees is straightforward—we’ll lean on backend PHP for stability (frontend JS might hit memory limits with that many files) and add a simple frontend trigger. Here’s a step-by-step implementation:
Core Approach
Instead of triggering 500 separate JS calls, we’ll create a PHP script that:
- Fetches all employee data from MySQL
- Reuses your existing PDF generation logic in a loop
- Saves all PDFs to a temporary folder (or directly packages them into a ZIP for easy download)
- Adds a frontend button to kick off the process
Step 1: Reuse Your PDF Generation Function
First, wrap your existing single-PDF code into a reusable function (I’ll assume you’re using FPDF/TCPDF—adjust to match your current library):
function generateSinglePayrollPDF($employeeData, $savePath) { // Replace this with your existing PDF generation code require('fpdf/fpdf.php'); // Or your PDF library include $pdf = new FPDF(); $pdf->AddPage(); // Header with employee name $pdf->SetFont('Arial', 'B', 16); $pdf->Cell(0, 10, "Payroll Slip: {$employeeData['name']}", 0, 1, 'C'); $pdf->Ln(5); // Add your existing salary data rendering here (basic pay, allowances, deductions, etc.) $pdf->SetFont('Arial', '', 12); $pdf->Cell(40, 8, "Basic Salary:", 0, 0); $pdf->Cell(0, 8, "₹{$employeeData['basic_salary']}", 0, 1); $pdf->Cell(40, 8, "Allowances:", 0, 0); $pdf->Cell(0, 8, "₹{$employeeData['allowances']}", 0, 1); $pdf->Cell(40, 8, "Total Deductions:", 0, 0); $pdf->Cell(0, 8, "₹{$employeeData['deductions']}", 0, 1); $pdf->Ln(5); $pdf->SetFont('Arial', 'B', 14); $pdf->Cell(0, 10, "Net Pay: ₹{$employeeData['net_pay']}", 0, 1, 'C'); // Save the PDF to the specified server path $pdf->Output('F', $savePath); }
Step 2: Create the Batch Processing PHP Script
Create a new file batch_generate_payroll.php that handles looping through all employees and generating PDFs:
<?php // Increase execution time and memory limits for large batches ini_set('max_execution_time', 300); // 5 minutes ini_set('memory_limit', '256M'); // Connect to your MySQL database (use your own credentials) $conn = mysqli_connect('localhost', 'root', '', 'payroll_db'); if (!$conn) { die("Database connection failed: " . mysqli_connect_error()); } // Fetch all employee data (adjust the query to match your table structure) $employeeQuery = "SELECT id, name, basic_salary, allowances, deductions, (basic_salary + allowances - deductions) AS net_pay FROM employees"; $result = mysqli_query($conn, $employeeQuery); // Create a temporary folder to store PDFs (ensure write permissions) $tempDir = 'temp_payroll_slips/'; if (!file_exists($tempDir)) { mkdir($tempDir, 0777, true); } // Loop through each employee and generate their PDF while ($employee = mysqli_fetch_assoc($result)) { // Use employee ID in filename to avoid overwrites for duplicate names $pdfFileName = "{$tempDir}{$employee['id']}_{$employee['name']}_payroll.pdf"; generateSinglePayrollPDF($employee, $pdfFileName); } // Package all PDFs into a ZIP file for easy download $zipFileName = 'all_employee_payrolls.zip'; $zip = new ZipArchive(); if ($zip->open($zipFileName, ZipArchive::CREATE | ZipArchive::OVERWRITE) === TRUE) { $pdfFiles = glob("{$tempDir}*.pdf"); foreach ($pdfFiles as $file) { $zip->addFile($file, basename($file)); } $zip->close(); } // Send the ZIP file to the user for download header('Content-Type: application/zip'); header('Content-Disposition: attachment; filename="' . $zipFileName . '"'); header('Content-Length: ' . filesize($zipFileName)); readfile($zipFileName); // Clean up temporary files (optional but recommended) unlink($zipFileName); array_map('unlink', glob("{$tempDir}*.pdf")); rmdir($tempDir); mysqli_close($conn); ?>
Step 3: Add a Frontend Button to Trigger Batch Generation
Add this button and JS to your existing PHP/HTML page to let users start the batch process:
<button id="batchGenerateBtn" style="padding: 10px 20px; cursor: pointer;"> Generate All 500 Payroll Slips </button> <script> const batchBtn = document.getElementById('batchGenerateBtn'); batchBtn.addEventListener('click', async () => { batchBtn.textContent = 'Generating... Please wait'; batchBtn.disabled = true; try { const response = await fetch('batch_generate_payroll.php'); if (!response.ok) throw new Error('Batch generation failed'); const blob = await response.blob(); const downloadUrl = window.URL.createObjectURL(blob); const downloadLink = document.createElement('a'); downloadLink.href = downloadUrl; downloadLink.download = 'all_employee_payrolls.zip'; document.body.appendChild(downloadLink); downloadLink.click(); window.URL.revokeObjectURL(downloadUrl); document.body.removeChild(downloadLink); alert('All payroll slips have been generated and downloaded!'); } catch (error) { console.error(error); alert('Oops, something went wrong. Check your server logs for details.'); } finally { batchBtn.textContent = 'Generate All 500 Payroll Slips'; batchBtn.disabled = false; } }); </script>
Key Notes for Success
- Server Permissions: Make sure the
temp_payroll_slips/folder has write permissions (in XAMPP, right-click the folder > Properties > Security > Allow write access). - Performance: For 500 employees, this might take a few minutes—adjust
max_execution_timeif needed. - Duplicate Names: Using employee IDs in filenames prevents overwriting PDFs for employees with the same name.
- Database Efficiency: Ensure your
employeestable has proper indexes (e.g., onid) to speed up the query.
内容的提问来源于stack exchange,提问作者Ritesh RC

