add('/export/excel/auto', function() { // Enable error reporting for debugging (disable or log to file in production) error_reporting(E_ALL); ini_set('display_errors', 1); // Should be 0 in production // For large reports, ensure sufficient execution time and memory. // These might need adjustment based on server configuration and report size. // ini_set('max_execution_time', 300); // e.g., 5 minutes // ini_set('memory_limit', '512M'); // e.g., 512 Megabytes // Check if request is POST if ($_SERVER['REQUEST_METHOD'] !== 'POST') { die("Invalid request method. Only POST is allowed."); } // Get form data if (!isset($_POST['data'])) { die("No data received in data field"); } // Decode JSON data $jsonData = json_decode($_POST['data'], true); if (json_last_error() !== JSON_ERROR_NONE) { die("Invalid JSON data: " . json_last_error_msg()); } if (!$jsonData || !isset($jsonData['headers']) || !isset($jsonData['data'])) { die("Invalid data structure. Required fields missing."); } // Create new Spreadsheet $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); // Set headers $headers = $jsonData['headers']; foreach ($headers as $colIndex => $header) { $sheet->setCellValueByColumnAndRow($colIndex + 1, 1, $header); } // Style headers $headerStyle = [ 'font' => [ 'bold' => true, 'color' => ['rgb' => 'FFFFFF'], ], 'fill' => [ 'fillType' => Fill::FILL_SOLID, 'startColor' => ['rgb' => '4CAF50'], ], 'alignment' => [ 'horizontal' => Alignment::HORIZONTAL_CENTER, 'vertical' => Alignment::VERTICAL_CENTER, ], 'borders' => [ 'allBorders' => [ 'borderStyle' => Border::BORDER_THIN, ], ], ]; $sheet->getStyle('A1:' . $sheet->getHighestColumn() . '1')->applyFromArray($headerStyle); // Add data $rowIndex = 2; foreach ($jsonData['data'] as $row) { foreach ($headers as $colIndex => $header) { if (!isset($row[$header])) { continue; // Skip if header not found in row data } $cellValue = $row[$header]['value']; $cellType = $row[$header]['type']; // Set cell value based on type switch ($cellType) { case 'currency': $sheet->setCellValueByColumnAndRow($colIndex + 1, $rowIndex, $cellValue); $sheet->getStyleByColumnAndRow($colIndex + 1, $rowIndex) ->getNumberFormat() ->setFormatCode('"Rp"#,##0.00'); break; case 'date': // Convert ISO date to dd-mm-yyyy format if (is_string($cellValue) && strtotime($cellValue)) { $date = new DateTime($cellValue); $cellValue = $date->format('d-m-Y'); } $sheet->setCellValueByColumnAndRow($colIndex + 1, $rowIndex, $cellValue); $sheet->getStyleByColumnAndRow($colIndex + 1, $rowIndex) ->getNumberFormat() ->setFormatCode('dd-mm-yyyy'); break; case 'number': $sheet->setCellValueByColumnAndRow($colIndex + 1, $rowIndex, $cellValue); $sheet->getStyleByColumnAndRow($colIndex + 1, $rowIndex) ->getNumberFormat() ->setFormatCode('#,##0.00'); break; default: $sheet->setCellValueByColumnAndRow($colIndex + 1, $rowIndex, $cellValue); } } $rowIndex++; } // Auto-size columns. Note: This can be performance-intensive for very large // datasets or many columns. If performance is an issue, consider setting // fixed column widths instead, e.g., $sheet->getColumnDimension('A')->setWidth(20); // Auto-size columns foreach (range('A', $sheet->getHighestColumn()) as $col) { $sheet->getColumnDimension($col)->setAutoSize(true); } // Set headers for download header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); header('Content-Disposition: attachment;filename="Laporan.xlsx"'); header('Cache-Control: max-age=0'); // Save file to PHP output $writer = new Xlsx($spreadsheet); $writer->save('php://output'); exit; }) ->use('vendor/autoload.php') ->use('module/db.php') ->use('module/perusahaan.php');