PHP导出csv文件

原创
小哥 2年前 (2023-05-17) 阅读数 657 #PHP

在PHP代码中想要将数据导出到浏览器,如下:持续下载

利用 php://output 输出流,以及 fputcsv 函数, yield 语法糖

public function export()
{
    $regions = RegionModel::find();

    Csv::export((function (ActiveQuery $regions) {
        //yield [ID, 名称, 编号,];//表头
        foreach ($regions->asArray()->each() as $region) {
            yield $region;
        }
    })($regions));
}

类Csv如下:

class Csv
{
    /**
     * @param Generator|array $data
     * @param string $filename
     */
    public static function export($data, string $filename = )
    {
        self::_setHeader($filename ?: date(YmdHis));
        self::_putCsv($data);
        exit;
    }

    /**
     * @param string $filename
     */
    private static function _setHeader(string $filename)
    {
        header(Content-Encoding: UTF-8);
        header(Content-Type: text/csv;charset=UTF-8);
        header("Content-Disposition: attachment;filename="{$filename}.csv"");
        header(Cache-Control: no-cache, private);
        header(Date:  . gmdate(D, d M Y H:i:s) .  GMT);
    }

    /**
     * @param Generator|array $data
     */
    private static function _putCsv($data)
    {
        $handle = fopen(php://output, w);
        //导出的CSV文件是无BOM编码UTF-8,而我们通常使用UTF-8编码格式都是有BOM的。所以添加BOM于CSV中
        fwrite($handle, chr(0xEF) . chr(0xBB) . chr(0xBF));
        foreach ($data as $datum) {
            fputcsv($handle, $datum);
        }
        fclose($handle);
    }
}

参数 $data 可以是数组,也可以是生成器。

使用 yield 进行迭代避免了内存溢出问题,数据量大也没问题了。
试了一下,下载一个33M的文件,内存占用2M。

版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除

热门