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']));

  

posted @ 2024-07-15 15:07  王越666  阅读(3)  评论(0编辑  收藏  举报