大批量导出数据

做数据导出时经常会出现数据量太大导致最后程序卡死 反正我写不来 公司好同事我辈学习之榜样曹老板写的 我给偷过来啦大笑



<?php

class ExportCsv
{
    private $path = '';
    private $header = [];
    private $db = null;
    private $fp = null;
    private $total = 0;
    private $writeRow = 0;
    private $time ;

    function __construct($file)
    {
        $this->time = time();
        set_time_limit(0);
        $endtitle = local_date("Y-m-d-h-i-s");
        $this->path = "{$file}-{$endtitle}.xls";
        $this->db = &m('store');
        header('Content-Type:text/html;charset=utf-8');
        header("Content-Encoding: none\r\n");
        ob_implicit_flush(true);
    }

    public function setHeader($header)
    {
        $this->header = $header;
    }

    

    public function processCsv1($config, $datafunc)
    {

        //输出文件头
        $this->fp = fopen( ROOT_PATH . '/temp/' .$this->path, 'w');
        //echo ROOT_PATH . '/temp/' .$this->path.'<br>';
        //echo $this->fp;
        //exit;
        if (!empty($this->header)) {
            $content = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
            $content .= '<table border="1">';
            $content .= '<tr>';
            foreach ($this->header as $v) {
                $content .= '<th>' . $v . '</th>';
            }
            $content .= '</tr>';

            fwrite($this->fp, $content);
        }

        $where = '';
        if(isset($config['where']) && !empty($config['where']))
        {
            $where = 'where '.$config['where'];
        }

        $countSql = 'select count(DISTINCT('.$config['countfield'].')) from '.$config['from'].' ' . $where;

        $this->total = $this->db->getOne($countSql);

        echo '总共'.$this->total.'条记录<br>';
        if($this->total > 0) {
            $pagecount = 2000;

            $opage = 0;
            for($pos = 0; $pos<$this->total; $pos+=$pagecount,++$opage)
            {
                $selectSql = 'select ' . $config['fields'] . ' from '.$config['from'].' ' . $where . ' '.$config['group'];
                $selectSql .= " limit " . ($opage) * $pagecount . ", $pagecount";

                $this->save2file($selectSql, $datafunc);
            }
        }
    }

    private function save2file($sql, $datafunc)
    {
        $arr = &$this->db->getAll($sql);

        foreach ($arr as $key => $value)
        {
            $value = $datafunc($value);
            if(empty($value)) {
                continue;
            }
            $content = '<tr>';
            foreach ($this->header as $k => $v2) {
                $tmp = isset($value[$k]) ? $value[$k] : '';
                if (is_numeric($tmp)) {
                    $tmp == 0 && $tmp = '';
                }
                $content .= '<td>' . $tmp . '</td>';
            }
            $content .= '</tr>';

            fwrite($this->fp, $content);
            //fputcsv($this->fp, $datafunc($value));
        }

        $this->writeRow += count($arr);
        unset($arr);

        echo str_repeat(' ',1024*64);
        echo '已经读取'.$this->writeRow.'条记录<br>';
        ob_flush();
        flush();
    }

    public function exportCsv()
    {
        if($this->total <= 0) {
            echo '没有可导出数据<br>';
            return;
        }

        fwrite($this->fp, '</table>');

        fclose($this->fp);

        echo '读取完毕<br>';
        echo '耗时:' . intval(time()-($this->time)).'<br>';
        echo '<a href="'.STATIC_URL . '/export/' . $this->path .'" download="'.$this->path.'">点击下载</a>';
       
        exit;
    }

    public function exportCsv1()
    {
        if($this->total <= 0) {
            echo '没有可导出数据<br>';
            return;
        }

        fwrite($this->fp, '</table>');

        fclose($this->fp);

        echo '读取完毕<br>';
        echo '耗时:' . intval(time()-($this->time)).'<br>';
        echo '<a href="'.DOMAIN . '/temp/' .$this->path .'" download="'.$this->path.'">点击下载</a>';
       
        exit;
    }
}

使用方法
if(isset($_GET['excel'])) {

   $export = new ExportCsv('userview');
   $export->setHeader([
      "type" => "类型",
      "title" => "名称",
      "user_name" => "用户",
      "store_name" => "店铺",
      "user_type" => "用户类型",
      "add_time" => "浏览时间",
      "referer" => "来源页面"

   ]);


   $config = [];
   
   $config['countfield'] = 'member_visitor.id';
   $config['fields'] = 'member_visitor.*,member_visitor.types as vtypes,m.user_name,m.isbazaar,uv.store_id as priv_store_id,uv.privs,s.store_id';
   $config['from'] = 'eihoo_member_visitor as member_visitor lEFT JOIN eihoo_member m ON m.user_id=member_visitor.user_id LEFT JOIN eihoo_user_priv uv on uv.user_id=m.user_id LEFT JOIN eihoo_store s on s.user_id=m.user_id';
   //echo $conditions;exit;
   $config['where'] = '';//筛选条件

   $config['group'] = 'group by member_visitor.id';

   $export->processCsv1($config, function ($goods) {
	
      // 这里返回的是1条数据 大部分情况下要针对这条数据做处理得到用户想要的数据
      return $goods;
   });

   $export->exportCsv1();
}



猜你喜欢

转载自blog.csdn.net/u013303689/article/details/78798811