如何用 php 生成一个大的 Excel 文件?

How to generate a big Excel file with php?

我必须自动生成 Excel 文件,Excel 文件包含 15.000 到 50.000 行和 75 列。

使用Excel中的join和公式得到(68个Excel公式,有IF,IFERROR,COUNTIF ...)。

所以我选择了库 PHPExcel,它可以工作,但我必须在 1h15 到 1h30 之间等待,我已将循环次数降至最低。看了很多文档,才发现这是PHPExcel.

的问题

如果我考虑使用从我的数据库中检索到的所有 Excel 公式和数据创建一个 php 数组的可能性,这种方法需要很长时间,我不确定它是否会成功工作。

所以我问你,还有别的办法吗?一种生成具有大量数据(具有 1 或 200 万个单元格)和公式的 Excel 工作簿类型的方法相当快(15 分钟内)。

<?php       
require_once dirname(__FILE__) . '/Classes/PHPExcel.php';
require_once dirname(__FILE__) .  '/Classes/PHPExcel/IOFactory.php';

$path = "Lirefichierexcel/Trame.xlsx";

$objPHPExcel = new PHPExcel(); 
$sheet = $objPHPExcel-> getActiveSheet();

$rowCount =5;

$worksheetTitle = $sheet->getTitle();
$highestRow = $sheet->getHighestRow(); // e.g. 10
$highestColumn = $sheet->getHighestColumn(); // e.g 'F'
$highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn);
$nrColumns = ord($highestColumn) - 64;

$rowCount=5;

   $projet=$_REQUEST['projet'];
     try {
       //Etablir la connexxion
       include 'Proprietes.php';

       $connexion = new PDO("$driver:host=$host;dbname=$dbase", $user, $password);

       //Préparer la requête
       $requeteSQL="select * from $projet as a left join feuille_de_prix as b 
       on b.Liasse = a.Liasse and b.Item = a.Item order by 1";
        $requetePreparee= $connexion->prepare($requeteSQL);

       //Exécuter la requête
     $resultat = $requetePreparee->execute();

     //Tester le résultat
     if(! $resultat) die("<p>La lecture a échoué</>\n");
    else {

   echo "<h1>Jointure entre le $projet et la feuille de prix </h1>";

       while($ligne=$requetePreparee->fetch()){

    $sheet->SetCellValue('F'.$rowCount, $ligne[4])
    ->SetCellValue('F'.$rowCount, $ligne[4])    

   $rowCount++;

    } 

       $worksheetTitle = $sheet->getTitle();
$highestRow = $sheet->getHighestRow(); // e.g. 10
$highestColumn = $sheet->getHighestColumn(); // e.g 'F'
$highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn);
$nrColumns = ord($highestColumn) - 64;

      for ($row = 5; $row <= $highestRow; ++ $row) {
    $row1=$row+1;
    $rowm1=$row-1;

       //AA4
    $sheet->setCellValue(
            'AA' . $row, '=..............')

//AB4
        ->setCellValue(
            'AB' . $row,'=..............')

}

}

echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL;
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL;
// Echo memory peak usage
echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL;

// Echo done
echo date('H:i:s') , " Done writing file" , PHP_EOL;

     $connexion=null;

   }catch (PDOException $e) {
     print "Erreur !: " . $e->getMessage() . "<br/>";
     die();
    }

    ?>

使用 BoxSpout。

It is a PHP library to read and write CSV and XLSX files, in a fast and scalable way. Contrary to other file readers or writers, it is capable of processing very large files while keeping the memory usage really low (less than 10MB). Here are a few numbers regarding the performance of Spout.

https://github.com/box/spout

尝试使用https://github.com/aVadim483/fast-excel-writer 这是非常快的 XLSX 生成器: 2,000 行(6,000 个单元格)- 0.198 秒 2,000,000 行(6,000,000 个单元格)- 17.049 秒

似乎 CNUM() 是该函数的法语名称,因此您需要在此库中设置法语语言环境

$sheetData = [];
// fill data
for ($row = 1; $row <= 200000; $row++) {
    $rowData = [];
    for ($col = 0; $col < 3; $col++) {
        $rowData[] = '=IF(OR(CNUM(N' . $row . ')=1,CNUM(N' . $row . ')=2),0,1+CNUM(M' . $row . '))';
    }
    $sheetData[] = $rowData;
}

$excel = \avadim\FastExcelWriter\Excel::create();
$excel->setLocale('fr');
$sheet = $excel->getSheet();

$timer = microtime(true);

foreach($sheetData as $rowData) {
    $sheet->writeRow($rowData);
}

$excel->save('simple.xlsx');

echo 'elapsed time: ', round(microtime(true) - $timer, 3), ' sec';