1. 程式人生 > >php大資料匯出測試類

php大資料匯出測試類

<?php
//header("Content-type:text/html;charset=utf-8");
//set_time_limit(0);
$link = mysqli_connect(
    'localhost',  /* The host to connect to 連線MySQL地址 */
    'root',      /* The user to connect as 連線MySQL使用者名稱 */
    '123456',  /* The password to use 連線MySQL密碼 */
    'artist');    /* The default database to query 連線資料庫名稱*/
$link->set_charset('utf8');
if (!$link) {
    printf("Can't connect to MySQL Server. Errorcode: %s ", mysqli_connect_error());
    exit;
}

//插入百萬資料案例
//$now =date('Y-m-d H:i:s');
//$sql = "
//INSERT INTO ar_apply
//            (name, phone, created_at, is_read, remark,course_id)
//            VALUES
//";
//$str=array();
//for ($t = 1; $t <= 1000000; $t ++)
//{
//        $str[] = "('Name {$t}', '13250702827', '{$now}', '1', '哈哈每個班麼燃煤仍和人民個讓美國噶而過沒人買','1')";
//        if ($t % 100 == 0)
//        {
//            $querySql = $sql.implode(',', $str);
//            $res = $link->query($querySql);
//            if ($res)
//            {
//                echo "成功插入".($t*100)."條<br>";
//            }else {
//                echo "失敗插入".($t*100)."條<br>";
//            }
//            $str = array();
//        }
//
//}
//die;

//總行數
$result = $link->query('select count(*) as num from ar_apply');
$totalNum = $result->fetch_row()[0];

$exportor = new ExcelExporter(array(
    //檔名
    'fileName'      => '匯出',
    //分配記憶體
    'memeryLimit'   => '512M',
    //資料總行數
    'totalNum'      => $totalNum,
    //平均每頁顯示的個數
    'perSize'       => 30000,
    //第一行資料
    'firstLineData' => [
        '姓名', '手機', '註冊時間', '是否已聯絡', '對方留言'      //需要幾列,定義好列名
    ],
    //超時限制
    'limitTime'     => 0,
    //獲取資料的回撥函式
    'calbackGetData'=> function(ExcelExporter $export, $p) use (&$link){
        $config = $export->getConfig();
        $p = $p <= 0? 1 : $p;
        $str = 'select * from ar_apply limit '.($p-1)*$config['perSize'].",{$config['perSize']}";
        $result = $link->query($str);
        $db_data = $result->fetch_all(MYSQLI_ASSOC);
        $data = [];
        foreach ($db_data as $value)
        {
            $data[] = [
                $value['name'],
                '\''.$value['phone'],
                '\''.$value['created_at'],
                $value['is_read'] == 1 ? '是': '否',
                empty($value['remark']) ? '/' : $value['remark']
            ];
        }
        return $data;
    },
));


$exportor->export();




//匯出類
class ExcelExporter {

    protected $config = array();
    protected $outPut;
    public function __construct(array $data = array())
    {
        $this->initData($data);
    }

    public function getConfig()
    {
        return $this->config;
    }

    public function initData($data)
    {
        $temp = array(
            //檔名
            'fileName'      => '匯出',
            //分配記憶體
            'memeryLimit'   => '512M',
            //獲取資料的回撥函式
            'calbackGetData'=> function($p){},
            //資料總行數
            'totalNum'      => 10,
            //平均每頁顯示的個數
            'perSize'       => 10,
            //第一行資料
            'firstLineData' => array(),
            //超時限制
            'limitTime'     => 0,
        );
        $this->config = array_merge($temp, $data);
    }

    protected function setHeader()
    {
        set_time_limit($this->config['limitTime']);
        ini_set('memory_limit', $this->config['memeryLimit']);
        //設定好告訴瀏覽器要下載excel檔案的headers
        header('Content-Description: File Transfer');
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment; filename="'.$this->config['fileName'].'.csv"');
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
    }

    public function export()
    {
        $this->setHeader();
        //開啟output流
        $this->outputOpen();
        //寫第一列
        $this->putCsv([date('Y-m-d H:i:s')]);
        $this->putCsv( $this->config['firstLineData']);

        //分頁處理
        $pages   = ceil($this->config['totalNum'] / $this->config['perSize']);
        for ($i = 0; $i <= $pages; $i++)
        {
            //回撥獲取資料
            $rowData = $this->config['calbackGetData']($this, $i);
            if (!empty($rowData))
            {
                foreach ($rowData as $value)
                {
                    //輸出資料
                    $this->putCsv($value);
                }
            }else {
                continue;
            }
        }
        $this->putCsv([date('Y-m-d H:i:s')]);

        //關閉輸出
        $this->outputClose();
        exit();
    }

    protected function outputOpen()
    {
        $this->outPut = fopen('php://output', 'a');
    }

    protected function outputClose()
    {
        fclose($this->outPut);
    }

    protected function putCsv($data)
    {
         mb_convert_variables('GBK', 'UTF-8', $data);
        fputcsv($this->outPut, $data);
    }

}