$headers * @param array> $rows */ public static function download(string $filename, array $headers, array $rows): StreamedResponse { return response()->streamDownload(function () use ($headers, $rows): void { $handle = fopen('php://output', 'wb'); if ($handle === false) { return; } // UTF-8 BOM improves Russian text rendering in Excel. fwrite($handle, "\xEF\xBB\xBF"); fputcsv($handle, self::normalizeRow($headers), ';'); foreach ($rows as $row) { fputcsv($handle, self::normalizeRow($row), ';'); } fclose($handle); }, $filename, [ 'Content-Type' => 'text/csv; charset=UTF-8', ]); } /** * @param array $row * @return array */ private static function normalizeRow(array $row): array { return array_map(static function (mixed $value): mixed { if ($value === null) { return ''; } if (is_string($value)) { return str_replace(["\r\n", "\r"], "\n", $value); } if (is_bool($value)) { return $value ? '1' : '0'; } return $value; }, $row); } }