php下excel导出汇总

fputcsv+mysql pdo nobuffer

  • 要点:
    设置mysql参数,不使用客户端(php)缓冲区,结果集存在mysql服务端
    MYSQL_ATTR_USE_BUFFERED_QUERY=false

  • 优点:
    速度快(一百万级十几秒即可),避免内存溢出,csv可以用excel打开

  • 缺点:mysql服务端压力过大,csv需要自己处理文本格式,csv用excel打开也是104万行数限制

  • 代码:

		$timestart   = microtime(true);
        $startMemory = memory_get_usage();
        $sql         = 'select * from ti_log';
        $pdo         = new\PDO('mysql:host=127.0.0.1;dbname=sd_ka', 'root', 'root');
        $pdo->setAttribute(\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
        $rows = $pdo->query($sql);

        $filename = date('Ymd') . '.csv';//设置文件名
        header('Content-Type:text/csv');
        header("Content-Disposition:attachment;filename={$filename}");
        $out = fopen('php://output', 'w');
        fputcsv(
            $out, [
                'log_id',
                'store_code',
                'member_id',
                'code',
                'product_name',
                'product_code',
                'product_type',
                'query_count'
            ]
        );

        foreach ($rows as $row) {
            $line = [
                $row['log_id'],
                $row['store_code'],
                $row['member_id'],
                $row['code'],
                $row['product_name'],
                $row['product_code'],
                $row['product_type'],
                $row['query_count']
            ];

            fputcsv($out, $line);
        }

        fclose($out);
        $memory = round((memory_get_usage() - $startMemory) / 1024 / 1024, 3) . 'M' . PHP_EOL;
        info('执行内存为为' . $memory);
        info('执行时间为' . (microtime(true) - $timestart));

使用laravel包maatwebsite/excel

  • 文档:laravel-excel

  • 要点:
    使用FromQuery()中的query()自动将数据chunk后执行,但是大数据量下写入excel内存溢出。可以追加queue()方法丢入队列,然而对lumen的queue不支持。
    或者使用eloquent的cursor()实现,FromCollection中返回cursor(),然而对with()类型的不友好,会有大量的whereIn执行

  • 优点:
    laravel推荐,功能强大,表格功能丰富

  • 缺点:
    还是容易内存溢出,支持10万以内的导出

  • 代码:

namespace App\Exports;

use App\Invoice;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\Exportable;

class InvoicesExport implements FromQuery
{
    use Exportable;

    public function query()
    {
        return Invoice::query();
    }
}

(new InvoicesExport)->queue('invoices.xlsx');
namespace App\Exports;

use App\Invoice;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\Exportable;

class InvoicesExport implements FromCollection
{
    use Exportable;

    public function collection()
    {
        return Invoice::query()->cursor();
    }
}

(new InvoicesExport)->store('invoices.xlsx');

php扩展xlswriter

  • 文档:xlswriter

  • 要点:
    使用eloquent的cursor()或者chunk()后单条插入

  • 优点:
    功能较强大

  • 缺点:
    还是可能内存溢出,支持60万以内的导出,需要安装扩展

  • 代码

 			$config = ['path' => storage_path('app/' . $filePath)];
            $excel  = new \Vtiful\Kernel\Excel($config);

            // constMemory内存模式 fileName普通模式
            $excel->constMemory($downloadTask['name'] . $this->fileExtension)
                ->header($exportObj->headings())
                ->setColumn('A:R', 20);

            TiCodeLog::query()
                ->where($this->where)
                ->chunkById(3000, function ($data) use ($exportObj, $excel) {
                    $data = $exportObj->formatData($data);
                    foreach ($data as $item) {
                        foreach ($item as $col => $column) {
                            $excel->insertText($this->index + 1, $col, $column);
                        }
                        $this->index++;
                    }

                    unset($data);
                    $data = null;
                }, 'log_id');

            $excel->output();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值