1

我有一个使用 YII 框架运行的 PHP 脚本,它遍历数据库并创建 Excel 表以用于导出目的。数据库中的数据现在大约有 15K 条记录,并且还在增加。问题是脚本消耗了大量内存,生成的 excel 文件变成了 45 MB 左右。我可以尝试压缩文件以将其压缩到我认为不会有问题的大小,但使用更多内存的脚本是我关心的。

我正在考虑解决它的一种方法是一次只处理 5k 条记录,然后将它们全部加起来以创建 Excel 文件。我不确定这是否会是这样。

    public function actionExport() {

        Yii::import('ext.phpexcel.XPHPExcel');
        XPHPExcel::init();


// Create new PHPExcel object
        $objPHPExcel = new PHPExcel();



// Adding data
        $objPHPExcel->setActiveSheetIndex(0)
                ->setCellValue('A1', 'SN')
                ->setCellValue('B1', 'Full Name')
                ->setCellValue('C1', 'Gender')
                ->setCellValue('D1', 'Date Of Birth')
                ->setCellValue('E1', 'Products')


        $merchantModels = Merchant::model()->findAll();
        $i = 2; //starting after the header row
        foreach ($merchantModels as $model) {
            $merchantPModels = MerchantProducts::model()->findAll(array(
                'condition' => 'merchantID = :merchantID',
                'params' => array(':merchantID' => $model->id),
            ));
            $productStr= "";
            $pStr ="";
            $x = 0; // counter for the merchnat product Loop 

            foreach ($merchantModels as $MPmodel) {
                if($MPmodel->product !== null){
                    $pStr = $MPmodel->product->productName;
                }else{
                    $pStr = "";
                }


                if ($x == 0) { // First Object
                    $productStr = $pStr;
                }else{
                   $productStr = $productStr . "," . $pStr; 
                }

                $x++;
            }
             * 
             */


            $objPHPExcel->setActiveSheetIndex(0)
                    ->setCellValue('A' . $i, $i - 1)
                    ->setCellValue('B' . $i, $model->fullName)
                    ->setCellValue('C' . $i, $model->gender)
                    ->setCellValue('D' . $i, $model->dateOfBirth)                        
                    ->setCellValue('E' . $i, $productStr);
            $i++;
        }
// Rename worksheet
        $objPHPExcel->getActiveSheet()->setTitle('Merchants');


// Set active sheet index to the first sheet, so Excel opens this as the first sheet
        $objPHPExcel->setActiveSheetIndex(0);
        $date = new DateTime('NOW');
        $date = $date->format('Y-m-d H:i:s'); // for example

        $this->render('export', array(
            'excelModel' => $objPHPExcel,
            'date' => $date,
        ));
    }
4

2 回答 2

1

而不是Merchant::model()->findAll()你应该使用CDbDataReader. 您将失去 ActiveRecord 的便利性,但它不会像以前那样将所有记录加载到内存中。

数据读取器从CDbCommand::query(). 因此,您可以执行以下操作:

$command   = Yii::app()->db->createCommand();
$merchants = $command->query('SELECT * FROM merchants');
foreach($merchants as $merchant) {
    // Add to excel here
}
于 2013-08-02T07:38:53.540 回答
0

我还参与了一个将数据从 MySQL 导出到 excel 的项目。在我生成的 XL 表中,我有大约 30 个选项卡,它们是针对不同单元格的一些复杂公式。我为此使用PHPExcel。但在我的情况下,我将 excel 作为一项 cron 工作生成,因为它需要很多时间。

在这里,如果您有一些复杂的 Excel 模板,那么您还可以将设计好的模板保存在服务器上,然后借助 PHPExcel 的读写器类,您可以读取该模板并在其上写入数据并将其保存在一个新文件中。

我认为这些信息会对您有所帮助。如果您想进一步澄清,请告诉我。

于 2013-08-01T13:04:13.103 回答