PHP脚本生成Excel文件占用太多内存

PHP脚本生成Excel文件占用太多内存,php,performance,yii,export-to-excel,Php,Performance,Yii,Export To Excel,我有一个使用YII框架运行的PHP脚本,该框架遍历数据库并创建和导出Excel表。数据库中的数据现在大约有15K条记录,而且还在增加。问题是脚本占用大量内存,生成的excel文件大约为45MB。我可以尝试压缩文件,将其压缩到我认为不会有问题的大小,但脚本使用更多内存是我关心的问题 我想解决这个问题的一种方法是,一次只处理5k条记录,然后将所有记录相加,创建Excel文件。我不确定这是否会是这样 public function actionExport() { Yii::

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

我想解决这个问题的一种方法是,一次只处理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,
        ));
    }

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

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


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

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

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


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

您应该使用。您将失去ActiveRecord的便利性,但它不会像以前那样将所有记录加载到内存中

从返回数据读取器。所以你可以这样做:

$command   = Yii::app()->db->createCommand();
$merchants = $command->query('SELECT * FROM merchants');
foreach($merchants as $merchant) {
    // Add to excel here
}

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

从返回数据读取器。所以你可以这样做:

$command   = Yii::app()->db->createCommand();
$merchants = $command->query('SELECT * FROM merchants');
foreach($merchants as $merchant) {
    // Add to excel here
}

我认为你需要更精确地让我们帮助你。例如:你能给我们看一些你现在是如何生成这些文件的代码吗?我们需要更多的信息,一些代码就好了。但是如果不知道您是否使用库或框架生成文件,我们无法告诉您要更改什么。使用CSV而不是Excel怎么样?这可能会节省内存。我已经用代码更新了问题。到目前为止,减少内存使用的最简单方法是创建一个csv文件,因为您可以一次写入一行,而不需要在内存中存储大型复杂数据结构。CSV文件可以在excel中使用,不会出现任何问题,但是如果需要,您可以在一次操作中将CSV文件转换为excel文件,这样可以节省内存使用量。我认为您需要更加精确,以便我们能够帮助您。例如:你能给我们看一些你现在是如何生成这些文件的代码吗?我们需要更多的信息,一些代码就好了。但是如果不知道您是否使用库或框架生成文件,我们无法告诉您要更改什么。使用CSV而不是Excel怎么样?这可能会节省内存。我已经用代码更新了问题。到目前为止,减少内存使用的最简单方法是创建一个csv文件,因为您可以一次写入一行,而不需要在内存中存储大型复杂数据结构。CSV文件可以在excel中使用,没有任何问题,但是如果需要,您可以在一次操作中将CSV文件转换为excel文件,这样可以节省内存使用量我正在使用phpexcel很棒!因此,您可以尝试从excel模板中读取并写入。这样会更快,而且您不必考虑格式化的单元格。因此,您建议先调整代码以加载模板,然后添加新数据?但问题是我的excel文档目前并不复杂,它只有一行标题,所有其他字段都是从数据库填充的。我使用的是phpexcel此刻,太棒了!因此,您可以尝试从excel模板中读取并写入。这样会更快,而且您不必考虑格式化的单元格。因此,您建议先调整代码以加载模板,然后添加新数据?但问题是,我的excel文档目前并不复杂,它只有一行标题,所有其他字段都是从数据库填充的。