$resp) { $row = [ $ri + 1, $resp['created_at'], $resp['status'], $resp['device_type'] ?? '', $resp['time_taken_seconds'] ?? '', ]; foreach ($questions as $q) { if (in_array($q['type'], ['statement','section_break'])) continue; $row[] = $answers[$resp['id']][$q['id']] ?? ''; } $rows[] = $row; } $safeName = preg_replace('/[^a-z0-9_-]/i', '_', $survey['title']); $filename = 'survam_' . $safeName . '_' . date('Ymd_His'); switch ($fmt) { // ── CSV ─────────────────────────────────────────────────── case 'csv': header('Content-Type: text/csv; charset=UTF-8'); header("Content-Disposition: attachment; filename=\"$filename.csv\""); $out = fopen('php://output', 'w'); // BOM for Excel UTF-8 compatibility fputs($out, "\xEF\xBB\xBF"); fputcsv($out, $headers); foreach ($rows as $row) fputcsv($out, $row); fclose($out); exit; // ── JSON ────────────────────────────────────────────────── case 'json': header('Content-Type: application/json; charset=UTF-8'); header("Content-Disposition: attachment; filename=\"$filename.json\""); $out = []; foreach ($responses as $ri => $resp) { $record = [ 'response_num' => $ri + 1, 'submitted_at' => $resp['created_at'], 'status' => $resp['status'], 'device' => $resp['device_type'] ?? '', 'time_seconds' => $resp['time_taken_seconds'], 'answers' => [], ]; foreach ($questions as $q) { if (in_array($q['type'], ['statement','section_break'])) continue; $record['answers'][$q['id']] = [ 'question' => $q['title'], 'type' => $q['type'], 'answer' => $answers[$resp['id']][$q['id']] ?? null, ]; } $out[] = $record; } echo json_encode(['survey' => $survey['title'], 'exported_at' => date('c'), 'responses' => $out], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; // ── XLSX ────────────────────────────────────────────────── case 'xlsx': if (!file_exists(__DIR__ . '/../vendor/autoload.php')) { // Fallback to CSV if PhpSpreadsheet not available header('Content-Type: text/csv; charset=UTF-8'); header("Content-Disposition: attachment; filename=\"$filename.csv\""); $out = fopen('php://output', 'w'); fputs($out, "\xEF\xBB\xBF"); fputcsv($out, $headers); foreach ($rows as $row) fputcsv($out, $row); fclose($out); exit; } require __DIR__ . '/../vendor/autoload.php'; $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); $sheet->setTitle('Responses'); // Header row foreach ($headers as $ci => $h) { $col = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($ci + 1); $sheet->setCellValue($col . '1', $h); $sheet->getStyle($col . '1')->getFont()->setBold(true); $sheet->getStyle($col . '1')->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB('FF1A1A2E'); $sheet->getStyle($col . '1')->getFont()->getColor()->setARGB('FFFFFFFF'); } // Data rows foreach ($rows as $ri => $row) { foreach ($row as $ci => $val) { $col = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($ci + 1); $sheet->setCellValue($col . ($ri + 2), $val); } } foreach (range(1, count($headers)) as $ci) { $sheet->getColumnDimensionByColumn($ci)->setAutoSize(true); } $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet); header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); header("Content-Disposition: attachment; filename=\"$filename.xlsx\""); $writer->save('php://output'); exit; // ── PDF ─────────────────────────────────────────────────── case 'pdf': // Render to HTML then print - works without library $html = generatePDFHTML($survey, $headers, $rows, $filename); header('Content-Type: text/html; charset=UTF-8'); echo $html; exit; // ── SPSS ───────────────────────────────────────────────── case 'spss': // Generate SAV-compatible syntax file (.sps) header('Content-Type: text/plain; charset=UTF-8'); header("Content-Disposition: attachment; filename=\"$filename.sps\""); echo generateSPSSsyntax($survey, $questions, $responses, $answers); exit; default: http_response_code(400); die('Unknown format.'); } function generatePDFHTML(array $survey, array $headers, array $rows, string $filename): string { $title = htmlspecialchars($survey['title']); $safeH = implode('
| $safeH |
|---|