Csv 文件导出
<?php namespace Shared\Adapter; use PDO; use PDOStatement; use RuntimeException; class ExportCsv { /** @param array<string> $headers */ static function fromQuery(PDOStatement $query, array $headers): void { self::setHeaders(); $fp = fopen('php://output', 'a'); if ($fp === false) { // prettier-ignore throw new RuntimeException('Unable to open php://output for writing.'); } fprintf($fp, chr(0xef) . chr(0xbb) . chr(0xbf)); fputcsv($fp, $headers); if ($headers == null) { $headers = []; foreach (range(0, $query->columnCount() - 1) as $column_index) { array_push( $headers, $query->getColumnMeta($column_index)['name'] ); } } /** @var array<array<string, string>> $items */ $items = []; $i = 0; while ($line = $query->fetch(PDO::FETCH_ASSOC)) { /** @var array<string, string|null> $line */ $items[] = $line; $i++; if ($i === 10) { self::handleChunk($fp, $items); $items = []; $i = 0; } } self::handleChunk($fp, $items); fclose($fp); } /** * @param resource $fp * @param array{string,string|null}[] $items */ static function handleChunk($fp, array $items): void { foreach ($items as $ferow) { $row = []; // Remove HTML tags and prevent loosing leading 0 in Excel foreach ($ferow as $field) { if ($field === null) { $field = ''; } $field = strip_tags($field); if ( is_numeric($field) && $field > 0 && $field[0] == 0 && strlen($field) > 1 && !strpos($field, '.') ) { $row[] = "'" . $field; } elseif (substr($field, 0, 10) == '0000-00-00') { $row[] = ''; } else { $row[] = $field; } } fputcsv($fp, $row); } } /** @param array<array<int,string>> $array */ static function fromArray(array $array): void { self::setHeaders(); $fp = fopen('php://output', 'a'); if ($fp === false) { throw new RuntimeException('Unable to open php://output for writing.'); } fprintf($fp, chr(0xef) . chr(0xbb) . chr(0xbf)); foreach ($array as $row) { fputcsv($fp, $row); } fclose($fp); } private static function setHeaders(): void { // Ensure that it does not download also previous content (ie. from corporate/_lang.php) ob_clean(); //This cookie is needed in order to trigger the success window. header('Set-Cookie: fileDownload=true; path=/'); header('Pragma: public'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Cache-Control: private', false); header('Content-Type: text/csv'); header('Content-Transfer-Encoding: UTF-8'); header('Content-Disposition: attachment; filename=export.csv'); } }
使用:
$arrayCsv[] = $result['thead']; foreach ($result['data'] as $key => $val) { $arrayCsv[] = $val; } try { ExportCsv::fromArray($arrayCsv); } catch (\Exception $e) { Flight::error($e); }
ExportCsv::fromQuery($query, explode(',', $params['headers']));