1. 程式人生 > >PHP phpspreadsheet 匯出大資料 csv excel

PHP phpspreadsheet 匯出大資料 csv excel

PHP phpspreadsheet 匯出大資料

1、composer 安裝 phpspreadsheet 這個

composer require phpoffice/phpspreadsheet

2、composer 安裝 phpspreadsheet 這個
普通的Excel根據記憶體來算 可能不超過4000條

普通的匯出xlsx (親測封頂3000多條)
set_time_limit(0);
for($i;$i<=60000;$i++){ // 這樣6萬條的話 可能
    $data[] = [
        'id' => $i+1,
        'name'
=> '使用者'.($i+1) ]; } $title = [ [ '編號', '使用者' ], ]; $arrData = array_merge($title, $arrData); $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet(); // 設定單元格格式 可以省略 $styleArray = [ 'font' => [ 'bold' => true, 'size' => 14, ], ]; $spreadsheet
->getActiveSheet()->getStyle('A1:B1')->applyFromArray($styleArray); $spreadsheet->getActiveSheet()->getColumnDimension('A')->setWidth(25); $spreadsheet->getActiveSheet()->getColumnDimension('B')->setWidth(25); $spreadsheet->getActiveSheet()->fromArray($arrData); $writer
= new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet); header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');//告訴瀏覽器輸出07Excel檔案 // header('Content-Type:application/vnd.ms-excel');//告訴瀏覽器將要輸出Excel03版本檔案 header('Content-Disposition: attachment;filename=test.xlsx');//告訴瀏覽器輸出瀏覽器名稱 header('Cache-Control: max-age=0');//禁止快取 $writer->save('php://output');
優化後的匯出xlsx (親測封頂6萬條)

如果加上優化的話 最多極限是6萬條,這個是excel的檔案限制
原理:其實主要是匯出的時候伺服器記憶體的問題導致無法匯出大資料,所以要分流匯出 並且釋放記憶體 重新整理緩衝

set_time_limit(0);
for($i;$i<=60000;$i++){
    $arrData[] = [
        'id' => $i+1,
        'name' => '使用者'.($i+1)
    ];
}

$title = [
    [
        '編號', '使用者'
    ],
];
$arrData = array_merge($title, $arrData);
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();

// 設定單元格格式 可以省略
$styleArray = [
    'font' => [
        'bold' => true,
        'size' => 14,
    ],
];
$spreadsheet->getActiveSheet()->getStyle('A1:B1')->applyFromArray($styleArray);
$spreadsheet->getActiveSheet()->getColumnDimension('A')->setWidth(25);
$spreadsheet->getActiveSheet()->getColumnDimension('B')->setWidth(25);
$spreadsheet->getActiveSheet()->fromArray($arrData);
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
header('Content-Description: File Transfer');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename=test.xlsx');
header('Cache-Control: max-age=0');
$writer->save('php://output');
$fp = fopen('php://output', 'a');//開啟output流
mb_convert_variables('GBK', 'UTF-8', $columns);
fputcsv($fp, $columns);//將資料格式化為xlsx格式並寫入到output流中

$dataNum = count( $arrData );
$perSize = 1000;//每次匯出的條數
$pages = ceil($dataNum / $perSize);

for ($i = 1; $i <= $pages; $i++) {
    foreach ($arrData as $item) {
        mb_convert_variables('GBK', 'UTF-8', $item);
        fputcsv($fp, $item);
    }
    //重新整理輸出緩衝到瀏覽器
    ob_flush();
    flush();//必須同時使用 ob_flush() 和flush() 函式來重新整理輸出緩衝。
}
fclose($fp);
exit();

如果使用csv的話可以匯出百萬級,當然也要記憶體支援,但是也差不多足夠

set_time_limit(0);
for($i;$i<=60000;$i++){
    $arrData[] = [
        'id' => $i+1,
        'name' => '使用者'.($i+1)
    ];
}

$title = [
    [
        '編號', '使用者'
    ],
];
$arrData = array_merge($title, $arrData);
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();

// 設定單元格格式 可以省略
$styleArray = [
    'font' => [
        'bold' => true,
        'size' => 14,
    ],
];
$spreadsheet->getActiveSheet()->getStyle('A1:B1')->applyFromArray($styleArray);
$spreadsheet->getActiveSheet()->getColumnDimension('A')->setWidth(25);
$spreadsheet->getActiveSheet()->getColumnDimension('B')->setWidth(25);
$spreadsheet->getActiveSheet()->fromArray($arrData);
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Csv($spreadsheet);
header('Content-Description: File Transfer');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename=test.csv');
header('Cache-Control: max-age=0');
$writer->save('php://output');
$fp = fopen('php://output', 'a');//開啟output流
mb_convert_variables('GBK', 'UTF-8', $columns);
fputcsv($fp, $columns);//將資料格式化為csv格式並寫入到output流中

$dataNum = count( $arrData );
$perSize = 1000;//每次匯出的條數
$pages = ceil($dataNum / $perSize);

for ($i = 1; $i <= $pages; $i++) {
    foreach ($arrData as $item) {
        mb_convert_variables('GBK', 'UTF-8', $item);
        fputcsv($fp, $item);
    }
    //重新整理輸出緩衝到瀏覽器
    ob_flush();
    flush();//必須同時使用 ob_flush() 和flush() 函式來重新整理輸出緩衝。
}
fclose($fp);
exit();